1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19 #include "oscl_string_utils.h" 20 #include "common_info.h" 21 #include "rtsp_range_utils.h" 22 #include "oscl_str_ptr_len.h" 23 #include "oscl_stdstring.h" 24 #include "sdp_parsing_utils.h" 25 #include "oscl_utf8conv.h" 26 #include "oscl_snprintf.h" 27 #include "oscl_bin_stream.h" 28 29 #define BYTE_ORDER_MASK 0xFEFF 30 static const char PVSDPMETADATA_LANG_CODE[] = ";iso-639-2-lang="; 31 static const char PVSDPMETADATA_RATING_ENTITY[] = ";rating-entity="; 32 static const char PVSDPMETADATA_RATING_CRITERIA[] = ";rating-criteria="; 33 static const char PVSDPMETADATA_CLASSIFICATION_ENTITY[] = ";classification-entity="; 34 static const char PVSDPMETADATA_CLASSFICATION_TABLE[] = ";classification-table="; 35 36 bool get_next_line(const char *start_ptr, const char * end_ptr, 37 const char *& line_start, 38 const char *& line_end) 39 { 40 // Finds the boundaries of the next non-empty line within start 41 // and end ptrs 42 43 // This initializes line_start to the first non-whitespace character 44 line_start = skip_whitespace_and_line_term(start_ptr, end_ptr); 45 46 line_end = skip_to_line_term(line_start, end_ptr); 47 48 return (line_start < end_ptr); 49 50 } 51 52 bool sdp_decodebase64(uint8* aInBuf, uint32 aInBufLen, 53 uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen) 54 { 55 oscl_memset(aOutBuf, 0, aMaxOutBufLen); 56 aOutBufLen = 0; 57 58 int i; 59 uint8 dtable[256]; 60 61 for (i = 0; i < 255; i++) 62 { 63 dtable[i] = 0x80; 64 } 65 for (i = 'A'; i <= 'I'; i++) 66 { 67 dtable[i] = 0 + (i - 'A'); 68 } 69 for (i = 'J'; i <= 'R'; i++) 70 { 71 dtable[i] = 9 + (i - 'J'); 72 } 73 for (i = 'S'; i <= 'Z'; i++) 74 { 75 dtable[i] = 18 + (i - 'S'); 76 } 77 for (i = 'a'; i <= 'i'; i++) 78 { 79 dtable[i] = 26 + (i - 'a'); 80 } 81 for (i = 'j'; i <= 'r'; i++) 82 { 83 dtable[i] = 35 + (i - 'j'); 84 } 85 for (i = 's'; i <= 'z'; i++) 86 { 87 dtable[i] = 44 + (i - 's'); 88 } 89 for (i = '0'; i <= '9'; i++) 90 { 91 dtable[i] = 52 + (i - '0'); 92 } 93 dtable[(int)'+'] = 62; 94 dtable[(int)'/'] = 63; 95 dtable[(int)'='] = 0; 96 97 uint32 read_count = 0; 98 uint32 write_count = 0; 99 while (read_count < aInBufLen) 100 { 101 uint8 a[4], b[4], o[3]; 102 103 for (i = 0; i < 4; i++) 104 { 105 uint8 c = *(aInBuf++); 106 read_count++; 107 108 if (read_count > aInBufLen) 109 { 110 //Input incomplete 111 return false; 112 } 113 if (dtable[(int)c]&0x80) 114 { 115 //Illegal character in 116 //return false; 117 i--; 118 continue; 119 } 120 a[i] = (uint8)c; 121 b[i] = (uint8)dtable[(int)c]; 122 } 123 o[0] = (b[0] << 2) | (b[1] >> 4); 124 o[1] = (b[1] << 4) | (b[2] >> 2); 125 o[2] = (b[2] << 6) | b[3]; 126 i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); 127 oscl_memcpy(aOutBuf, o, i); 128 aOutBuf += i; 129 write_count += i; 130 if (write_count > aMaxOutBufLen) 131 { 132 return false; 133 } 134 if (i < 3) 135 { 136 break; 137 } 138 } 139 aOutBufLen = write_count; 140 return true; 141 } 142 143 144 bool parseQoEMetrics(const char *start_ptr, const char *end_ptr, QoEMetricsType &qoeMetrics) 145 { 146 const char *sptr = start_ptr; 147 const char *eptr = end_ptr; 148 149 sptr = skip_whitespace_and_line_term(sptr, end_ptr); 150 151 StrPtrLen rate("rate="); 152 StrPtrLen range("range:"); 153 154 if (!oscl_strncmp(sptr, "{", 1)) 155 sptr = sptr + 1; 156 else 157 return false; 158 159 sptr = skip_whitespace_and_line_term(sptr, end_ptr); 160 if (sptr > eptr) 161 return false; 162 163 while (sptr < end_ptr) 164 { 165 166 if (!oscl_strncmp(sptr, "Initial_Buffering_Duration", 167 oscl_strlen("Initial_Buffering_Duration"))) 168 { 169 qoeMetrics.name[QoEMetricsType::INITIAL_BUFFERING_DURATION] = true; 170 sptr = sptr + oscl_strlen("Initial_Buffering_Duration"); 171 } 172 else if (!oscl_strncmp(sptr, "Rebuffering_Duration", 173 oscl_strlen("Rebuffering_Duration"))) 174 { 175 qoeMetrics.name[QoEMetricsType::REBUFFERING_DURATION] = true; 176 sptr = sptr + oscl_strlen("Rebuffering_Duration"); 177 } 178 else if (!oscl_strncmp(sptr, "Corruption_Duration", 179 oscl_strlen("Corruption_Duration"))) 180 { 181 qoeMetrics.name[QoEMetricsType::CORRUPTION_DURATION] = true; 182 sptr = sptr + oscl_strlen("Corruption_Duration"); 183 } 184 else if (!oscl_strncmp(sptr, "Succssive_Loss", 185 oscl_strlen("Succssive_Loss"))) 186 { 187 qoeMetrics.name[QoEMetricsType::SUCESSIVE_LOSS] = true; 188 sptr = sptr + oscl_strlen("Succssive_Loss"); 189 } 190 else if (!oscl_strncmp(sptr, "Framerate_Deviation", 191 oscl_strlen("Framerate_Deviation"))) 192 { 193 qoeMetrics.name[QoEMetricsType::FRAMERATE_DEVIATION] = true; 194 sptr = sptr + oscl_strlen("Framerate_Deviation"); 195 } 196 else if (!oscl_strncmp(sptr, "Jitter_Duration", 197 oscl_strlen("Jitter_Duration"))) 198 { 199 qoeMetrics.name[QoEMetricsType::JITTER_DURATION] = true; 200 sptr = sptr + oscl_strlen("Jitter_Duration"); 201 } 202 else if (!oscl_strncmp(sptr, "Decoded_Bytes", 203 oscl_strlen("Decoded_Bytes"))) 204 { 205 qoeMetrics.name[QoEMetricsType::DECODED_BYTES] = true; 206 sptr = sptr + oscl_strlen("Decoded_Bytes"); 207 } 208 else 209 return false; 210 211 sptr = skip_whitespace_and_line_term(sptr, end_ptr); 212 if (sptr > end_ptr) 213 return false; 214 215 if (!oscl_strncmp(sptr, ",", 1)) 216 sptr = sptr + 1; 217 else if (!oscl_strncmp(sptr, "}", 1)) 218 { 219 sptr = sptr + 1; 220 break; 221 } 222 } 223 224 if (sptr > end_ptr) 225 return false; 226 227 if (!oscl_strncmp(sptr, ";", 1)) 228 sptr = sptr + 1; 229 else 230 return false; 231 232 if (!oscl_strncmp(sptr, rate.c_str(), rate.length())) 233 { 234 sptr = sptr + rate.length(); 235 if (!oscl_strncmp(sptr, "End", oscl_strlen("End"))) 236 { 237 qoeMetrics.rateFmt = QoEMetricsType::END; 238 qoeMetrics.rateEnd = 'E'; 239 sptr = sptr + oscl_strlen("End"); 240 241 } 242 else 243 { 244 uint32 temp; 245 eptr = sptr; //get length of range digit 246 for (; (*eptr != ';' && eptr < end_ptr); ++eptr); 247 248 qoeMetrics.rateFmt = QoEMetricsType::VAL; 249 250 if (PV_atoi(sptr, 'd', (int)(eptr - sptr), temp)) 251 { 252 qoeMetrics.rateVal = temp; 253 sptr = eptr ; 254 } 255 else 256 return false; 257 } 258 259 } 260 else 261 return false; 262 263 if (sptr == end_ptr) //end of line reached. 264 return true; 265 266 if (sptr > end_ptr) 267 return false; 268 269 if (!oscl_strncmp(sptr, ";", 1)) 270 sptr = sptr + 1; 271 else 272 return false; 273 if (!oscl_strncmp(sptr, range.c_str(), range.length())) 274 { 275 eptr = sptr + range.length(); 276 for (; *eptr != ';' && eptr != end_ptr ; eptr++); // get length of range. 277 278 if (!parseRtspRange((sptr + range.length()), (eptr - sptr - range.length()), 279 qoeMetrics.range)) 280 return false; 281 } 282 283 sptr = eptr; 284 if (sptr == end_ptr) 285 return true; // end of line reached. 286 else //Parameter_Ext 287 { 288 sptr = eptr + 1; 289 if (!oscl_strncmp(sptr, "On", oscl_strlen("On"))) 290 { 291 qoeMetrics.paramExtStat = true; 292 qoeMetrics.paramFmt = QoEMetricsType::STATUS; 293 } 294 else if (!oscl_strncmp(sptr, "Off", oscl_strlen("Off"))) 295 { 296 qoeMetrics.paramExtStat = false; 297 qoeMetrics.paramFmt = QoEMetricsType::STATUS; 298 } 299 else 300 { 301 uint32 len = OSCL_MIN((uint32)(eptr - sptr), oscl_strlen(".")); 302 if (oscl_strncmp(sptr, ".", len) == 0) //if floating point number 303 { 304 if (!PV_atof(sptr, (int)(eptr - sptr), qoeMetrics.paramExtFdigit)) 305 return false; 306 qoeMetrics.paramFmt = QoEMetricsType::FDIGIT; 307 } 308 else // hex digit 309 { 310 uint32 temp; 311 if (PV_atoi(sptr, 'x', (int)(eptr - sptr), temp)) 312 { 313 qoeMetrics.paramExtIdigit = temp; 314 qoeMetrics.paramFmt = QoEMetricsType::IDIGIT; 315 316 } 317 else 318 return false; 319 } 320 321 } 322 323 324 } 325 326 return true; 327 328 } 329 330 void pvSDPParserGetAssetInfoLanguageCode(uint16 langcode, char* LangCode) 331 { 332 //ISO-639-2/T 3-char Lang Code 333 oscl_memset(LangCode, 0, 4); 334 LangCode[0] = 0x60 + ((langcode >> 10) & 0x1F); 335 LangCode[1] = 0x60 + ((langcode >> 5) & 0x1F); 336 LangCode[2] = 0x60 + ((langcode) & 0x1F); 337 } 338 339 bool pvSDPParserParse3GPPAssetInfoLocation(AssetInfoType& ainfo, 340 uint8* aBuf, 341 uint32 aBufSize) 342 { 343 uint32 count = 0; 344 uint16 lang = *aBuf++; 345 lang = ((lang << 8) | (*aBuf++)); 346 count += 2; 347 uint16 byteOrderMask = 0; 348 byteOrderMask = *aBuf; 349 byteOrderMask = 350 ((byteOrderMask << 8) | (*(aBuf + 1))); 351 if (byteOrderMask == BYTE_ORDER_MASK) 352 { 353 aBuf += 2; 354 uint32 index = 0; 355 uint8 firstbyte = aBuf[index]; 356 uint8 secondbyte = aBuf[index++]; 357 oscl_wchar wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); 358 bool nextChar = (wc == 0) ? false : true; 359 while (nextChar && (index < aBufSize)) 360 { 361 firstbyte = aBuf[index]; 362 secondbyte = aBuf[index++]; 363 wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); 364 nextChar = (wc == 0) ? false : true; 365 } 366 ainfo.iLocationStruct._location_name = 367 (oscl_wchar*)(oscl_malloc(sizeof(oscl_wchar) * (index + 1))); 368 if (ainfo.iLocationStruct._location_name == NULL) return false; 369 oscl_memcpy(ainfo.iLocationStruct._location_name, aBuf, (index*2)); 370 } 371 else 372 { 373 uint32 index = 0; 374 bool nextChar = (aBuf[index] == 0) ? false : true; 375 while (nextChar && (index < aBufSize)) 376 { 377 index++; 378 nextChar = (aBuf[index] == 0) ? false : true; 379 } 380 oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (index + 1)); 381 if (unicodeBuf == NULL) return false; 382 oscl_UTF8ToUnicode((char*)aBuf, 383 index, 384 unicodeBuf, 385 index + 1); 386 ainfo.iLocationStruct._location_name = unicodeBuf; 387 } 388 ainfo.iLocationStruct._role = *aBuf++; 389 uint32 i; 390 ainfo.iLocationStruct._longitude = 0; 391 for (i = 0; i < 4; i++) 392 { 393 ainfo.iLocationStruct._longitude |= *aBuf++; 394 } 395 ainfo.iLocationStruct._latitude = 0; 396 for (i = 0; i < 4; i++) 397 { 398 ainfo.iLocationStruct._latitude |= *aBuf++; 399 } 400 ainfo.iLocationStruct._altitude = 0; 401 for (i = 0; i < 4; i++) 402 { 403 ainfo.iLocationStruct._altitude |= *aBuf++; 404 } 405 byteOrderMask = *aBuf; 406 byteOrderMask = 407 ((byteOrderMask << 8) | (*(aBuf + 1))); 408 if (byteOrderMask == BYTE_ORDER_MASK) 409 { 410 aBuf += 2; 411 uint32 index = 0; 412 uint8 firstbyte = aBuf[index]; 413 uint8 secondbyte = aBuf[index++]; 414 oscl_wchar wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); 415 bool nextChar = (wc == 0) ? false : true; 416 while (nextChar && (index < aBufSize)) 417 { 418 firstbyte = aBuf[index]; 419 secondbyte = aBuf[index++]; 420 wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); 421 nextChar = (wc == 0) ? false : true; 422 } 423 ainfo.iLocationStruct._astronomical_body = 424 (oscl_wchar*)(oscl_malloc(sizeof(oscl_wchar) * (index + 1))); 425 if (ainfo.iLocationStruct._astronomical_body == NULL) return false; 426 oscl_memcpy(ainfo.iLocationStruct._astronomical_body, aBuf, (index*2)); 427 } 428 else 429 { 430 uint32 index = 0; 431 bool nextChar = (aBuf[index] == 0) ? false : true; 432 while (nextChar && (index < aBufSize)) 433 { 434 index++; 435 nextChar = (aBuf[index] == 0) ? false : true; 436 } 437 oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (index + 1)); 438 if (unicodeBuf == NULL) return false; 439 oscl_UTF8ToUnicode((char*)aBuf, 440 index, 441 unicodeBuf, 442 index + 1); 443 ainfo.iLocationStruct._astronomical_body = unicodeBuf; 444 } 445 byteOrderMask = *aBuf; 446 byteOrderMask = 447 ((byteOrderMask << 8) | (*(aBuf + 1))); 448 if (byteOrderMask == BYTE_ORDER_MASK) 449 { 450 aBuf += 2; 451 uint32 index = 0; 452 uint8 firstbyte = aBuf[index]; 453 uint8 secondbyte = aBuf[index++]; 454 oscl_wchar wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); 455 bool nextChar = (wc == 0) ? false : true; 456 while (nextChar && (index < aBufSize)) 457 { 458 firstbyte = aBuf[index]; 459 secondbyte = aBuf[index++]; 460 wc = (uint16)(firstbyte << 8 | (uint16) secondbyte); 461 nextChar = (wc == 0) ? false : true; 462 } 463 ainfo.iLocationStruct._additional_notes = 464 (oscl_wchar*)(oscl_malloc(sizeof(oscl_wchar) * index)); 465 if (ainfo.iLocationStruct._additional_notes == NULL) return false; 466 oscl_memcpy(ainfo.iLocationStruct._additional_notes, aBuf, (index*2)); 467 } 468 else 469 { 470 uint32 index = 0; 471 bool nextChar = (aBuf[index] == 0) ? false : true; 472 while (nextChar && (index < aBufSize)) 473 { 474 index++; 475 nextChar = (aBuf[index] == 0) ? false : true; 476 } 477 oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (index + 1)); 478 if (unicodeBuf == NULL) return false; 479 oscl_UTF8ToUnicode((char*)aBuf, 480 index, 481 unicodeBuf, 482 index + 1); 483 ainfo.iLocationStruct._additional_notes = unicodeBuf; 484 } 485 return true; 486 } 487 488 489 bool parseAssetInfo(const char *sptr, const char *line_end_ptr, AssetInfoType &ainfo) 490 { 491 const char *eptr = sptr; 492 int assetbox; 493 494 while (eptr < line_end_ptr) 495 { 496 sptr = skip_whitespace(sptr, line_end_ptr); 497 if (oscl_CIstrncmp(sptr, "{", 1)) 498 return false; 499 sptr = sptr + 1; 500 sptr = skip_whitespace(sptr, line_end_ptr); 501 if (sptr > line_end_ptr) 502 return false; 503 504 if (!oscl_CIstrncmp(sptr, "url=", oscl_strlen("url="))) 505 { 506 sptr = sptr + oscl_strlen("url="); 507 sptr = skip_whitespace(sptr, line_end_ptr); 508 if (sptr > line_end_ptr) 509 return false; 510 if (!oscl_CIstrncmp(sptr, "\"", 1)) 511 { 512 sptr = sptr + 1; 513 sptr = skip_whitespace(sptr, line_end_ptr); 514 if (sptr > line_end_ptr) 515 return false; 516 eptr = sptr; 517 518 for (; *eptr != '"'; ++eptr); 519 520 ainfo.URL.set((const char *)sptr, (eptr - sptr)); 521 } 522 else 523 { 524 eptr = sptr; 525 526 for (; *eptr != '}'; ++eptr); 527 528 ainfo.URL.set((const char *)sptr, (eptr - sptr)); 529 } 530 return true; 531 532 } 533 534 if (!oscl_CIstrncmp(sptr, "Title=", oscl_strlen("Title="))) 535 { 536 sptr = sptr + oscl_strlen("Title="); 537 assetbox = (int) AssetInfoType::TITLE; 538 ainfo.oTitlePresent = true; 539 } 540 else if (!oscl_CIstrncmp(sptr, "Description=", oscl_strlen("Description="))) 541 { 542 sptr = sptr + oscl_strlen("Description="); 543 assetbox = (int) AssetInfoType::DESCRIPTION; 544 ainfo.oDescriptionPresent = true; 545 } 546 else if (!oscl_CIstrncmp(sptr, "Copyright=", oscl_strlen("Copyright="))) 547 { 548 sptr = sptr + oscl_strlen("Copyright="); 549 assetbox = (int) AssetInfoType::COPYRIGHT; 550 ainfo.oCopyRightPresent = true; 551 } 552 else if (!oscl_CIstrncmp(sptr, "Performer=", oscl_strlen("Performer="))) 553 { 554 sptr = sptr + oscl_strlen("Performer="); 555 assetbox = (int) AssetInfoType::PERFORMER; 556 ainfo.oPerformerPresent = true; 557 } 558 else if (!oscl_CIstrncmp(sptr, "Author=", oscl_strlen("Author="))) 559 { 560 sptr = sptr + oscl_strlen("Author="); 561 assetbox = (int) AssetInfoType::AUTHOR; 562 ainfo.oAuthorPresent = true; 563 } 564 else if (!oscl_CIstrncmp(sptr, "Genre=", oscl_strlen("Genre="))) 565 { 566 sptr = sptr + oscl_strlen("Genre="); 567 assetbox = (int) AssetInfoType::GENRE; 568 ainfo.oGenrePresent = true; 569 } 570 else if (!oscl_CIstrncmp(sptr, "Rating=", oscl_strlen("Rating="))) 571 { 572 sptr = sptr + oscl_strlen("Rating="); 573 assetbox = (int) AssetInfoType::RATING; 574 ainfo.oRatingPresent = true; 575 } 576 else if (!oscl_CIstrncmp(sptr, "Classification=", oscl_strlen("Classification="))) 577 { 578 sptr = sptr + oscl_strlen("Classification="); 579 assetbox = (int) AssetInfoType::CLASSIFICATION; 580 ainfo.oClassificationPresent = true; 581 } 582 else if (!oscl_CIstrncmp(sptr, "Keywords=", oscl_strlen("Keywords="))) 583 { 584 sptr = sptr + oscl_strlen("Keywords="); 585 assetbox = (int) AssetInfoType::KEYWORDS; 586 ainfo.oKeyWordsPresent = true; 587 } 588 else if (!oscl_CIstrncmp(sptr, "Location=", oscl_strlen("Location="))) 589 { 590 sptr = sptr + oscl_strlen("Location="); 591 assetbox = (int) AssetInfoType::LOCATION; 592 ainfo.oLocationPresent = true; 593 } 594 else if (!oscl_CIstrncmp(sptr, "Album=", oscl_strlen("Album="))) 595 { 596 sptr = sptr + oscl_strlen("Album="); 597 assetbox = (int) AssetInfoType::ALBUM; 598 ainfo.oAlbumPresent = true; 599 } 600 else if (!oscl_CIstrncmp(sptr, "RecordingYear=", oscl_strlen("RecordingYear="))) 601 { 602 sptr = sptr + oscl_strlen("RecordingYear="); 603 assetbox = (int) AssetInfoType::RECORDINGYEAR; 604 ainfo.oRecordingYearPresent = true; 605 } 606 else// if(!oscl_CIstrncmp(sptr, "asset-extention=", oscl_strlen("asset-extention="))) 607 {//asset-extension ignore for now 608 //sptr = sptr + oscl_strlen("asset-extention="); 609 assetbox = (int) AssetInfoType::ASSET_EXTENTION; 610 ainfo.oAssetExtensionPresent = true; 611 } 612 613 sptr = skip_whitespace(sptr, line_end_ptr); 614 if (sptr > line_end_ptr) 615 return false; 616 617 for (eptr = sptr; *eptr != '}'; ++eptr) 618 { 619 if (eptr > line_end_ptr) 620 return false; 621 } 622 623 { 624 //(here sptr is the complete value of base64 encoded metadata) 625 uint8* inBuf = (uint8*)sptr; 626 //(length of base64 encode metadata value) 627 uint32 inBufLen = (eptr - sptr); 628 //(string to collect the base64 decoded data) 629 uint8* outBuf = (uint8*)oscl_malloc(inBufLen); 630 if (outBuf != NULL) 631 { 632 //(max length of the base64 decoded data) 633 uint32 maxoutBuflen = inBufLen; 634 uint32 outBuflen = 0; 635 sdp_decodebase64(inBuf, inBufLen, outBuf, outBuflen, maxoutBuflen); 636 //4 bytes size, 4 bytes fourcc, 4 bytes flags 637 uint32 assetinfoatomoffset = 12; 638 if (outBuflen > assetinfoatomoffset) 639 { 640 uint8* buf = outBuf + assetinfoatomoffset; 641 if ((assetbox == AssetInfoType::TITLE) || 642 (assetbox == AssetInfoType::DESCRIPTION) || 643 (assetbox == AssetInfoType::COPYRIGHT) || 644 (assetbox == AssetInfoType::PERFORMER) || 645 (assetbox == AssetInfoType::AUTHOR) || 646 (assetbox == AssetInfoType::GENRE) || 647 (assetbox == AssetInfoType::ALBUM) || 648 (assetbox == AssetInfoType::RATING) || 649 (assetbox == AssetInfoType::CLASSIFICATION)) 650 { 651 char rating_entity[21]; 652 char rating_criteria[21]; 653 if (assetbox == AssetInfoType::RATING) 654 { 655 oscl_snprintf(rating_entity, 656 oscl_strlen(PVSDPMETADATA_RATING_ENTITY) + 4, 657 "%s%s", 658 PVSDPMETADATA_RATING_ENTITY, buf); 659 buf += 4; 660 rating_entity[20] = '\0'; 661 oscl_snprintf(rating_criteria, 662 oscl_strlen(PVSDPMETADATA_RATING_CRITERIA) + 4, 663 "%s%s", 664 PVSDPMETADATA_RATING_CRITERIA, buf); 665 buf += 4; 666 rating_criteria[20] = '\0'; 667 } 668 char classification_entity[26]; 669 char classification_table[26]; 670 if (assetbox == AssetInfoType::CLASSIFICATION) 671 { 672 oscl_snprintf(classification_entity, 673 oscl_strlen(PVSDPMETADATA_CLASSIFICATION_ENTITY) + 4, 674 "%s%s", 675 PVSDPMETADATA_CLASSIFICATION_ENTITY, buf); 676 buf += 4; 677 classification_entity[25] = '\0'; 678 oscl_snprintf(classification_table, 679 oscl_strlen(PVSDPMETADATA_CLASSFICATION_TABLE) + 2, 680 "%s%s", 681 PVSDPMETADATA_CLASSFICATION_TABLE, buf); 682 buf += 2; 683 classification_table[25] = '\0'; 684 } 685 uint16 lang = *buf++; 686 lang = ((lang << 8) | (*buf++)); 687 char LangCode[4]; 688 pvSDPParserGetAssetInfoLanguageCode(lang, LangCode); 689 char lang_param[21]; 690 oscl_snprintf(lang_param, 691 oscl_strlen(PVSDPMETADATA_LANG_CODE) + 4, 692 "%s%s", PVSDPMETADATA_LANG_CODE, LangCode); 693 lang_param[20] = '\0'; 694 uint16 byteOrderMask = *buf; 695 byteOrderMask = 696 ((byteOrderMask << 8) | (*(buf + 1))); 697 if (byteOrderMask == BYTE_ORDER_MASK) 698 { 699 buf += 2; 700 OsclBinIStreamBigEndian datastream; 701 datastream.Attach((void *)(buf), (outBuflen - assetinfoatomoffset - 2)); 702 //(string to collect the utf8 data) 703 uint8* utf8Buf = (uint8*)oscl_malloc(inBufLen); 704 oscl_memset(utf8Buf, 0, inBufLen); 705 int32 unicodebuflen = (int32)((outBuflen - assetinfoatomoffset - 2) / 2); 706 oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc((unicodebuflen + 1) * sizeof(oscl_wchar)); 707 oscl_memset(unicodeBuf, 0, (unicodebuflen + 1)*sizeof(oscl_wchar)); 708 for (int32 i = 0; i < unicodebuflen; i++) 709 { 710 uint16 temp = 0; 711 datastream >> temp; 712 unicodeBuf[i] = (uint16)(temp); 713 } 714 oscl_UnicodeToUTF8(unicodeBuf, 715 unicodebuflen, 716 (char*)utf8Buf, 717 inBufLen); 718 ainfo.Box[assetbox].set((const char *)(utf8Buf), 719 oscl_strlen((const char*)utf8Buf)); 720 oscl_free(utf8Buf); 721 oscl_free(unicodeBuf); 722 } 723 else 724 { 725 ainfo.Box[assetbox].set((const char *)(buf), 726 (outBuflen - assetinfoatomoffset)); 727 } 728 ainfo.Box[assetbox] += lang_param; 729 if (assetbox == AssetInfoType::RATING) 730 { 731 ainfo.Box[assetbox] += rating_entity; 732 ainfo.Box[assetbox] += rating_criteria; 733 } 734 else if (assetbox == AssetInfoType::CLASSIFICATION) 735 { 736 ainfo.Box[assetbox] += classification_entity; 737 ainfo.Box[assetbox] += classification_table; 738 } 739 } 740 else if (assetbox == AssetInfoType::RECORDINGYEAR) 741 { 742 ainfo.iRecordingYear = 0; 743 ainfo.iRecordingYear = *buf++; 744 ainfo.iRecordingYear = ((ainfo.iRecordingYear << 8) | (*buf++)); 745 } 746 else if (assetbox == AssetInfoType::KEYWORDS) 747 { 748 uint16 lang = *buf++; 749 lang = ((lang << 8) | (*buf++)); 750 char LangCode[4]; 751 pvSDPParserGetAssetInfoLanguageCode(lang, LangCode); 752 char lang_param[21]; 753 oscl_snprintf(lang_param, 754 oscl_strlen(PVSDPMETADATA_LANG_CODE) + 4, 755 "%s%s", PVSDPMETADATA_LANG_CODE, LangCode); 756 lang_param[20] = '\0'; 757 ainfo.iNumKeyWords = (uint32)(*buf++); 758 for (uint32 i = 0; i < ainfo.iNumKeyWords; i++) 759 { 760 OSCL_HeapString<OsclMemAllocator> keyWordString; 761 uint32 keywordsize = (uint32)(*buf++); 762 uint16 byteOrderMask = *buf; 763 byteOrderMask = 764 ((byteOrderMask << 8) | (*(buf + 1))); 765 if (byteOrderMask == BYTE_ORDER_MASK) 766 { 767 buf += 2; 768 keywordsize -= 2; 769 OsclBinIStreamBigEndian datastream; 770 datastream.Attach((void *)(buf), keywordsize); 771 //(string to collect the utf8 data) 772 uint8* utf8Buf = (uint8*)oscl_malloc(keywordsize); 773 oscl_memset(utf8Buf, 0, keywordsize); 774 int32 unicodebuflen = (int32)((keywordsize) / 2); 775 oscl_wchar* unicodeBuf = (oscl_wchar*)oscl_malloc((unicodebuflen + 1) * sizeof(oscl_wchar)); 776 oscl_memset(unicodeBuf, 0, (unicodebuflen + 1)*sizeof(oscl_wchar)); 777 for (int32 i = 0; i < unicodebuflen; i++) 778 { 779 uint16 temp = 0; 780 datastream >> temp; 781 unicodeBuf[i] = (uint16)(temp); 782 } 783 oscl_UnicodeToUTF8(unicodeBuf, 784 unicodebuflen, 785 (char*)utf8Buf, 786 inBufLen); 787 keyWordString.set((const char *)(utf8Buf), 788 oscl_strlen((const char*)utf8Buf)); 789 oscl_free(utf8Buf); 790 oscl_free(unicodeBuf); 791 buf += keywordsize; 792 } 793 else 794 { 795 keyWordString.set((const char *)(buf), keywordsize); 796 buf += keywordsize; 797 } 798 keyWordString += lang_param; 799 ainfo.KeyWords[i] = keyWordString; 800 } 801 } 802 else if (assetbox == AssetInfoType::LOCATION) 803 { 804 if (pvSDPParserParse3GPPAssetInfoLocation(ainfo, buf, outBuflen) != true) 805 { 806 return false; 807 } 808 } 809 else 810 { 811 ainfo.Box[assetbox].set((const char *)(buf), 812 (outBuflen - assetinfoatomoffset)); 813 } 814 } 815 oscl_free(outBuf); 816 } 817 } 818 eptr = eptr + 1; 819 sptr = eptr + 1; 820 } 821 822 return true; 823 } 824 825 826