| /* ------------------------------------------------------------------ |
| * 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 "oscl_string_utils.h" |
| #include "common_info.h" |
| #include "rtsp_range_utils.h" |
| #include "oscl_str_ptr_len.h" |
| #include "oscl_stdstring.h" |
| #include "sdp_parsing_utils.h" |
| #include "oscl_utf8conv.h" |
| #include "oscl_snprintf.h" |
| #include "oscl_bin_stream.h" |
| |
| #define BYTE_ORDER_MASK 0xFEFF |
| static const char PVSDPMETADATA_LANG_CODE[] = ";iso-639-2-lang="; |
| static const char PVSDPMETADATA_RATING_ENTITY[] = ";rating-entity="; |
| static const char PVSDPMETADATA_RATING_CRITERIA[] = ";rating-criteria="; |
| static const char PVSDPMETADATA_CLASSIFICATION_ENTITY[] = ";classification-entity="; |
| static const char PVSDPMETADATA_CLASSFICATION_TABLE[] = ";classification-table="; |
| |
| bool get_next_line(const char *start_ptr, const char * end_ptr, |
| const char *& line_start, |
| const char *& line_end) |
| { |
| // Finds the boundaries of the next non-empty line within start |
| // and end ptrs |
| |
| // This initializes line_start to the first non-whitespace character |
| line_start = skip_whitespace_and_line_term(start_ptr, end_ptr); |
| |
| line_end = skip_to_line_term(line_start, end_ptr); |
| |
| return (line_start < end_ptr); |
| |
| } |
| |
| bool sdp_decodebase64(uint8* aInBuf, uint32 aInBufLen, |
| uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen) |
| { |
| oscl_memset(aOutBuf, 0, aMaxOutBufLen); |
| aOutBufLen = 0; |
| |
| int i; |
| uint8 dtable[256]; |
| |
| for (i = 0; i < 255; i++) |
| { |
| dtable[i] = 0x80; |
| } |
| for (i = 'A'; i <= 'I'; i++) |
| { |
| dtable[i] = 0 + (i - 'A'); |
| } |
| for (i = 'J'; i <= 'R'; i++) |
| { |
| dtable[i] = 9 + (i - 'J'); |
| } |
| for (i = 'S'; i <= 'Z'; i++) |
| { |
| dtable[i] = 18 + (i - 'S'); |
| } |
| for (i = 'a'; i <= 'i'; i++) |
| { |
| dtable[i] = 26 + (i - 'a'); |
| } |
| for (i = 'j'; i <= 'r'; i++) |
| { |
| dtable[i] = 35 + (i - 'j'); |
| } |
| for (i = 's'; i <= 'z'; i++) |
| { |
| dtable[i] = 44 + (i - 's'); |
| } |
| for (i = '0'; i <= '9'; i++) |
| { |
| dtable[i] = 52 + (i - '0'); |
| } |
| dtable[(int)'+'] = 62; |
| dtable[(int)'/'] = 63; |
| dtable[(int)'='] = 0; |
| |
| uint32 read_count = 0; |
| uint32 write_count = 0; |
| while (read_count < aInBufLen) |
| { |
| uint8 a[4], b[4], o[3]; |
| |
| for (i = 0; i < 4; i++) |
| { |
| uint8 c = *(aInBuf++); |
| read_count++; |
| |
| if (read_count > aInBufLen) |
| { |
| //Input incomplete |
| return false; |
| } |
| if (dtable[(int)c]&0x80) |
| { |
| //Illegal character in |
| //return false; |
| i--; |
| continue; |
| } |
| a[i] = (uint8)c; |
| b[i] = (uint8)dtable[(int)c]; |
| } |
| o[0] = (b[0] << 2) | (b[1] >> 4); |
| o[1] = (b[1] << 4) | (b[2] >> 2); |
| o[2] = (b[2] << 6) | b[3]; |
| i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); |
| oscl_memcpy(aOutBuf, o, i); |
| aOutBuf += i; |
| write_count += i; |
| if (write_count > aMaxOutBufLen) |
| { |
| return false; |
| } |
| if (i < 3) |
| { |
| break; |
| } |
| } |
| aOutBufLen = write_count; |
| return true; |
| } |
| |
| |
| bool parseQoEMetrics(const char *start_ptr, const char *end_ptr, QoEMetricsType &qoeMetrics) |
| { |
| const char *sptr = start_ptr; |
| const char *eptr = end_ptr; |
| |
| sptr = skip_whitespace_and_line_term(sptr, end_ptr); |
| |
| StrPtrLen rate("rate="); |
| StrPtrLen range("range:"); |
| |
| if (!oscl_strncmp(sptr, "{", 1)) |
| sptr = sptr + 1; |
| else |
| return false; |
| |
| sptr = skip_whitespace_and_line_term(sptr, end_ptr); |
| if (sptr > eptr) |
| return false; |
| |
| while (sptr < end_ptr) |
| { |
| |
| if (!oscl_strncmp(sptr, "Initial_Buffering_Duration", |
| oscl_strlen("Initial_Buffering_Duration"))) |
| { |
| qoeMetrics.name[QoEMetricsType::INITIAL_BUFFERING_DURATION] = true; |
| sptr = sptr + oscl_strlen("Initial_Buffering_Duration"); |
| } |
| else if (!oscl_strncmp(sptr, "Rebuffering_Duration", |
| oscl_strlen("Rebuffering_Duration"))) |
| { |
| qoeMetrics.name[QoEMetricsType::REBUFFERING_DURATION] = true; |
| sptr = sptr + oscl_strlen("Rebuffering_Duration"); |
| } |
| else if (!oscl_strncmp(sptr, "Corruption_Duration", |
| oscl_strlen("Corruption_Duration"))) |
| { |
| qoeMetrics.name[QoEMetricsType::CORRUPTION_DURATION] = true; |
| sptr = sptr + oscl_strlen("Corruption_Duration"); |
| } |
| else if (!oscl_strncmp(sptr, "Succssive_Loss", |
| oscl_strlen("Succssive_Loss"))) |
| { |
| qoeMetrics.name[QoEMetricsType::SUCESSIVE_LOSS] = true; |
| sptr = sptr + oscl_strlen("Succssive_Loss"); |
| } |
| else if (!oscl_strncmp(sptr, "Framerate_Deviation", |
| oscl_strlen("Framerate_Deviation"))) |
| { |
| qoeMetrics.name[QoEMetricsType::FRAMERATE_DEVIATION] = true; |
| sptr = sptr + oscl_strlen("Framerate_Deviation"); |
| } |
| else if (!oscl_strncmp(sptr, "Jitter_Duration", |
| oscl_strlen("Jitter_Duration"))) |
| { |
| qoeMetrics.name[QoEMetricsType::JITTER_DURATION] = true; |
| sptr = sptr + oscl_strlen("Jitter_Duration"); |
| } |
| else if (!oscl_strncmp(sptr, "Decoded_Bytes", |
| oscl_strlen("Decoded_Bytes"))) |
| { |
| qoeMetrics.name[QoEMetricsType::DECODED_BYTES] = true; |
| sptr = sptr + oscl_strlen("Decoded_Bytes"); |
| } |
| else |
| return false; |
| |
| sptr = skip_whitespace_and_line_term(sptr, end_ptr); |
| if (sptr > end_ptr) |
| return false; |
| |
| if (!oscl_strncmp(sptr, ",", 1)) |
| sptr = sptr + 1; |
| else if (!oscl_strncmp(sptr, "}", 1)) |
| { |
| sptr = sptr + 1; |
| break; |
| } |
| } |
| |
| if (sptr > end_ptr) |
| return false; |
| |
| if (!oscl_strncmp(sptr, ";", 1)) |
| sptr = sptr + 1; |
| else |
| return false; |
| |
| if (!oscl_strncmp(sptr, rate.c_str(), rate.length())) |
| { |
| sptr = sptr + rate.length(); |
| if (!oscl_strncmp(sptr, "End", oscl_strlen("End"))) |
| { |
| qoeMetrics.rateFmt = QoEMetricsType::END; |
| qoeMetrics.rateEnd = 'E'; |
| sptr = sptr + oscl_strlen("End"); |
| |
| } |
| else |
| { |
| uint32 temp; |
| eptr = sptr; //get length of range digit |
| for (; (*eptr != ';' && eptr < end_ptr); ++eptr); |
| |
| qoeMetrics.rateFmt = QoEMetricsType::VAL; |
| |
| if (PV_atoi(sptr, 'd', (int)(eptr - sptr), temp)) |
| { |
| qoeMetrics.rateVal = temp; |
| sptr = eptr ; |
| } |
| else |
| return false; |
| } |
| |
| } |
| else |
| return false; |
| |
| if (sptr == end_ptr) //end of line reached. |
| return true; |
| |
| if (sptr > end_ptr) |
| return false; |
| |
| if (!oscl_strncmp(sptr, ";", 1)) |
| sptr = sptr + 1; |
| else |
| return false; |
| if (!oscl_strncmp(sptr, range.c_str(), range.length())) |
| { |
| eptr = sptr + range.length(); |
| for (; *eptr != ';' && eptr != end_ptr ; eptr++); // get length of range. |
| |
| if (!parseRtspRange((sptr + range.length()), (eptr - sptr - range.length()), |
| qoeMetrics.range)) |
| return false; |
| } |
| |
| sptr = eptr; |
| if (sptr == end_ptr) |
| return true; // end of line reached. |
| else //Parameter_Ext |
| { |
| sptr = eptr + 1; |
| if (!oscl_strncmp(sptr, "On", oscl_strlen("On"))) |
| { |
| qoeMetrics.paramExtStat = true; |
| qoeMetrics.paramFmt = QoEMetricsType::STATUS; |
| } |
| else if (!oscl_strncmp(sptr, "Off", oscl_strlen("Off"))) |
| { |
| qoeMetrics.paramExtStat = false; |
| qoeMetrics.paramFmt = QoEMetricsType::STATUS; |
| } |
| else |
| { |
| uint32 len = OSCL_MIN((uint32)(eptr - sptr), oscl_strlen(".")); |
| if (oscl_strncmp(sptr, ".", len) == 0) //if floating point number |
| { |
| if (!PV_atof(sptr, (int)(eptr - sptr), qoeMetrics.paramExtFdigit)) |
| return false; |
| qoeMetrics.paramFmt = QoEMetricsType::FDIGIT; |
| } |
| else // hex digit |
| { |
| uint32 temp; |
| if (PV_atoi(sptr, 'x', (int)(eptr - sptr), temp)) |
| { |
| qoeMetrics.paramExtIdigit = temp; |
| qoeMetrics.paramFmt = QoEMetricsType::IDIGIT; |
| |
| } |
| else |
| return false; |
| } |
| |
| } |
| |
| |
| } |
| |
| return true; |
| |
| } |
| |
| void pvSDPParserGetAssetInfoLanguageCode(uint16 langcode, char* LangCode) |
| { |
| //ISO-639-2/T 3-char Lang Code |
| oscl_memset(LangCode, 0, 4); |
| LangCode[0] = 0x60 + ((langcode >> 10) & 0x1F); |
| LangCode[1] = 0x60 + ((langcode >> 5) & 0x1F); |
| LangCode[2] = 0x60 + ((langcode) & 0x1F); |
| } |
| |
| bool pvSDPParserParse3GPPAssetInfoLocation(AssetInfoType& ainfo, |
| uint8* aBuf, |
| uint32 aBufSize) |
| { |
| uint32 count = 0; |
| uint16 lang = *aBuf++; |
| lang = ((lang << 8) | (*aBuf++)); |
| count += 2; |
| uint16 byteOrderMask = 0; |
| byteOrderMask = *aBuf; |
| byteOrderMask = |
| ((byteOrderMask << 8) | (*(aBuf + 1))); |
| if (byteOrderMask == BYTE_ORDER_MASK) |
| { |
| aBuf += 2; |
| uint32 index = 0; |
| uint8 firstbyte = aBuf[index]; |
| uint8 secondbyte = aBuf[index++]; |
| oscl_wchar wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); |
| bool nextChar = (wc == 0) ? false : true; |
| while (nextChar && (index < aBufSize)) |
| { |
| firstbyte = aBuf[index]; |
| secondbyte = aBuf[index++]; |
| wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); |
| nextChar = (wc == 0) ? false : true; |
| } |
| ainfo.iLocationStruct._location_name = |
| (oscl_wchar*)(oscl_malloc(sizeof(oscl_wchar) * (index + 1))); |
| if (ainfo.iLocationStruct._location_name == NULL) return false; |
| oscl_memcpy(ainfo.iLocationStruct._location_name, aBuf, (index*2)); |
| } |
| else |
| { |
| uint32 index = 0; |
| bool nextChar = (aBuf[index] == 0) ? false : true; |
| while (nextChar && (index < aBufSize)) |
| { |
| index++; |
| nextChar = (aBuf[index] == 0) ? false : true; |
| } |
| oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (index + 1)); |
| if (unicodeBuf == NULL) return false; |
| oscl_UTF8ToUnicode((char*)aBuf, |
| index, |
| unicodeBuf, |
| index + 1); |
| ainfo.iLocationStruct._location_name = unicodeBuf; |
| } |
| ainfo.iLocationStruct._role = *aBuf++; |
| uint32 i; |
| ainfo.iLocationStruct._longitude = 0; |
| for (i = 0; i < 4; i++) |
| { |
| ainfo.iLocationStruct._longitude |= *aBuf++; |
| } |
| ainfo.iLocationStruct._latitude = 0; |
| for (i = 0; i < 4; i++) |
| { |
| ainfo.iLocationStruct._latitude |= *aBuf++; |
| } |
| ainfo.iLocationStruct._altitude = 0; |
| for (i = 0; i < 4; i++) |
| { |
| ainfo.iLocationStruct._altitude |= *aBuf++; |
| } |
| byteOrderMask = *aBuf; |
| byteOrderMask = |
| ((byteOrderMask << 8) | (*(aBuf + 1))); |
| if (byteOrderMask == BYTE_ORDER_MASK) |
| { |
| aBuf += 2; |
| uint32 index = 0; |
| uint8 firstbyte = aBuf[index]; |
| uint8 secondbyte = aBuf[index++]; |
| oscl_wchar wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); |
| bool nextChar = (wc == 0) ? false : true; |
| while (nextChar && (index < aBufSize)) |
| { |
| firstbyte = aBuf[index]; |
| secondbyte = aBuf[index++]; |
| wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); |
| nextChar = (wc == 0) ? false : true; |
| } |
| ainfo.iLocationStruct._astronomical_body = |
| (oscl_wchar*)(oscl_malloc(sizeof(oscl_wchar) * (index + 1))); |
| if (ainfo.iLocationStruct._astronomical_body == NULL) return false; |
| oscl_memcpy(ainfo.iLocationStruct._astronomical_body, aBuf, (index*2)); |
| } |
| else |
| { |
| uint32 index = 0; |
| bool nextChar = (aBuf[index] == 0) ? false : true; |
| while (nextChar && (index < aBufSize)) |
| { |
| index++; |
| nextChar = (aBuf[index] == 0) ? false : true; |
| } |
| oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (index + 1)); |
| if (unicodeBuf == NULL) return false; |
| oscl_UTF8ToUnicode((char*)aBuf, |
| index, |
| unicodeBuf, |
| index + 1); |
| ainfo.iLocationStruct._astronomical_body = unicodeBuf; |
| } |
| byteOrderMask = *aBuf; |
| byteOrderMask = |
| ((byteOrderMask << 8) | (*(aBuf + 1))); |
| if (byteOrderMask == BYTE_ORDER_MASK) |
| { |
| aBuf += 2; |
| uint32 index = 0; |
| uint8 firstbyte = aBuf[index]; |
| uint8 secondbyte = aBuf[index++]; |
| oscl_wchar wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); |
| bool nextChar = (wc == 0) ? false : true; |
| while (nextChar && (index < aBufSize)) |
| { |
| firstbyte = aBuf[index]; |
| secondbyte = aBuf[index++]; |
| wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); |
| nextChar = (wc == 0) ? false : true; |
| } |
| ainfo.iLocationStruct._additional_notes = |
| (oscl_wchar*)(oscl_malloc(sizeof(oscl_wchar) * index)); |
| if (ainfo.iLocationStruct._additional_notes == NULL) return false; |
| oscl_memcpy(ainfo.iLocationStruct._additional_notes, aBuf, (index*2)); |
| } |
| else |
| { |
| uint32 index = 0; |
| bool nextChar = (aBuf[index] == 0) ? false : true; |
| while (nextChar && (index < aBufSize)) |
| { |
| index++; |
| nextChar = (aBuf[index] == 0) ? false : true; |
| } |
| oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (index + 1)); |
| if (unicodeBuf == NULL) return false; |
| oscl_UTF8ToUnicode((char*)aBuf, |
| index, |
| unicodeBuf, |
| index + 1); |
| ainfo.iLocationStruct._additional_notes = unicodeBuf; |
| } |
| return true; |
| } |
| |
| |
| bool parseAssetInfo(const char *sptr, const char *line_end_ptr, AssetInfoType &ainfo) |
| { |
| const char *eptr = sptr; |
| int assetbox; |
| |
| while (eptr < line_end_ptr) |
| { |
| sptr = skip_whitespace(sptr, line_end_ptr); |
| if (oscl_CIstrncmp(sptr, "{", 1)) |
| return false; |
| sptr = sptr + 1; |
| sptr = skip_whitespace(sptr, line_end_ptr); |
| if (sptr > line_end_ptr) |
| return false; |
| |
| if (!oscl_CIstrncmp(sptr, "url=", oscl_strlen("url="))) |
| { |
| sptr = sptr + oscl_strlen("url="); |
| sptr = skip_whitespace(sptr, line_end_ptr); |
| if (sptr > line_end_ptr) |
| return false; |
| if (!oscl_CIstrncmp(sptr, "\"", 1)) |
| { |
| sptr = sptr + 1; |
| sptr = skip_whitespace(sptr, line_end_ptr); |
| if (sptr > line_end_ptr) |
| return false; |
| eptr = sptr; |
| |
| for (; *eptr != '"'; ++eptr); |
| |
| ainfo.URL.set((const char *)sptr, (eptr - sptr)); |
| } |
| else |
| { |
| eptr = sptr; |
| |
| for (; *eptr != '}'; ++eptr); |
| |
| ainfo.URL.set((const char *)sptr, (eptr - sptr)); |
| } |
| return true; |
| |
| } |
| |
| if (!oscl_CIstrncmp(sptr, "Title=", oscl_strlen("Title="))) |
| { |
| sptr = sptr + oscl_strlen("Title="); |
| assetbox = (int) AssetInfoType::TITLE; |
| ainfo.oTitlePresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Description=", oscl_strlen("Description="))) |
| { |
| sptr = sptr + oscl_strlen("Description="); |
| assetbox = (int) AssetInfoType::DESCRIPTION; |
| ainfo.oDescriptionPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Copyright=", oscl_strlen("Copyright="))) |
| { |
| sptr = sptr + oscl_strlen("Copyright="); |
| assetbox = (int) AssetInfoType::COPYRIGHT; |
| ainfo.oCopyRightPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Performer=", oscl_strlen("Performer="))) |
| { |
| sptr = sptr + oscl_strlen("Performer="); |
| assetbox = (int) AssetInfoType::PERFORMER; |
| ainfo.oPerformerPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Author=", oscl_strlen("Author="))) |
| { |
| sptr = sptr + oscl_strlen("Author="); |
| assetbox = (int) AssetInfoType::AUTHOR; |
| ainfo.oAuthorPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Genre=", oscl_strlen("Genre="))) |
| { |
| sptr = sptr + oscl_strlen("Genre="); |
| assetbox = (int) AssetInfoType::GENRE; |
| ainfo.oGenrePresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Rating=", oscl_strlen("Rating="))) |
| { |
| sptr = sptr + oscl_strlen("Rating="); |
| assetbox = (int) AssetInfoType::RATING; |
| ainfo.oRatingPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Classification=", oscl_strlen("Classification="))) |
| { |
| sptr = sptr + oscl_strlen("Classification="); |
| assetbox = (int) AssetInfoType::CLASSIFICATION; |
| ainfo.oClassificationPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Keywords=", oscl_strlen("Keywords="))) |
| { |
| sptr = sptr + oscl_strlen("Keywords="); |
| assetbox = (int) AssetInfoType::KEYWORDS; |
| ainfo.oKeyWordsPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Location=", oscl_strlen("Location="))) |
| { |
| sptr = sptr + oscl_strlen("Location="); |
| assetbox = (int) AssetInfoType::LOCATION; |
| ainfo.oLocationPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "Album=", oscl_strlen("Album="))) |
| { |
| sptr = sptr + oscl_strlen("Album="); |
| assetbox = (int) AssetInfoType::ALBUM; |
| ainfo.oAlbumPresent = true; |
| } |
| else if (!oscl_CIstrncmp(sptr, "RecordingYear=", oscl_strlen("RecordingYear="))) |
| { |
| sptr = sptr + oscl_strlen("RecordingYear="); |
| assetbox = (int) AssetInfoType::RECORDINGYEAR; |
| ainfo.oRecordingYearPresent = true; |
| } |
| else// if(!oscl_CIstrncmp(sptr, "asset-extention=", oscl_strlen("asset-extention="))) |
| {//asset-extension ignore for now |
| //sptr = sptr + oscl_strlen("asset-extention="); |
| assetbox = (int) AssetInfoType::ASSET_EXTENTION; |
| ainfo.oAssetExtensionPresent = true; |
| } |
| |
| sptr = skip_whitespace(sptr, line_end_ptr); |
| if (sptr > line_end_ptr) |
| return false; |
| |
| for (eptr = sptr; *eptr != '}'; ++eptr) |
| { |
| if (eptr > line_end_ptr) |
| return false; |
| } |
| |
| { |
| //(here sptr is the complete value of base64 encoded metadata) |
| uint8* inBuf = (uint8*)sptr; |
| //(length of base64 encode metadata value) |
| uint32 inBufLen = (eptr - sptr); |
| //(string to collect the base64 decoded data) |
| uint8* outBuf = (uint8*)oscl_malloc(inBufLen); |
| if (outBuf != NULL) |
| { |
| //(max length of the base64 decoded data) |
| uint32 maxoutBuflen = inBufLen; |
| uint32 outBuflen = 0; |
| sdp_decodebase64(inBuf, inBufLen, outBuf, outBuflen, maxoutBuflen); |
| //4 bytes size, 4 bytes fourcc, 4 bytes flags |
| uint32 assetinfoatomoffset = 12; |
| if (outBuflen > assetinfoatomoffset) |
| { |
| uint8* buf = outBuf + assetinfoatomoffset; |
| if ((assetbox == AssetInfoType::TITLE) || |
| (assetbox == AssetInfoType::DESCRIPTION) || |
| (assetbox == AssetInfoType::COPYRIGHT) || |
| (assetbox == AssetInfoType::PERFORMER) || |
| (assetbox == AssetInfoType::AUTHOR) || |
| (assetbox == AssetInfoType::GENRE) || |
| (assetbox == AssetInfoType::ALBUM) || |
| (assetbox == AssetInfoType::RATING) || |
| (assetbox == AssetInfoType::CLASSIFICATION)) |
| { |
| char rating_entity[21]; |
| char rating_criteria[21]; |
| if (assetbox == AssetInfoType::RATING) |
| { |
| oscl_snprintf(rating_entity, |
| oscl_strlen(PVSDPMETADATA_RATING_ENTITY) + 4, |
| "%s%s", |
| PVSDPMETADATA_RATING_ENTITY, buf); |
| buf += 4; |
| rating_entity[20] = '\0'; |
| oscl_snprintf(rating_criteria, |
| oscl_strlen(PVSDPMETADATA_RATING_CRITERIA) + 4, |
| "%s%s", |
| PVSDPMETADATA_RATING_CRITERIA, buf); |
| buf += 4; |
| rating_criteria[20] = '\0'; |
| } |
| char classification_entity[26]; |
| char classification_table[26]; |
| if (assetbox == AssetInfoType::CLASSIFICATION) |
| { |
| oscl_snprintf(classification_entity, |
| oscl_strlen(PVSDPMETADATA_CLASSIFICATION_ENTITY) + 4, |
| "%s%s", |
| PVSDPMETADATA_CLASSIFICATION_ENTITY, buf); |
| buf += 4; |
| classification_entity[25] = '\0'; |
| oscl_snprintf(classification_table, |
| oscl_strlen(PVSDPMETADATA_CLASSFICATION_TABLE) + 2, |
| "%s%s", |
| PVSDPMETADATA_CLASSFICATION_TABLE, buf); |
| buf += 2; |
| classification_table[25] = '\0'; |
| } |
| uint16 lang = *buf++; |
| lang = ((lang << 8) | (*buf++)); |
| char LangCode[4]; |
| pvSDPParserGetAssetInfoLanguageCode(lang, LangCode); |
| char lang_param[21]; |
| oscl_snprintf(lang_param, |
| oscl_strlen(PVSDPMETADATA_LANG_CODE) + 4, |
| "%s%s", PVSDPMETADATA_LANG_CODE, LangCode); |
| lang_param[20] = '\0'; |
| uint16 byteOrderMask = *buf; |
| byteOrderMask = |
| ((byteOrderMask << 8) | (*(buf + 1))); |
| if (byteOrderMask == BYTE_ORDER_MASK) |
| { |
| buf += 2; |
| OsclBinIStreamBigEndian datastream; |
| datastream.Attach((void *)(buf), (outBuflen - assetinfoatomoffset - 2)); |
| //(string to collect the utf8 data) |
| uint8* utf8Buf = (uint8*)oscl_malloc(inBufLen); |
| oscl_memset(utf8Buf, 0, inBufLen); |
| int32 unicodebuflen = (int32)((outBuflen - assetinfoatomoffset - 2) / 2); |
| oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc((unicodebuflen + 1) * sizeof(oscl_wchar)); |
| oscl_memset(unicodeBuf, 0, (unicodebuflen + 1)*sizeof(oscl_wchar)); |
| for (int32 i = 0; i < unicodebuflen; i++) |
| { |
| uint16 temp = 0; |
| datastream >> temp; |
| unicodeBuf[i] = (uint16)(temp); |
| } |
| oscl_UnicodeToUTF8(unicodeBuf, |
| unicodebuflen, |
| (char*)utf8Buf, |
| inBufLen); |
| ainfo.Box[assetbox].set((const char *)(utf8Buf), |
| oscl_strlen((const char*)utf8Buf)); |
| oscl_free(utf8Buf); |
| oscl_free(unicodeBuf); |
| } |
| else |
| { |
| ainfo.Box[assetbox].set((const char *)(buf), |
| (outBuflen - assetinfoatomoffset)); |
| } |
| ainfo.Box[assetbox] += lang_param; |
| if (assetbox == AssetInfoType::RATING) |
| { |
| ainfo.Box[assetbox] += rating_entity; |
| ainfo.Box[assetbox] += rating_criteria; |
| } |
| else if (assetbox == AssetInfoType::CLASSIFICATION) |
| { |
| ainfo.Box[assetbox] += classification_entity; |
| ainfo.Box[assetbox] += classification_table; |
| } |
| } |
| else if (assetbox == AssetInfoType::RECORDINGYEAR) |
| { |
| ainfo.iRecordingYear = 0; |
| ainfo.iRecordingYear = *buf++; |
| ainfo.iRecordingYear = ((ainfo.iRecordingYear << 8) | (*buf++)); |
| } |
| else if (assetbox == AssetInfoType::KEYWORDS) |
| { |
| uint16 lang = *buf++; |
| lang = ((lang << 8) | (*buf++)); |
| char LangCode[4]; |
| pvSDPParserGetAssetInfoLanguageCode(lang, LangCode); |
| char lang_param[21]; |
| oscl_snprintf(lang_param, |
| oscl_strlen(PVSDPMETADATA_LANG_CODE) + 4, |
| "%s%s", PVSDPMETADATA_LANG_CODE, LangCode); |
| lang_param[20] = '\0'; |
| ainfo.iNumKeyWords = (uint32)(*buf++); |
| for (uint32 i = 0; i < ainfo.iNumKeyWords; i++) |
| { |
| OSCL_HeapString<OsclMemAllocator> keyWordString; |
| uint32 keywordsize = (uint32)(*buf++); |
| uint16 byteOrderMask = *buf; |
| byteOrderMask = |
| ((byteOrderMask << 8) | (*(buf + 1))); |
| if (byteOrderMask == BYTE_ORDER_MASK) |
| { |
| buf += 2; |
| keywordsize -= 2; |
| OsclBinIStreamBigEndian datastream; |
| datastream.Attach((void *)(buf), keywordsize); |
| //(string to collect the utf8 data) |
| uint8* utf8Buf = (uint8*)oscl_malloc(keywordsize); |
| oscl_memset(utf8Buf, 0, keywordsize); |
| int32 unicodebuflen = (int32)((keywordsize) / 2); |
| oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc((unicodebuflen + 1) * sizeof(oscl_wchar)); |
| oscl_memset(unicodeBuf, 0, (unicodebuflen + 1)*sizeof(oscl_wchar)); |
| for (int32 i = 0; i < unicodebuflen; i++) |
| { |
| uint16 temp = 0; |
| datastream >> temp; |
| unicodeBuf[i] = (uint16)(temp); |
| } |
| oscl_UnicodeToUTF8(unicodeBuf, |
| unicodebuflen, |
| (char*)utf8Buf, |
| inBufLen); |
| keyWordString.set((const char *)(utf8Buf), |
| oscl_strlen((const char*)utf8Buf)); |
| oscl_free(utf8Buf); |
| oscl_free(unicodeBuf); |
| buf += keywordsize; |
| } |
| else |
| { |
| keyWordString.set((const char *)(buf), keywordsize); |
| buf += keywordsize; |
| } |
| keyWordString += lang_param; |
| ainfo.KeyWords[i] = keyWordString; |
| } |
| } |
| else if (assetbox == AssetInfoType::LOCATION) |
| { |
| if (pvSDPParserParse3GPPAssetInfoLocation(ainfo, buf, outBuflen) != true) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| ainfo.Box[assetbox].set((const char *)(buf), |
| (outBuflen - assetinfoatomoffset)); |
| } |
| } |
| oscl_free(outBuf); |
| } |
| } |
| eptr = eptr + 1; |
| sptr = eptr + 1; |
| } |
| |
| return true; |
| } |
| |
| |