blob: 9875fec25dc524673717bb771903e20750d31da0 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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;
}