| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #include "pv_mime_string_utils.h" |
| #include "oscl_mem.h" |
| |
| char *oscl_strcpy(char *str1, char *str2) |
| { |
| return oscl_strncpy(str1, str2, oscl_strlen(str2) + 1); |
| } |
| |
| void pv_mime_toggle(int *quote_flag) |
| { |
| if (*quote_flag == 0) |
| *quote_flag = 1; |
| else |
| *quote_flag = 0; |
| } |
| |
| char *pv_mime_string_append_param(char *mimestring, char *string, char* newstring) |
| { |
| if (mimestring == NULL) |
| { |
| return NULL; |
| |
| } |
| |
| /* @todo fix the length guards here. The uses of strncat |
| * are false ... need to check against length of TARGET |
| * string, not source! But that's not available here... |
| */ |
| oscl_strcpy(newstring, mimestring); |
| oscl_strncat(newstring, (char *)";", oscl_strlen(";")); |
| oscl_strncat(newstring, string, oscl_strlen(string)); |
| return newstring; |
| } |
| |
| char *pv_mime_string_append_type(char *mimestring, char *string, char* newstring) |
| { |
| int i = 0; |
| if (mimestring == NULL) |
| { |
| return NULL; |
| } |
| |
| while (mimestring[i] != '\0' && mimestring[i] != ';') |
| { |
| i++; |
| } |
| |
| if (mimestring[i] == '\0') // i.e mime strig has no parametres |
| { |
| oscl_strcpy(newstring, mimestring); |
| oscl_strncat(newstring, (char *)"/", oscl_strlen("/")); |
| oscl_strncat(newstring, string, oscl_strlen(string)); |
| } |
| else // mimestring[i] == ';' |
| { |
| if (i > 0) // skip if i==0 (mimestring==";...") |
| // (is that an error case we shd flag?) |
| { |
| oscl_strncpy(newstring, mimestring, i - 1); |
| } |
| oscl_strncat((newstring), (char *)"/", oscl_strlen("/")); |
| oscl_strncat(newstring, string, oscl_strlen(string)); |
| oscl_strncat(newstring, (mimestring + i), oscl_strlen(mimestring + i)); |
| } |
| |
| return newstring; |
| } |
| |
| int pv_mime_string_parse_type(char *mimestring, char *string, char * &stringaddr) |
| { |
| if (mimestring == NULL) |
| { |
| stringaddr = NULL; |
| return 0; |
| } |
| |
| int i = 0, j = 0; |
| char *tempcomp = OSCL_ARRAY_NEW(char, oscl_strlen(mimestring)); |
| // if NEW fails, this will OSCL_LEAVE .. so tempcomp is non-null here |
| |
| while ((mimestring[i] != '\0') && (mimestring[i] != ';')) |
| { |
| while (mimestring[i] != '/') |
| { |
| if (mimestring[i] == '\0') |
| break; |
| |
| tempcomp[j++] = mimestring[i++]; |
| } |
| |
| tempcomp[j] = '\0'; |
| |
| if (!oscl_CIstrcmp(string, tempcomp)) |
| { |
| int ptr = i - j; |
| stringaddr = &mimestring[ptr]; |
| OSCL_ARRAY_DELETE(tempcomp); |
| return (oscl_strlen(stringaddr)); |
| } |
| |
| j = 0; |
| i++; |
| } |
| |
| OSCL_ARRAY_DELETE(tempcomp); |
| return 0; |
| } |
| |
| OSCL_EXPORT_REF int pv_mime_string_parse_param(char *mimestring, char *string, char * &stringaddr) |
| { |
| int i = 0, j = 0, quote_flag = 0; |
| |
| if (mimestring == NULL) |
| { |
| stringaddr = NULL; |
| return 0; |
| } |
| |
| char *tempcomp = OSCL_ARRAY_NEW(char, oscl_strlen(mimestring)); |
| // Clear all types |
| while (mimestring[i] != '\0' && mimestring[i] != ';') |
| { |
| i++; |
| } |
| |
| if (mimestring[i] == '\0') // If there are no parametres |
| { |
| OSCL_ARRAY_DELETE(tempcomp); |
| return 0; |
| } |
| else // There are parametres we have to locate the one we want |
| { |
| i++; // get over ";" |
| while (mimestring[i] != '\0') |
| { |
| if ((mimestring[i] == '\"') && (mimestring[i-1] != '\\')) |
| { |
| pv_mime_toggle("e_flag); |
| } |
| while (!(mimestring[i] == ';' && quote_flag == 0)) |
| { |
| if (mimestring[i] == '\0') |
| break; |
| |
| tempcomp[j++] = mimestring[i++]; |
| if ((mimestring[i] == '\"') && (mimestring[i-1] != '\\')) |
| { |
| pv_mime_toggle("e_flag); |
| } |
| } |
| |
| tempcomp[j] = '\0'; |
| if (!oscl_CIstrcmp(string, tempcomp)) |
| { |
| int ptr = i - j; |
| stringaddr = &mimestring[ptr]; |
| OSCL_ARRAY_DELETE(tempcomp); |
| return (oscl_strlen(stringaddr)); |
| } |
| |
| if (mimestring[i] == '\0') break; |
| |
| j = 0; |
| i++; |
| } |
| } |
| |
| OSCL_ARRAY_DELETE(tempcomp); |
| return 0; |
| } |
| |
| |
| OSCL_EXPORT_REF int pv_mime_strcmp(const char *mimestring1, const char *mimestring2) |
| { |
| int i = 0; |
| |
| // Some constants used in this method |
| const char MIME_PARAM_DELIMITER_CHAR = ';'; |
| const char MIME_SUBTYPE_DELIMITER_CHAR = '/'; |
| |
| // constants for the return values |
| const int RETVAL_NO_MATCH = -1; |
| const int RETVAL_MATCH = 0; |
| const int RETVAL_FIRST_PREFIX = 1; |
| const int RETVAL_SECOND_PREFIX = 2; |
| |
| if ((mimestring1 == NULL) || (mimestring2 == NULL)) |
| { |
| // if either string pointer is NULL then return NO MATCH |
| return RETVAL_NO_MATCH; |
| } |
| |
| // Iterate through the strings doing case-insensitive matching until the |
| // the first non-matching character or a terminating character. |
| for (i = 0; mimestring1[i] != '\0' && oscl_tolower(mimestring1[i]) == oscl_tolower(mimestring2[i]); i++) |
| { |
| if ((mimestring1[i] == MIME_PARAM_DELIMITER_CHAR) || |
| (mimestring2[i] == MIME_PARAM_DELIMITER_CHAR)) |
| { |
| // one of the strings has reached the parameters section. |
| // The type string has been extracted |
| break; |
| } |
| } |
| |
| // initialize the length values of both strings to 'i+1' then the checks |
| // below will correct it if we actually reached a string terminator |
| // for that string. |
| int len1 = i + 1; |
| int len2 = len1; |
| |
| |
| // set the length for the two strings |
| if (mimestring1[i] == MIME_PARAM_DELIMITER_CHAR || |
| mimestring1[i] == '\0') |
| { |
| len1 = i; |
| } |
| |
| if (mimestring2[i] == MIME_PARAM_DELIMITER_CHAR || |
| mimestring2[i] == '\0') |
| { |
| len2 = i; |
| } |
| |
| if (len1 == len2) |
| { |
| // if the lengths are equal && one string has got '\0' or MIME_PARAM_DELIMITER_CHAR |
| if (len1 == i) |
| { |
| return RETVAL_MATCH; |
| } |
| return RETVAL_NO_MATCH; |
| } |
| else if (len1 < len2) |
| { |
| // check if string1 is a prefix. |
| /* Must have subtype delimiter character in string2 for the prefix |
| * condition to be true. For example something like str1 = "aa/bb" and |
| * str2 = "aa/bb/cc". Instead if str2 = "aa/bbcc" then str1 would |
| * not be considered a prefix |
| */ |
| if (mimestring2[i] == MIME_SUBTYPE_DELIMITER_CHAR) |
| { |
| return RETVAL_FIRST_PREFIX; |
| } |
| return RETVAL_NO_MATCH; |
| } |
| else |
| { // must be len2 < len1 |
| // see comments on previous case for how to check for prefix condition |
| if (mimestring1[i] == MIME_SUBTYPE_DELIMITER_CHAR) |
| { |
| return RETVAL_SECOND_PREFIX; |
| } |
| return RETVAL_NO_MATCH; |
| } |
| |
| } |
| |
| |
| OSCL_EXPORT_REF int pv_mime_strstr(char *mimestring1, char *mimestring2) |
| { |
| //skip any .../ in either string. |
| char* str1 = mimestring1; |
| char* str2 = mimestring2; |
| if (oscl_strncmp(str1, ".../", 4) == 0) |
| str1 += 4; |
| if (oscl_strncmp(str2, ".../", 4) == 0) |
| str2 += 4; |
| |
| //if either string is empty, they match. |
| if (str1[0] == '\0' |
| || str2[0] == '\0') |
| return 0; |
| |
| //count components. |
| int n1 = pv_mime_string_compcnt(str1); |
| int n2 = pv_mime_string_compcnt(str2); |
| |
| //swap if needed so that str1 is the larger. |
| if (n2 > n1) |
| { |
| { |
| char* temp = str1; |
| str1 = str2; |
| str2 = temp; |
| } |
| { |
| int temp = n1; |
| n1 = n2; |
| n2 = temp; |
| } |
| } |
| |
| //match str2 against any sub-set of str1. |
| for (int n = 0; n < n1; n++) |
| { |
| char* str = NULL; |
| pv_mime_string_extract_type(n, str1, str); |
| int cmp = pv_mime_strcmp(str, str2); |
| if (cmp != (-1)) |
| return cmp; |
| } |
| return (-1);//no match. |
| } |
| |
| OSCL_EXPORT_REF int pv_mime_string_extract_param(int compnumber, char *mimestring, char * &string) |
| { |
| int count = 0, j = 0, start = 0, quote_flag = 0; |
| |
| if (mimestring == NULL) |
| { |
| string = NULL; |
| return 0; |
| } |
| |
| // Seek to the beginning of the parametre list |
| while (mimestring[j] != '\0' && mimestring[j] != ';') |
| { |
| j++; |
| } |
| |
| start = j + 1; |
| j++; // get j past ";" |
| |
| if (mimestring[j] == '\0') |
| { |
| return 0; // mimestring has no parametres |
| } |
| else // mimestring has ";" |
| { |
| while (mimestring[j] != '\0') |
| { |
| if ((mimestring[j] == '\"') && (mimestring[j-1] != '\\')) |
| { |
| pv_mime_toggle("e_flag); |
| } |
| |
| if (((mimestring[j] == ';') || (mimestring[j] == '\0')) && (quote_flag == 0)) |
| { |
| if (compnumber == count) |
| { |
| string = &mimestring[start]; |
| return (j - start); |
| |
| } |
| else |
| count++; |
| |
| start = j + 1; |
| } |
| |
| if (j++ > (int)oscl_strlen(mimestring)) |
| return 0; |
| } |
| |
| if (compnumber == count && mimestring[j] == '\0') |
| { |
| string = &mimestring[start]; |
| return (j - start); |
| } |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF int pv_mime_string_extract_type(int compnumber, char *mimestring, char * &string) |
| { |
| int count = 0 , j = 0, start = 0; |
| if (mimestring == NULL) |
| { |
| string = NULL; |
| return 0; |
| } |
| |
| while (mimestring[j] != '\0') |
| { |
| if ((mimestring[j] == '/') || |
| (mimestring[j] == '\0') || |
| (mimestring[j] == ';')) |
| { |
| if (compnumber == count) |
| { |
| string = &mimestring[start]; |
| return (j - start); |
| } |
| else |
| { |
| count++; |
| } |
| |
| start = j + 1; |
| |
| if (mimestring[j] == ';') |
| { |
| break; |
| } |
| } |
| |
| if (j++ > (int)oscl_strlen(mimestring)) |
| { |
| return 0; |
| } |
| } |
| |
| if (compnumber == count && mimestring[j] == '\0') |
| { |
| string = &mimestring[start]; |
| return (j - start); |
| } |
| |
| return 0; |
| } |
| |
| OSCL_EXPORT_REF int pv_mime_string_compcnt(char* mimestring) |
| { |
| int count = 1; /* mime string will have at least one component */ |
| int quote_flag = 0; |
| |
| if (mimestring == NULL) |
| { |
| return 0; |
| } |
| |
| for (int i = 0; mimestring[i] != '\0'; i++) |
| { |
| if ((mimestring[i] == '\"') && (mimestring[i-1] != '\\')) |
| { |
| pv_mime_toggle("e_flag); |
| } |
| |
| if (mimestring[i] == '/' && !quote_flag) |
| count++; |
| } |
| return count; |
| } |
| |
| OSCL_EXPORT_REF int pv_mime_string_parcnt(char* mimestring) |
| { |
| int count = 0; /* mime string will have zero or more parametres*/ |
| int quote_flag = 0; |
| |
| if (mimestring == NULL) |
| { |
| return 0; |
| } |
| |
| for (int i = 0; mimestring[i] != '\0'; i++) |
| { |
| if ((mimestring[i] == '\"') && (mimestring[i-1] != '\\')) |
| { |
| pv_mime_toggle("e_flag); |
| } |
| |
| if (mimestring[i] == ';' && !quote_flag) |
| count++; |
| |
| } |
| return count; |
| } |
| |
| bool pv_mime_string_is_relative(char* mimestring) |
| { |
| if (mimestring == NULL) |
| { |
| return false; |
| } |
| else |
| { |
| if ((oscl_strncmp(mimestring, ".../", 4) == 0) && (oscl_strlen(mimestring) >= 5)) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| } |
| |
| char * pv_mime_string_strappend(char *mimestring, char *mimestring1, char* newstring) |
| { |
| int i = 0, j = 0, k = 0; |
| if ((mimestring == NULL) && (mimestring1 != NULL)) |
| { |
| oscl_strcpy(newstring, mimestring1); |
| return newstring; |
| } |
| else if ((mimestring1 == NULL) && (mimestring != NULL)) |
| { |
| oscl_strcpy(newstring, mimestring); |
| return newstring; |
| |
| } |
| else if ((mimestring1 == NULL) && (mimestring == NULL)) |
| { |
| newstring = NULL; |
| return newstring; |
| } |
| |
| if (pv_mime_string_is_relative(mimestring1)) |
| { |
| j = 4; |
| } |
| |
| while (mimestring[k] != '\0' && mimestring[k] != ';') |
| { |
| if ((mimestring[k] == '.') && (mimestring[k-1] == '/') && (mimestring[k+1] == '.') && (mimestring[k+2] == '/')) |
| { |
| k = k + 3; // get past "../" |
| i = i - 2; // get past "/." |
| |
| while ((i >= 0) && (newstring[i] != '/')) |
| { |
| i--; |
| } |
| i++; // get past '/' |
| } |
| else |
| { |
| newstring[i] = mimestring[k]; |
| i++; |
| k++; |
| } |
| |
| } |
| |
| newstring[i++] = '/'; |
| |
| // merge the TYPES first |
| while (mimestring1[j] != '\0' && mimestring1[j] != ';') |
| { |
| if ((mimestring1[j] == '.') && (mimestring1[j-1] == '/') && (mimestring1[j+1] == '.') && (mimestring1[j+2] == '/')) |
| { |
| j = j + 3; // get past "../" |
| i = i - 2; // get past "/." |
| while ((i >= 0) && (newstring[i] != '/')) |
| { |
| i--; |
| } |
| |
| i++; // get past '/' |
| |
| } |
| else |
| { |
| newstring[i] = mimestring1[j]; |
| i++; |
| j++; |
| } |
| } |
| |
| // Merge parametres of mimestring |
| while (mimestring[k] != '\0') |
| { |
| newstring[i] = mimestring[k]; |
| k++; |
| i++; |
| } |
| |
| // Merge in parametres of mimestring1 |
| while (mimestring1[j] != '\0') |
| { |
| newstring[i] = mimestring1[j]; |
| i++; |
| j++; |
| } |
| |
| newstring[i] = '\0'; |
| return newstring; |
| } |
| |