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 * @file pv_id3_parcom_types.cpp 20 * @brief Type definitions for ID3 Parser-Composer 21 */ 22 23 #ifndef PV_ID3_PARCOM_H_INCLUDED 24 #include "pv_id3_parcom.h" 25 #endif 26 #ifndef PV_ID3_PARCOM_CONSTANTS_H_INCLUDED 27 #include "pv_id3_parcom_constants.h" 28 #endif 29 #ifndef OSCL_SNPRINTF_H_INCLUDED 30 #include "oscl_snprintf.h" 31 #endif 32 #ifndef PVLOGGER_H_INCLUDED 33 #include "pvlogger.h" 34 #endif 35 #ifndef PVMI_KVP_UTIL_H_INCLUDED 36 #include "pvmi_kvp_util.h" 37 #endif 38 #ifndef OSCL_MIME_STRING_UTILS_H 39 #include "pv_mime_string_utils.h" 40 #endif 41 #ifndef OSCL_DLL_H_INCLUDED 42 #include "oscl_dll.h" 43 #endif 44 #ifndef WCHAR_SIZE_UTILS_H_INCLUDED 45 #include "wchar_size_utils.h" 46 #endif 47 48 #define LOG_STACK_TRACE(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, m); 49 #define LOG_DEBUG(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, m); 50 #define LOG_ERR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m); 51 52 #ifndef NULL_TERM_CHAR 53 #define NULL_TERM_CHAR '\0' 54 #endif 55 56 // DLL entry point 57 OSCL_DLL_ENTRY_POINT_DEFAULT() 58 59 //////////////////////////////////////////////////////////////////////////// 60 class PVID3ParComKvpCleanupDA : public OsclDestructDealloc 61 { 62 public: 63 PVID3ParComKvpCleanupDA(Oscl_DefAlloc* in_gen_alloc) : 64 gen_alloc(in_gen_alloc) {}; 65 virtual ~PVID3ParComKvpCleanupDA() {}; 66 67 virtual void destruct_and_dealloc(OsclAny* ptr) 68 { 69 // no need to call destructors in this case just dealloc 70 gen_alloc->deallocate(ptr); 71 } 72 73 private: 74 Oscl_DefAlloc* gen_alloc; 75 }; 76 77 //////////////////////////////////////////////////////////////////////////// 78 OSCL_EXPORT_REF PVID3ParCom::PVID3ParCom() 79 : iInputFile(NULL), 80 iTitleFoundFlag(false), 81 iArtistFoundFlag(false), 82 iAlbumFoundFlag(false), 83 iYearFoundFlag(false), 84 iCommentFoundFlag(false), 85 iTrackNumberFoundFlag(false), 86 iGenereFoundFlag(false), 87 iFileSizeInBytes(0), 88 iByteOffsetToStartOfAudioFrames(0), 89 iID3V1Present(false), 90 iID3V2Present(false), 91 iVersion(PV_ID3_INVALID_VERSION), 92 iUseMaxTagSize(false), 93 iMaxTagSize(0), 94 iUsePadding(false), 95 iTagAtBof(false), 96 iSeekFrameFound(false) 97 { 98 iLogger = PVLogger::GetLoggerObject("PVID3ParCom"); 99 iID3TagInfo.iID3V2ExtendedHeaderSize = 0; 100 iID3TagInfo.iID3V2FrameSize = 0; 101 iID3TagInfo.iID3V2TagFlagsV2 = 0; 102 iID3TagInfo.iID3V2TagSize = 0 ; 103 iID3TagInfo.iFooterPresent = false; 104 105 oscl_memset(&iID3TagInfo.iID3V2FrameFlag, 0, sizeof(iID3TagInfo.iID3V2FrameFlag)); 106 107 } 108 109 //////////////////////////////////////////////////////////////////////////// 110 OSCL_EXPORT_REF PVID3ParCom::~PVID3ParCom() 111 { 112 iFrames.clear(); 113 } 114 115 //////////////////////////////////////////////////////////////////////////// 116 OSCL_EXPORT_REF uint32 PVID3ParCom::GetID3TagSize(PVFile* aFile) 117 { 118 if (!aFile) 119 { 120 return 0; 121 } 122 123 iInputFile = aFile; 124 125 if (iInputFile->Seek(0, Oscl_File::SEEKSET) == -1) 126 { 127 iFileSizeInBytes = 0; 128 } 129 else 130 { 131 iInputFile->GetRemainingBytes((uint32&)iFileSizeInBytes); 132 if (iInputFile->Seek(0, Oscl_File::SEEKSET) == -1) 133 { 134 return 0; 135 } 136 } 137 138 uint32 buffsize = 100; //number of bytes to search , from the end of file, to look for footer 139 if (CheckForTagID3V2() 140 || (LookForV2_4Footer(buffsize, 0) == PVMFSuccess)) 141 { 142 if (iInputFile->Seek(2, Oscl_File::SEEKCUR) == -1) 143 { 144 return 0; 145 } 146 147 // Read and convert tag flags 148 uint8 flags = 0; 149 if (read8(iInputFile, flags) == false) 150 { 151 return 0; 152 } 153 154 // Read and convert tag size 155 uint32 synchIntTagSize; 156 if (read32(iInputFile, synchIntTagSize) == false) 157 { 158 return 0; 159 } 160 161 // tagSize will store the file's Id3v2 tag size 162 uint32 tagSize = SafeSynchIntToInt32(synchIntTagSize) + ID3V2_TAG_NUM_BYTES_HEADER; 163 164 //check if footer is present 165 if ((iVersion == PV_ID3_V2_4) && (flags & FTR_FLAGMASK)) 166 tagSize += ID3V2_TAG_NUM_BYTES_HEADER; // add 10 bytes for footer 167 168 return tagSize; 169 } 170 else 171 { 172 if (CheckForTagID3V1()) 173 { 174 return ID3V1_MAX_NUM_BYTES_TOTAL; 175 } 176 } 177 return 0; 178 } 179 180 //////////////////////////////////////////////////////////////////////////// 181 OSCL_EXPORT_REF uint32 PVID3ParCom::GetID3TagSize() 182 { 183 uint32 composedTagSize = 0; 184 switch (iVersion) 185 { 186 case PV_ID3_V2_2: 187 case PV_ID3_V2_3: 188 case PV_ID3_V2_4: 189 { 190 composedTagSize = ID3V2_TAG_NUM_BYTES_HEADER + iID3TagInfo.iID3V2TagSize; 191 192 if (iID3TagInfo.iFooterPresent) 193 composedTagSize += ID3V2_TAG_NUM_BYTES_HEADER; //footer is replica of Tag Header 194 } 195 break; 196 197 case PV_ID3_V1: 198 case PV_ID3_V1_1: 199 composedTagSize = 128; // ID3v1 tag has fix size 200 break; 201 default: 202 composedTagSize = 0; 203 204 } 205 206 return composedTagSize; 207 } 208 209 //////////////////////////////////////////////////////////////////////////// 210 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::SetMaxID3TagSize(bool aUseMaxSize, uint32 aMaxSize, bool aUsePadding) 211 { 212 switch (iVersion) 213 { 214 case PV_ID3_V1: 215 case PV_ID3_V1_1: 216 case PV_ID3_INVALID_VERSION: 217 { 218 LOG_ERR((0, "PVID3Parcom::SetMaxID3TagSize: Error - Fix size ID3 tag")); 219 return PVMFErrNotSupported; 220 } 221 case PV_ID3_V2_2: 222 // Minimum for an ID3v2_2 tag is tag header plus 1 frame. The minimum data length of 223 // a frame is 1 byte 224 { 225 if (aUseMaxSize && aMaxSize < (ID3V2_TAG_NUM_BYTES_HEADER + ID3V2_2_FRAME_NUM_BYTES_HEADER + 1)) 226 { 227 LOG_ERR((0, "PVID3ParCom::SetMaxID3TagSize: Error - Minimum tag size is 17 bytes")); 228 return PVMFErrArgument; 229 } 230 } 231 break; 232 case PV_ID3_V2_3: 233 case PV_ID3_V2_4: 234 // Minimum for an ID3v2 tag is tag header plus 1 frame. The minimum data length of 235 // a frame is 1 byte 236 if (aUseMaxSize && aMaxSize < (ID3V2_TAG_NUM_BYTES_HEADER + ID3V2_FRAME_NUM_BYTES_HEADER + 1)) 237 { 238 LOG_ERR((0, "PVID3ParCom::SetMaxID3TagSize: Error - Minimum tag size is 21 bytes")); 239 return PVMFErrArgument; 240 } 241 } 242 243 iUseMaxTagSize = aUseMaxSize; 244 if (iUseMaxTagSize) 245 { 246 iMaxTagSize = aMaxSize; 247 iUsePadding = aUsePadding; 248 } 249 else 250 { 251 iMaxTagSize = 0; 252 iUsePadding = false; 253 } 254 255 return PVMFSuccess; 256 } 257 258 //////////////////////////////////////////////////////////////////////////// 259 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::ParseID3Tag(PVFile* aFile, uint32 buffsize) 260 { 261 if (!aFile) 262 { 263 return PVMFFailure; 264 } 265 266 iInputFile = aFile; 267 268 int32 currentFilePosn = 0; 269 270 // SEEK TO THE END OF THE FILE AND GET FILE SIZE 271 currentFilePosn = iInputFile->Tell(); 272 if (currentFilePosn == -1) 273 { 274 return PVMFFailure; 275 } 276 277 if (iInputFile->Seek(0, Oscl_File::SEEKSET) == -1) 278 { 279 iFileSizeInBytes = 0; 280 } 281 else 282 { 283 iInputFile->GetRemainingBytes((uint32&)iFileSizeInBytes); 284 if (iInputFile->Seek(currentFilePosn, Oscl_File::SEEKSET) == -1) 285 { 286 iInputFile = NULL; 287 return PVMFFailure; 288 } 289 } 290 291 bool readTags = false; 292 //check for ID3 Version 2 293 if (CheckForTagID3V2() || (LookForV2_4Footer(buffsize, 0) == PVMFSuccess)) 294 { 295 //Read the header 296 readTags = ReadHeaderID3V2(); 297 298 //check for ID3 Version 1 299 if (CheckForTagID3V1()) 300 { 301 iVersion = PV_ID3_V1; 302 ReadID3V1Tag(); 303 } 304 if (iInputFile->Seek(currentFilePosn, Oscl_File::SEEKSET) == -1) 305 { 306 iInputFile = NULL; 307 return PVMFFailure; 308 } 309 } 310 else if (!readTags && CheckForTagID3V1()) 311 { 312 //check for ID3 Version 1 313 iVersion = PV_ID3_V1; 314 //Read the header 315 ReadID3V1Tag(); 316 317 iByteOffsetToStartOfAudioFrames = 0; 318 if (iInputFile->Seek(currentFilePosn, Oscl_File::SEEKSET) == -1) 319 { 320 iInputFile = NULL; 321 return PVMFFailure; 322 } 323 } 324 else 325 { 326 return PVMFFailure; 327 } 328 329 iInputFile = NULL; 330 return PVMFSuccess; 331 } 332 333 //////////////////////////////////////////////////////////////////////////// 334 OSCL_EXPORT_REF PVID3Version PVID3ParCom::GetID3Version() const 335 { 336 return iVersion; 337 } 338 339 //////////////////////////////////////////////////////////////////////////// 340 OSCL_EXPORT_REF bool PVID3ParCom::IsID3V1Present() const 341 { 342 return iID3V1Present; 343 } 344 345 //////////////////////////////////////////////////////////////////////////// 346 OSCL_EXPORT_REF bool PVID3ParCom::IsID3V2Present() const 347 { 348 return iID3V2Present; 349 } 350 351 //////////////////////////////////////////////////////////////////////////// 352 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::GetID3Frames(PvmiKvpSharedPtrVector& aFrames) 353 { 354 aFrames = iFrames; 355 return PVMFSuccess; 356 } 357 358 //////////////////////////////////////////////////////////////////////////// 359 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::GetID3Frame(const OSCL_String& aFrameType, PvmiKvpSharedPtrVector& aFrameVector) 360 { 361 uint32 i; 362 for (i = 0; i < iFrames.size(); i++) 363 { 364 if (pv_mime_strcmp(iFrames[i]->key, aFrameType.get_str()) == 0) 365 { 366 return PushFrameToFrameVector(iFrames[i], aFrameVector); 367 } 368 } 369 370 return PVMFSuccess; 371 } 372 373 //////////////////////////////////////////////////////////////////////////// 374 OSCL_EXPORT_REF bool PVID3ParCom::IsID3FrameAvailable(const OSCL_String& aFrameType) 375 { 376 uint32 i; 377 for (i = 0; i < iFrames.size(); i++) 378 { 379 if (pv_mime_strcmp(iFrames[i]->key, aFrameType.get_str()) == 0) 380 { 381 return true; 382 } 383 } 384 385 return false; 386 } 387 388 //////////////////////////////////////////////////////////////////////////// 389 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::SetID3Version(PVID3Version aVersion) 390 { 391 iVersion = aVersion; 392 return PVMFSuccess; 393 } 394 395 //////////////////////////////////////////////////////////////////////////// 396 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::SetID3Frame(const PvmiKvp& aFrame) 397 { 398 uint32 i; 399 OSCL_StackString<4> frameID; 400 PVID3FrameType newFrameType; 401 PVID3FrameType existingFrameType; 402 PVMFStatus status = PVMFSuccess; 403 404 // Find an existing entry in iFrames with matching frame type 405 status = GetFrameTypeFromKvp(aFrame, frameID, newFrameType); 406 for (i = 0; status == PVMFSuccess && i < iFrames.size(); i++) 407 { 408 status = GetFrameTypeFromKvp(iFrames[i], frameID, existingFrameType); 409 if (status != PVMFSuccess) 410 { 411 LOG_ERR((0, "PVID3ParCom::SetID3Frame: Error - GetFrameTypeFromKvp failed")); 412 break; 413 } 414 if (existingFrameType == newFrameType) 415 { 416 iFrames.erase(iFrames.begin() + i); 417 break; 418 } 419 420 } 421 422 if (status != PVMFSuccess) 423 { 424 return status; 425 } 426 427 PvmiKvpValueType kvpValueType = GetValTypeFromKeyString(aFrame.key); 428 OSCL_StackString<128> key = _STRLIT_CHAR(aFrame.key); 429 uint32 valueSize = 0; 430 uint32 valueStrLen = 0; 431 switch (kvpValueType) 432 { 433 case PVMI_KVPVALTYPE_CHARPTR: 434 valueStrLen = oscl_strlen(aFrame.value.pChar_value); 435 valueSize = valueStrLen + 1; 436 break; 437 case PVMI_KVPVALTYPE_WCHARPTR: 438 valueStrLen = oscl_strlen(aFrame.value.pWChar_value); 439 valueSize = (valueStrLen + 2) * sizeof(oscl_wchar); 440 break; 441 case PVMI_KVPVALTYPE_KSV: 442 // Comment field 443 break; 444 case PVMI_KVPVALTYPE_UINT32: 445 valueSize = 0; 446 break; 447 default: 448 return PVMFErrNotSupported; 449 } 450 451 status = PVMFSuccess; 452 PvmiKvpSharedPtr kvp; 453 bool truncate = false; 454 kvp = HandleErrorForKVPAllocation(key, kvpValueType, valueSize, truncate, status); 455 456 if (truncate || (PVMFSuccess != status) || !kvp) 457 { 458 return PVMFErrNoMemory; 459 } 460 461 switch (kvpValueType) 462 { 463 case PVMI_KVPVALTYPE_CHARPTR: 464 oscl_strncpy(kvp->value.pChar_value, aFrame.value.pChar_value, valueStrLen); 465 kvp->value.pChar_value[valueStrLen] = NULL_TERM_CHAR; 466 break; 467 case PVMI_KVPVALTYPE_WCHARPTR: 468 oscl_strncpy(kvp->value.pWChar_value, aFrame.value.pWChar_value, valueStrLen); 469 kvp->value.pWChar_value[valueStrLen] = NULL_TERM_CHAR; 470 break; 471 case PVMI_KVPVALTYPE_UINT32: 472 kvp->value.uint32_value = aFrame.value.uint32_value; 473 break; 474 case PVMI_KVPVALTYPE_KSV: 475 // comment field 476 default: 477 return PVMFErrNotSupported; 478 } 479 480 481 if (PVMFSuccess != PushFrameToFrameVector(kvp, iFrames)) 482 { 483 return PVMFErrNoMemory; 484 } 485 return PVMFSuccess; 486 } 487 488 //////////////////////////////////////////////////////////////////////////// 489 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::RemoveID3Frame(const OSCL_String& aFrameType) 490 { 491 uint32 i; 492 for (i = 0; i < iFrames.size(); i++) 493 { 494 if (pv_mime_strcmp(iFrames[i]->key, aFrameType.get_str()) == 0) 495 { 496 iFrames.erase(iFrames.begin() + i); 497 return PVMFSuccess; 498 } 499 } 500 501 // Frame of specified type is not found 502 return PVMFErrArgument; 503 } 504 505 //////////////////////////////////////////////////////////////////////////// 506 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::ComposeID3Tag(OsclRefCounterMemFrag& aTag) 507 { 508 switch (iVersion) 509 { 510 case PV_ID3_V2_2: 511 case PV_ID3_V2_3: 512 case PV_ID3_V2_4: 513 return ComposeID3v2Tag(aTag); 514 default: 515 return PVMFErrNotSupported; 516 } 517 } 518 519 //////////////////////////////////////////////////////////////////////////// 520 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::Reset() 521 { 522 iFrames.clear(); 523 return PVMFSuccess; 524 } 525 526 //////////////////////////////////////////////////////////////////////////// 527 bool PVID3ParCom::CheckForTagID3V1() 528 { 529 uint8 tagHeader[ID3V1_TAG_NUM_BYTES_HEADER+1] = {0}; 530 531 // Make sure file is big enough to contain a tag 532 if (iFileSizeInBytes >= ID3V1_MAX_NUM_BYTES_TOTAL) 533 { 534 uint32 nBytes = 0; 535 // Read the value at the tag position 536 537 nBytes = iFileSizeInBytes - ID3V1_MAX_NUM_BYTES_TOTAL; 538 if (iInputFile->Seek(nBytes, Oscl_File::SEEKSET) == -1) 539 { 540 return false; 541 } 542 543 544 if (!readByteData(iInputFile, ID3V1_TAG_NUM_BYTES_HEADER, tagHeader)) 545 { 546 return false; 547 } 548 549 // Read in ID3 Tags at the front of the file. 550 if (oscl_memcmp(ID3_V1_IDENTIFIER, tagHeader, ID3V1_TAG_NUM_BYTES_HEADER) == 0) 551 { 552 iID3V1Present = true; 553 return true; 554 } 555 } 556 return false; 557 } 558 559 //////////////////////////////////////////////////////////////////////////// 560 bool PVID3ParCom::CheckForTagID3V2() 561 { 562 uint8 id3Header[ID3V2_TAG_NUM_BYTES_HEADER+1] = {0}; 563 564 if (!readByteData(iInputFile, ID3V2_TAG_NUM_BYTES_ID, id3Header)) 565 { 566 return false; 567 } 568 569 // Read in ID3 Tags at the front of the file. 570 if (oscl_memcmp(ID3_V2_IDENTIFIER, id3Header, ID3V2_TAG_NUM_BYTES_ID) == 0) 571 { 572 iTagAtBof = true; 573 iID3V2Present = true; 574 return true; 575 } 576 return false; 577 } 578 579 OSCL_EXPORT_REF bool PVID3ParCom::IsID3V2Present(PVFile* aFile, uint32& aTagSize) 580 { 581 iInputFile = aFile; 582 if (iID3V2Present) 583 { 584 // if id3 tag has already been discovered, just return the tag size 585 aTagSize = iByteOffsetToStartOfAudioFrames; 586 return true; 587 } 588 589 if (CheckForTagID3V2()) 590 { 591 // we dont want to parse the id3 frames, just read the id3 header 592 593 ReadHeaderID3V2(false); 594 aTagSize = iByteOffsetToStartOfAudioFrames; 595 return true; 596 } 597 return false; 598 } 599 600 OSCL_EXPORT_REF PVMFStatus PVID3ParCom::LookForV2_4Footer(uint32 aBuffSz, uint32 aFileOffset) 601 { 602 if (iTagAtBof) //already found tag. no need to search from the end. 603 return PVMFFailure; 604 605 uint32 footer_location = SearchTagV2_4(aBuffSz, aFileOffset); 606 607 if (footer_location == 0) 608 return PVMFFailure; 609 610 if (iInputFile->Seek(footer_location + ID3V2_TAG_NUM_BYTES_ID + ID3V2_TAG_NUM_BYTES_VERSION + ID3V2_TAG_NUM_BYTES_FLAG, 611 Oscl_File::SEEKSET) == -1) 612 { 613 return PVMFFailure; 614 } 615 616 uint32 tag_size = 0, size = 0; 617 618 if (read32(iInputFile, size) == false) 619 { 620 return PVMFFailure; 621 } 622 623 tag_size = SafeSynchIntToInt32(size); 624 625 if (iInputFile->Seek(-(int32)(tag_size + ID3V2_TAG_NUM_BYTES_HEADER + (ID3V2_TAG_NUM_BYTES_HEADER - ID3V2_TAG_NUM_BYTES_ID)), 626 Oscl_File::SEEKCUR) == -1) 627 { 628 return PVMFFailure; 629 } 630 631 return PVMFSuccess; 632 } 633 //////////////////////////////////////////////////////////////////////////// 634 // (if an error is detected, this returns 0) 635 636 uint32 PVID3ParCom::SearchTagV2_4(uint32 aBuffSz, uint32 aFileOffset) 637 { 638 639 if (iFileSizeInBytes == 0) 640 return 0; 641 642 uint8 *buff = (uint8 *)oscl_malloc(aBuffSz); 643 if (! buff) // malloc might fail 644 return 0; 645 646 int remaining_bytes = 0; 647 648 int num_bytes_read = aBuffSz + aFileOffset; 649 650 //in case we have almost reached to the begining of file, 651 //and remaining bytes are less than the buffer size, 652 //look for ID3 tag in the remaining bytes only. 653 654 if (num_bytes_read > iFileSizeInBytes) 655 remaining_bytes = iFileSizeInBytes - (num_bytes_read - aBuffSz); 656 657 if (remaining_bytes > 0) 658 { 659 660 if (iInputFile->Seek(0 , Oscl_File::SEEKSET) == -1) 661 { 662 oscl_free(buff); 663 return 0; 664 } 665 666 if (readByteData(iInputFile, remaining_bytes, buff) == false) 667 { 668 oscl_free(buff); 669 return 0; 670 } 671 672 for (int i = 0; i < remaining_bytes; i++) 673 { 674 if (oscl_memcmp(buff + i, ID3_V2_4_TAG_FOOTER, ID3V2_TAG_NUM_BYTES_ID) == 0) 675 { 676 oscl_free(buff); 677 return i; 678 } 679 680 } 681 682 oscl_free(buff); 683 return 0; 684 } 685 else 686 { 687 688 if (iInputFile->Seek((iFileSizeInBytes - (aFileOffset + aBuffSz)), Oscl_File::SEEKSET) == -1) 689 { 690 oscl_free(buff); 691 return 0; 692 } 693 694 if (readByteData(iInputFile, aBuffSz, buff) == false) 695 { 696 oscl_free(buff); 697 return 0; 698 } 699 700 for (uint i = 0; i < aBuffSz; i++) 701 { 702 if (oscl_memcmp(buff + i, ID3_V2_4_TAG_FOOTER, ID3V2_TAG_NUM_BYTES_ID) == 0) 703 { 704 oscl_free(buff); 705 return ((iFileSizeInBytes - ((aFileOffset + aBuffSz) - i))); 706 } 707 708 } 709 710 } 711 712 oscl_free(buff); 713 return 0; 714 } 715 716 //////////////////////////////////////////////////////////////////////////// 717 void PVID3ParCom::ReadID3V1Tag(void) 718 { 719 720 PVMFStatus status = PVMFSuccess; 721 bool truncate = false; 722 723 if (!iTitleFoundFlag) 724 { 725 //Title 726 status = ReadStringValueFrame(PV_ID3_FRAME_TITLE, PV_ID3_CHARSET_ISO88591, ID3V1_MAX_NUM_BYTES_TITLE); 727 if (status != PVMFSuccess) 728 { 729 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error = ReadStringValueFrame failed for title")); 730 OSCL_LEAVE(OsclErrGeneral); 731 } 732 iTitleFoundFlag = true; 733 } 734 else 735 { 736 737 if (iInputFile->Seek(ID3V1_MAX_NUM_BYTES_TITLE, Oscl_File::SEEKCUR) == -1) 738 { 739 return; 740 } 741 742 } 743 if (!iArtistFoundFlag) 744 { 745 //Artist 746 status = ReadStringValueFrame(PV_ID3_FRAME_ARTIST, PV_ID3_CHARSET_ISO88591, ID3V1_MAX_NUM_BYTES_ARTIST); 747 if (status != PVMFSuccess) 748 { 749 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error = ReadStringValueFrame failed for artist")); 750 OSCL_LEAVE(OsclErrGeneral); 751 } 752 iArtistFoundFlag = true; 753 } 754 else 755 { 756 if (iInputFile->Seek(ID3V1_MAX_NUM_BYTES_ARTIST, Oscl_File::SEEKCUR) == -1) 757 { 758 return; 759 } 760 } 761 762 if (!iAlbumFoundFlag) 763 { 764 // Album 765 status = ReadStringValueFrame(PV_ID3_FRAME_ALBUM, PV_ID3_CHARSET_ISO88591, ID3V1_MAX_NUM_BYTES_ALBUM); 766 if (status != PVMFSuccess) 767 { 768 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error = ReadStringValueFrame failed for album")); 769 OSCL_LEAVE(OsclErrGeneral); 770 } 771 iAlbumFoundFlag = true; 772 } 773 else 774 { 775 if (iInputFile->Seek(ID3V1_MAX_NUM_BYTES_ALBUM, Oscl_File::SEEKCUR) == -1) 776 { 777 return; 778 } 779 } 780 781 if (!iYearFoundFlag) 782 { 783 //Year 784 status = ReadStringValueFrame(PV_ID3_FRAME_YEAR, PV_ID3_CHARSET_ISO88591, ID3V1_MAX_NUM_BYTES_YEAR); 785 if (status != PVMFSuccess) 786 { 787 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error = ReadStringValueFrame failed for year")); 788 OSCL_LEAVE(OsclErrGeneral); 789 } 790 iYearFoundFlag = true; 791 } 792 else 793 { 794 if (iInputFile->Seek(ID3V1_MAX_NUM_BYTES_YEAR, Oscl_File::SEEKCUR) == -1) 795 { 796 return; 797 } 798 } 799 OSCL_StackString<128> keyStr; 800 PvmiKvpSharedPtr kvpPtr; 801 uint8* frameData = NULL; 802 803 if (!iCommentFoundFlag || !iTrackNumberFoundFlag) 804 { 805 frameData = NULL; 806 //Comment or Track Number 807 // Read and convert comment & track number 808 uint32 frameDataSize = ID3V1_MAX_NUM_BYTES_FIELD_SIZE + 1; 809 int32 err = OsclErrNone; 810 frameData = (uint8*) AllocateValueArray(err, PVMI_KVPVALTYPE_UINT8PTR, frameDataSize, &iAlloc); 811 if (OsclErrNone != err || !frameData) 812 { 813 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - Out of memory")); 814 OSCL_LEAVE(OsclErrNoMemory); 815 } 816 oscl_memset(frameData, 0, frameDataSize); 817 818 if (readByteData(iInputFile, ID3V1_MAX_NUM_BYTES_COMMENT, frameData) == false) 819 { 820 iAlloc.deallocate(frameData); 821 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - readByteData failed")); 822 OSCL_LEAVE(OsclErrGeneral); 823 } 824 825 826 if (frameData[ID3V1_MAX_NUM_BYTES_COMMENT-2] == 0 && 827 frameData[ID3V1_MAX_NUM_BYTES_COMMENT-1] != 0) 828 { 829 if (!iTrackNumberFoundFlag) 830 { 831 // This would mean its an ID3v1.1 tag and hence has the 832 // the track number also, so extract it 833 iVersion = PV_ID3_V1_1; 834 835 if (ConstructKvpKey(keyStr, PV_ID3_FRAME_TRACK_NUMBER, PV_ID3_CHARSET_INVALID) != PVMFSuccess) 836 { 837 iAlloc.deallocate(frameData); 838 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - ConstructKvpKey failed for tracknumber")); 839 OSCL_LEAVE(OsclErrNotSupported); 840 } 841 842 // Allocate key-value pair 843 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_UINT32, 1, truncate);); 844 if (OsclErrNone != err || !kvpPtr) 845 { 846 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - AllocateKvp failed. err=%d", err)); 847 iAlloc.deallocate(frameData); 848 OSCL_LEAVE(OsclErrNoMemory); 849 return; 850 } 851 852 if (!truncate) 853 { 854 kvpPtr->value.uint32_value = (uint32)frameData[ID3V1_MAX_NUM_BYTES_COMMENT - 1]; 855 } 856 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 857 OSCL_FIRST_CATCH_ANY(err, 858 LOG_ERR((0, "PVID3ParCom::ReadTrackLengthFrame: Error - iFrame.push_back failed")); 859 iAlloc.deallocate(frameData); 860 OSCL_LEAVE(OsclErrNoMemory); 861 return; 862 ); 863 iTrackNumberFoundFlag = true; 864 } 865 } 866 if (!iCommentFoundFlag) 867 { 868 869 // Comment frame 870 frameData[ID3V1_MAX_NUM_BYTES_COMMENT] = 0; 871 if (ConstructKvpKey(keyStr, PV_ID3_FRAME_COMMENT, PV_ID3_CHARSET_ISO88591) != PVMFSuccess) 872 { 873 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - ConstructKvpKey failed for tracknumber")); 874 iAlloc.deallocate(frameData); 875 OSCL_LEAVE(OsclErrNotSupported); 876 } 877 878 uint32 dataSize = ID3V1_MAX_NUM_BYTES_COMMENT + 1; 879 // Allocate key-value pair 880 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_CHARPTR, dataSize, truncate);); 881 if (OsclErrNone != err || !kvpPtr) 882 { 883 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - AllocateKvp failed. err=%d", err)); 884 iAlloc.deallocate(frameData); 885 OSCL_LEAVE(OsclErrNoMemory); 886 return; 887 } 888 889 if (!truncate) 890 { 891 uint32 comment_size = oscl_strlen((char*) frameData); 892 oscl_strncpy(kvpPtr->value.pChar_value, (char *)frameData, dataSize); 893 kvpPtr->value.pChar_value[comment_size] = 0; 894 kvpPtr->length = comment_size + 1; 895 } 896 897 if (PVMFSuccess != PushFrameToFrameVector(kvpPtr, iFrames)) 898 { 899 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - iFrame.push_back failed")); 900 iAlloc.deallocate(frameData); 901 return ; 902 } 903 iCommentFoundFlag = true; 904 905 } 906 iAlloc.deallocate(frameData); 907 } 908 else 909 { 910 if (iInputFile->Seek(ID3V1_MAX_NUM_BYTES_FIELD_SIZE, Oscl_File::SEEKCUR) == -1) 911 { 912 return; 913 } 914 } 915 if (!iGenereFoundFlag) 916 { 917 // Genre frame 918 uint32 frameDataSize = ID3V1_MAX_NUM_BYTES_GENRE + 1; 919 int32 err = 0; 920 frameData = (uint8*) AllocateValueArray(err, PVMI_KVPVALTYPE_UINT8PTR, frameDataSize, &iAlloc); 921 if (OsclErrNone != err || !frameData) 922 { 923 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - Out of memory")); 924 OSCL_LEAVE(OsclErrNoMemory); 925 } 926 oscl_memset(frameData, 0, frameDataSize); 927 928 if (readByteData(iInputFile, ID3V1_MAX_NUM_BYTES_GENRE, frameData) == false) 929 { 930 iAlloc.deallocate(frameData); 931 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - readByteData failed")); 932 OSCL_LEAVE(OsclErrGeneral); 933 } 934 935 if (ConstructKvpKey(keyStr, PV_ID3_FRAME_GENRE, PV_ID3_CHARSET_INVALID) != PVMFSuccess) 936 { 937 iAlloc.deallocate(frameData); 938 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - ConstructKvpKey failed for genre")); 939 OSCL_LEAVE(OsclErrNotSupported); 940 } 941 942 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_UINT32, 1, truncate);); 943 if (OsclErrNone != err || !kvpPtr) 944 { 945 iAlloc.deallocate(frameData); 946 LOG_ERR((0, "PVID3ParCom::ReadID3V1Tag: Error - AllocateKvp failed. err=%d", err)); 947 OSCL_LEAVE(OsclErrNoMemory); 948 return; 949 } 950 951 if (!truncate) 952 { 953 kvpPtr->value.uint32_value = (uint32)(frameData[ID3V1_MAX_NUM_BYTES_GENRE - 1]); 954 } 955 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 956 OSCL_FIRST_CATCH_ANY(err, 957 iAlloc.deallocate(frameData); 958 LOG_ERR((0, "PVID3ParCom::ReadTrackLengthFrame: Error - iFrame.push_back failed")); 959 OSCL_LEAVE(OsclErrNoMemory); 960 return; 961 ); 962 iAlloc.deallocate(frameData); 963 iGenereFoundFlag = true; 964 } 965 else 966 { 967 if (iInputFile->Seek(ID3V1_MAX_NUM_BYTES_GENRE, Oscl_File::SEEKCUR) == -1) 968 { 969 return; 970 } 971 } 972 } 973 974 //////////////////////////////////////////////////////////////////////////// 975 bool PVID3ParCom::ReadHeaderID3V2(bool aReadTags) 976 { 977 bool result = false; 978 979 // Read and convert tag versions, Major and Minor 980 uint8 ID3V2MajorVer, ID3V2MinorVer; 981 if (read8(iInputFile, ID3V2MajorVer) == false) 982 { 983 return false; 984 } 985 if (read8(iInputFile, ID3V2MinorVer) == false) 986 { 987 return false; 988 } 989 990 switch (ID3V2MajorVer) 991 { 992 case PV_ID3_V2_2: 993 iVersion = PV_ID3_V2_2; 994 break; 995 case PV_ID3_V2_3: 996 iVersion = PV_ID3_V2_3; 997 break; 998 case PV_ID3_V2_4: 999 iVersion = PV_ID3_V2_4; 1000 break; 1001 } 1002 1003 BEGIN_V2: 1004 // Read and convert tag flags 1005 if (read8(iInputFile, iID3TagInfo.iID3V2TagFlagsV2) == false) 1006 { 1007 return false; 1008 } 1009 1010 uint32 tagsize = 0; 1011 1012 // Read and convert tag size 1013 if (read32(iInputFile, tagsize) == false) 1014 { 1015 return false; 1016 } 1017 1018 // Now check if an extended header exists 1019 bool extHeaderFlag = false; 1020 if (iID3TagInfo.iID3V2TagFlagsV2 & EXT_FLAGMASK) 1021 { 1022 if (iVersion == PV_ID3_V2_2) 1023 { 1024 // Since no compression scheme has been decided yet, just ignore the entire tag 1025 LOG_ERR((0, "PVID3ParCom::ReadHeaderID3V2(): Error - cannot process a compressed tag")); 1026 OSCL_LEAVE(OsclErrGeneral); 1027 } 1028 1029 extHeaderFlag = true; 1030 //read extended header data 1031 if (!ReadExtendedHeader()) 1032 return false; 1033 } 1034 1035 //check if footer is present. 1036 if (iID3TagInfo.iID3V2TagFlagsV2 & FTR_FLAGMASK) 1037 { 1038 iID3TagInfo.iFooterPresent = true; 1039 } 1040 1041 // tagSize will store the file's Id3v2 tag size 1042 iID3TagInfo.iID3V2TagSize = SafeSynchIntToInt32(tagsize); 1043 1044 //calculate start of audio frame. 1045 if (iTagAtBof) 1046 { 1047 // set iByteOffsetToStartOfAudioFrames and it must account for the frame header 1048 iByteOffsetToStartOfAudioFrames = 1049 iID3TagInfo.iID3V2TagSize + ID3V2_TAG_NUM_BYTES_HEADER; 1050 1051 if (iID3TagInfo.iFooterPresent) 1052 iByteOffsetToStartOfAudioFrames += ID3V2_TAG_NUM_BYTES_HEADER; //header & footer are of same size. 1053 } 1054 else 1055 { 1056 iByteOffsetToStartOfAudioFrames = 0; 1057 } 1058 1059 // Header read is completed, now check whether we need to read the tags or not 1060 if (!aReadTags) 1061 { 1062 return false; 1063 } 1064 else 1065 { 1066 int count = ReadTagID3V2(iVersion); 1067 if (count > 0) 1068 { 1069 // we found some tags 1070 result = true; 1071 } 1072 1073 if (iSeekFrameFound) 1074 { 1075 //jump to the new tag location skipping 5 bytes of tag ID and version. 1076 uint32 seek_size = iID3TagInfo.iID3V2TagSize + ID3V2_TAG_NUM_BYTES_HEADER + (iID3TagInfo.iFooterPresent ? ID3V2_TAG_NUM_BYTES_HEADER : 0); 1077 if (iInputFile->Seek(seek_size, Oscl_File::SEEKSET) == -1) 1078 { 1079 return false; 1080 } 1081 1082 //skip 5 bytes of tag ID and version. 1083 if (iInputFile->Seek(iID3TagInfo.iID3V2SeekOffset, Oscl_File::SEEKCUR) == -1) 1084 { 1085 return false; 1086 } 1087 1088 if (!CheckForTagID3V2()) 1089 return false; 1090 1091 if (read8(iInputFile, ID3V2MajorVer) == false) 1092 { 1093 return false; 1094 } 1095 1096 if (read8(iInputFile, ID3V2MinorVer) == false) 1097 { 1098 return false; 1099 } 1100 1101 if (ID3V2MajorVer != PV_ID3_V2_4) 1102 return false; 1103 1104 //parse new tag, located at the seek offset. 1105 iSeekFrameFound = false; 1106 goto BEGIN_V2; 1107 } 1108 } 1109 return result; 1110 } 1111 1112 ///////////////////////////////////////////////////////////////////////////////// 1113 bool PVID3ParCom::ReadExtendedHeader() 1114 { 1115 1116 uint32 extsize = 0; 1117 if (read32(iInputFile, extsize) == false) 1118 { 1119 return false; 1120 } 1121 1122 // Calculate the length of the extended header. 1123 iID3TagInfo.iID3V2ExtendedHeaderSize = SafeSynchIntToInt32(extsize); 1124 1125 1126 if (iVersion == PV_ID3_V2_4) 1127 { 1128 //subtract "ext hdr size" field size from the header size. 1129 iID3TagInfo.iID3V2ExtendedHeaderSize = iID3TagInfo.iID3V2ExtendedHeaderSize - ID3V2_TAG_EXTENDED_HEADER_SIZE; 1130 1131 //check if this tag is an update of previous tag. 1132 uint8 flgsize = 0, exthdrflg = 0; 1133 // Read and ext hdr flg size tag flags 1134 if (read8(iInputFile, flgsize) == false) 1135 { 1136 return false; 1137 } 1138 if (flgsize > 0x01) //flg size should be 1 byte in V2.4 1139 return false ; 1140 // Read tag flags 1141 if (read8(iInputFile, exthdrflg) == false) 1142 { 1143 return false; 1144 } 1145 //if this tag is not an update flag, ignore any tag found before this one 1146 if (!(exthdrflg & EXTHDR_UPDMASK) && (iFrames.size() > 0)) 1147 { 1148 while (iFrames.size() > 0) 1149 iFrames.pop_back(); 1150 } 1151 1152 //subtract 2 bytes for flg size and flg from ext hdr size. 1153 iID3TagInfo.iID3V2ExtendedHeaderSize = iID3TagInfo.iID3V2ExtendedHeaderSize - 2; 1154 } 1155 1156 if (iVersion == PV_ID3_V2_3) 1157 { 1158 //V2.3 extended hdr size field does not include 6 byte size of the header 1159 iID3TagInfo.iID3V2ExtendedHeaderSize += ID3V2_TAG_EXTENDED_HEADER_TOTAL_SIZE; 1160 } 1161 1162 return true; 1163 } 1164 1165 ///////////////////////////////////////////////////////////////////////////////// 1166 int PVID3ParCom::ReadTagID3V2(PVID3Version aVersion) 1167 { 1168 PVID3FrameType frameType = PV_ID3_FRAME_EEND; 1169 uint32 i = 0; 1170 uint32 currFrameLength = 0; 1171 uint32 current_file_pos = iInputFile->Tell(); 1172 uint32 data_len_indicator_size = 0; 1173 uint32 count = 0; 1174 1175 if (iID3TagInfo.iID3V2ExtendedHeaderSize > 0) 1176 i += iID3TagInfo.iID3V2ExtendedHeaderSize ; 1177 1178 while (i <= (iID3TagInfo.iID3V2TagSize)) 1179 { 1180 // Read the frame header 1181 if (iInputFile->Seek(current_file_pos + i, Oscl_File::SEEKSET) == -1) 1182 { 1183 return count; 1184 } 1185 1186 ReadFrameHeaderID3V2(aVersion); 1187 1188 currFrameLength = iID3TagInfo.iID3V2FrameSize; 1189 frameType = FrameSupportedID3V2(aVersion); 1190 1191 if ((frameType != PV_ID3_FRAME_SEEK) && (currFrameLength > iID3TagInfo.iID3V2TagSize)) 1192 { 1193 break; 1194 } 1195 // handle the frame header 1196 1197 uint32 frame_header_size = 0; 1198 if (aVersion == PV_ID3_V2_2) 1199 frame_header_size = ID3V2_2_FRAME_NUM_BYTES_HEADER; 1200 else 1201 frame_header_size = ID3V2_FRAME_NUM_BYTES_HEADER; 1202 1203 1204 if ((currFrameLength == 0) && (frameType != PV_ID3_FRAME_EEND)) 1205 { 1206 i += frame_header_size; 1207 continue; 1208 } 1209 if (aVersion == PV_ID3_V2_3) 1210 { 1211 if (iID3TagInfo.iID3V2FrameFlag[1] & ENCR_COMP_3_FLAGMASK) 1212 frameType = PV_ID3_FRAME_UNRECOGNIZED; 1213 } 1214 else if (aVersion == PV_ID3_V2_4) 1215 { 1216 if (iID3TagInfo.iID3V2FrameFlag[1] & ENCR_COMP_4_FLAGMASK) 1217 frameType = PV_ID3_FRAME_UNRECOGNIZED; 1218 } 1219 1220 if (frameType == PV_ID3_FRAME_SEEK) 1221 { 1222 iSeekFrameFound = true; 1223 iID3TagInfo.iID3V2SeekOffset = iID3TagInfo.iID3V2FrameSize; 1224 return count; 1225 } 1226 1227 // Check if data length indicator is present 1228 if (aVersion == PV_ID3_V2_4 && (iID3TagInfo.iID3V2FrameFlag[1] & FRAME_LENGTH_INDICATOR_FLAGMASK)) 1229 { 1230 uint32 temp = 0; 1231 // Read data length indicator 1232 if (read32(iInputFile, temp) == false) 1233 { 1234 return count; 1235 } 1236 // stored as syncsafe integer 1237 currFrameLength = SafeSynchIntToInt32(temp); 1238 1239 data_len_indicator_size = ID3V2_4_DATA_LENGTH_INDICATOR_SIZE; 1240 } 1241 1242 if (((currFrameLength > 1) && (frameType != PV_ID3_FRAME_UNRECOGNIZED 1243 && frameType != PV_ID3_FRAME_INVALID 1244 && frameType != PV_ID3_FRAME_EEND 1245 && frameType != PV_ID3_FRAME_CANDIDATE))) 1246 { 1247 uint8 unicodeCheck; 1248 1249 if (read8(iInputFile, unicodeCheck) == false) 1250 { 1251 return count; 1252 } 1253 1254 if ((frameType == PV_ID3_FRAME_LYRICS) || (frameType == PV_ID3_FRAME_COMMENT)) 1255 { 1256 ReadLyricsCommFrame(unicodeCheck, currFrameLength - 1, frameType); 1257 1258 } 1259 else if ((frameType == PV_ID3_FRAME_APIC) || (frameType == PV_ID3_FRAME_PIC)) 1260 { 1261 if (currFrameLength > 3000000) 1262 { 1263 // TODO: scale down album art to something manageable right here 1264 LOG_DEBUG((0, "PVID3ParCom::ReadTagID3V2: skipping > 3MB album art")); 1265 } 1266 else 1267 { 1268 if (ReadAlbumArtFrame(frameType, unicodeCheck, currFrameLength) != PVMFSuccess) 1269 { 1270 LOG_ERR((0, "PVID3ParCom::ReadTagID3V2: Error - ReadAPICFrame failed")); 1271 return count; 1272 } 1273 } 1274 } 1275 else if (unicodeCheck < PV_ID3_CHARSET_END) 1276 { 1277 1278 if (!ReadFrameData(unicodeCheck, frameType, 1279 current_file_pos + i + frame_header_size + data_len_indicator_size + 1, 1280 currFrameLength)) 1281 { 1282 return count; 1283 } 1284 } 1285 else 1286 { 1287 // This case is when no text type is defined in the frame. 1288 HandleID3V2FrameDataASCII(frameType, i + frame_header_size + data_len_indicator_size, currFrameLength); 1289 } 1290 count++; 1291 } 1292 else 1293 { 1294 if (frameType == PV_ID3_FRAME_EEND || 1295 frameType == PV_ID3_FRAME_INVALID) 1296 { 1297 i = iID3TagInfo.iID3V2TagSize + 1; 1298 } 1299 else if (frameType == PV_ID3_FRAME_UNRECOGNIZED || 1300 frameType == PV_ID3_FRAME_CANDIDATE) // handle candidate frames as we do unsupported 1301 { 1302 if (i < iID3TagInfo.iID3V2TagSize) 1303 { 1304 HandleID3V2FrameUnsupported(frameType, 1305 current_file_pos + i, 1306 currFrameLength + frame_header_size + data_len_indicator_size); 1307 } 1308 } 1309 } 1310 1311 i += iID3TagInfo.iID3V2FrameSize + frame_header_size; 1312 } 1313 return count; 1314 } 1315 1316 bool PVID3ParCom::ValidateFrameV2_4(PVID3FrameType& frameType, bool bUseSyncSafeFrameSize) 1317 { 1318 // Initialize OUT param 1319 frameType = PV_ID3_FRAME_INVALID; 1320 1321 uint8 frameid[ID3V2_FRAME_NUM_BYTES_ID + 1] = {0}; 1322 // read frame id for next frame 1323 if (readByteData(iInputFile, ID3V2_FRAME_NUM_BYTES_ID, frameid) == false) 1324 { 1325 return false; 1326 } 1327 frameid[ID3V2_FRAME_NUM_BYTES_ID] = 0; 1328 1329 // Get frame type from frame ID 1330 frameType = FrameSupportedID3V2(PV_ID3_V2_4, frameid); 1331 if (PV_ID3_FRAME_INVALID == frameType || 1332 PV_ID3_FRAME_EEND == frameType) 1333 { 1334 return false; 1335 } 1336 else 1337 { 1338 uint32 frameSize = 0; 1339 uint8 frameflags[ID3V2_FRAME_NUM_BYTES_FLAG] = {0}; 1340 1341 // Validate frame size and flags 1342 1343 if (read32(iInputFile, frameSize) == false) 1344 { 1345 return false; 1346 } 1347 if (bUseSyncSafeFrameSize) 1348 { 1349 frameSize = SafeSynchIntToInt32(frameSize); 1350 } 1351 1352 if (readByteData(iInputFile, ID3V2_FRAME_NUM_BYTES_FLAG, frameflags) == false) 1353 { 1354 return false; 1355 } 1356 1357 if ((0 == frameSize || 1358 (frameSize + ID3V2_FRAME_NUM_BYTES_HEADER) > iID3TagInfo.iID3V2TagSize) || 1359 ((frameflags[0] & ID3V2_4_MASK_FRAME_FLAG_VERIFICATION) || 1360 (frameflags[1] & ID3V2_4_MASK_FRAME_FLAG_VERIFICATION))) 1361 { 1362 // validation for frame size or flags failed 1363 return false; 1364 } 1365 else 1366 { 1367 return true; 1368 } 1369 } 1370 } 1371 1372 uint32 PVID3ParCom::ValidateFrameLengthV2_4(uint32 aFrameSize) 1373 { 1374 int32 currFilePos = iInputFile->Tell(); 1375 int32 errCode = -1; 1376 int32 actualFrameLen = 0; 1377 1378 // we have already read the complete current frame header 1379 1380 do 1381 { 1382 // Assuming syncsafe frame size 1383 actualFrameLen = SafeSynchIntToInt32(aFrameSize); 1384 1385 // 1386 /* validate frame using syncsafe size */ 1387 // 1388 1389 // Seek to next frame boundary with syncsafe size 1390 errCode = iInputFile->Seek(actualFrameLen, Oscl_File::SEEKCUR); 1391 if (-1 == errCode) 1392 { 1393 // proceed with default syncsafe handling 1394 break; 1395 } 1396 1397 bool bIsSyncSafeFrameValid = false; 1398 PVID3FrameType frameTypeUsingSyncSafeSize = PV_ID3_FRAME_INVALID; 1399 // Get the validation status and frame type 1400 bIsSyncSafeFrameValid = ValidateFrameV2_4(frameTypeUsingSyncSafeSize); 1401 1402 // 1403 /* validate frame using non-syncsafe size */ 1404 // 1405 1406 // FrameSize is not even stored as non-syncsafe 1407 if ((aFrameSize + ID3V2_FRAME_NUM_BYTES_HEADER) > iID3TagInfo.iID3V2TagSize) 1408 { 1409 // proceed with syncsafe, as non-syncsafe length not valid 1410 break; 1411 } 1412 1413 // Seek back 1414 errCode = iInputFile->Seek(currFilePos, Oscl_File::SEEKSET); 1415 if (-1 == errCode) 1416 { 1417 LOG_ERR((0, "PVID3ParCom::ValidateFrameLengthV2_4: Error - iInputFile->Seek failed")); 1418 OSCL_LEAVE(OsclErrGeneral); 1419 } 1420 // Seek to next frame boundary with non-syncsafe size 1421 errCode = iInputFile->Seek(aFrameSize, Oscl_File::SEEKCUR); 1422 if (-1 == errCode) 1423 { 1424 // proceed with default syncsafe handling 1425 break; 1426 } 1427 1428 bool bIsNonSyncSafeFrameValid = false; 1429 PVID3FrameType frameTypeUsingNonSyncSafeSize = PV_ID3_FRAME_INVALID; 1430 // Get the validation status and frame type 1431 bIsNonSyncSafeFrameValid = ValidateFrameV2_4(frameTypeUsingNonSyncSafeSize, false); 1432 1433 // - Give more priority to non-syncsafe VALID frame ID, 1434 // than syncsafe candidate frame ID (frame validation is true for both) 1435 // - In case, we have frame validation true for both syncsafe and non-syncsafe size, 1436 // we will use default syncsafe representation 1437 // - In case, we have frame validation false for both syncsafe and non-syncsafe size, 1438 // we will use default syncsafe representation 1439 if (bIsSyncSafeFrameValid && frameTypeUsingSyncSafeSize != PV_ID3_FRAME_CANDIDATE) 1440 { 1441 // syncsafe representation 1442 } 1443 else if (bIsNonSyncSafeFrameValid && frameTypeUsingNonSyncSafeSize != PV_ID3_FRAME_CANDIDATE) 1444 { 1445 // non-syncsafe representation 1446 actualFrameLen = aFrameSize; 1447 } 1448 else if (!bIsSyncSafeFrameValid && bIsNonSyncSafeFrameValid) 1449 { 1450 // non-syncsafe representation 1451 actualFrameLen = aFrameSize; 1452 } 1453 else 1454 { 1455 // consider rest all syncsafe representation 1456 } 1457 1458 } 1459 while (false); 1460 1461 // Seek back 1462 errCode = iInputFile->Seek(currFilePos, Oscl_File::SEEKSET); 1463 if (-1 == errCode) 1464 { 1465 LOG_ERR((0, "PVID3ParCom::ValidateFrameLengthV2_4: Error - iInputFile->Seek failed")); 1466 OSCL_LEAVE(OsclErrGeneral); 1467 } 1468 1469 return actualFrameLen; 1470 } 1471 1472 ////////////////////////////////////////////////////////////////////////// 1473 bool PVID3ParCom::ReadFrameData(uint8 unicodeCheck, PVID3FrameType frameType, uint32 pos, uint32 currFrameLength) 1474 { 1475 if (unicodeCheck == PV_ID3_CHARSET_ISO88591) 1476 { 1477 // This frame contains normal ASCII text strings. (ISO-8859-1) 1478 iID3TagInfo.iTextType = PV_ID3_CHARSET_ISO88591; 1479 HandleID3V2FrameDataASCII(frameType, pos, currFrameLength - 1); 1480 } 1481 else if (unicodeCheck == PV_ID3_CHARSET_UTF16) 1482 { 1483 uint16 endianCheck; 1484 1485 if (read16(iInputFile, endianCheck) == false) 1486 { 1487 return false; 1488 } 1489 1490 // This frame's text strings are Unicode and the frame 1491 // does include a BOM value. (UTF-16) 1492 iID3TagInfo.iTextType = PV_ID3_CHARSET_UTF16; 1493 uint32 endianType; 1494 if (endianCheck == UNICODE_LITTLE_ENDIAN_INDICATOR_FULL) 1495 { 1496 endianType = UNICODE_LITTLE_ENDIAN; 1497 } 1498 else if (endianCheck == UNICODE_BIG_ENDIAN_INDICATOR_FULL) 1499 { 1500 endianType = UNICODE_BIG_ENDIAN; 1501 } 1502 else 1503 { 1504 return false; 1505 } 1506 1507 // value of 2 is for BOM Character 1508 HandleID3V2FrameDataUnicode16(frameType, pos + 2, currFrameLength - 3, endianType); 1509 } 1510 else if (unicodeCheck == PV_ID3_CHARSET_UTF16BE) 1511 { 1512 // This frame's text strings are Unicode but the frame 1513 // does not contain a BOM(byte order mark) (UTF-16BE) 1514 iID3TagInfo.iTextType = PV_ID3_CHARSET_UTF16BE; 1515 // Default ID3V2 endian type to Big Endian 1516 uint32 endianType = UNICODE_BIG_ENDIAN; 1517 // Big Endian is assumed since the frame did not specify the endian type. 1518 HandleID3V2FrameDataUnicode16(frameType, pos, currFrameLength - 1, endianType); 1519 } 1520 else if (unicodeCheck == PV_ID3_CHARSET_UTF8) 1521 { 1522 // This frame's text strings are Unicode (UTF-8) 1523 iID3TagInfo.iTextType = PV_ID3_CHARSET_UTF8; 1524 HandleID3V2FrameDataUTF8(frameType, pos, currFrameLength - 1); 1525 } 1526 return true; 1527 } 1528 1529 //////////////////////////////////////////////////////////////////////////// 1530 void PVID3ParCom::ReadFrameHeaderID3V2(PVID3Version aVersion) 1531 { 1532 if (aVersion == PV_ID3_V2_2) 1533 { 1534 ReadFrameHeaderID3V2_2(); 1535 } 1536 else 1537 { 1538 // Read frame ID 1539 if (readByteData(iInputFile, ID3V2_FRAME_NUM_BYTES_ID, iID3TagInfo.iID3V2FrameID) == false) 1540 { 1541 return; 1542 } 1543 iID3TagInfo.iID3V2FrameID[ID3V2_FRAME_NUM_BYTES_ID] = 0; 1544 // Read frame size 1545 if (read32(iInputFile, iID3TagInfo.iID3V2FrameSize) == false) 1546 { 1547 return; 1548 } 1549 // Read frame flag 1550 if (readByteData(iInputFile, ID3V2_FRAME_NUM_BYTES_FLAG, iID3TagInfo.iID3V2FrameFlag) == false) 1551 { 1552 return; 1553 } 1554 1555 if (PV_ID3_V2_4 == aVersion) 1556 { 1557 if (iID3TagInfo.iID3V2FrameSize > MAX_SYNCSAFE_LEN) 1558 { 1559 // Verify whether frame length is SyncSafe or Non-SyncSafe 1560 iID3TagInfo.iID3V2FrameSize = ValidateFrameLengthV2_4(iID3TagInfo.iID3V2FrameSize); 1561 } 1562 } 1563 } 1564 return; 1565 } 1566 1567 //////////////////////////////////////////////////////////////////////////// 1568 void PVID3ParCom::ReadFrameHeaderID3V2_2() 1569 { 1570 if (readByteData(iInputFile, ID3V2_2_FRAME_NUM_BYTES_ID, iID3TagInfo.iID3V2FrameID) == false) 1571 { 1572 return; 1573 } 1574 iID3TagInfo.iID3V2FrameID[ID3V2_2_FRAME_NUM_BYTES_ID] = 0; 1575 if (read24(iInputFile, iID3TagInfo.iID3V2FrameSize) == false) 1576 { 1577 return; 1578 } 1579 1580 return; 1581 } 1582 1583 ////////////////////////////////////////////////////////////////////////////// 1584 void PVID3ParCom::HandleID3V2FrameDataASCII(PVID3FrameType aFrameType, 1585 uint32 aPos, 1586 uint32 aSize) 1587 { 1588 OSCL_StackString<128> keyStr; 1589 PvmiKvpSharedPtr kvpPtr; 1590 PVMFStatus status = PVMFSuccess; 1591 if (iInputFile->Seek(aPos, Oscl_File::SEEKSET) == -1) 1592 { 1593 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataASCII: Error - iInputFile->Seek failed")); 1594 OSCL_LEAVE(OsclErrGeneral); 1595 } 1596 1597 switch (aFrameType) 1598 { 1599 case PV_ID3_FRAME_TRACK_LENGTH: 1600 status = ReadTrackLengthFrame(aSize, PV_ID3_CHARSET_ISO88591); 1601 if (status != PVMFSuccess) 1602 { 1603 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataASCII: Error - ReadTrackLengthFrame failed. status=%d", status)); 1604 OSCL_LEAVE(OsclErrGeneral); 1605 } 1606 break; 1607 case PV_ID3_FRAME_TITLE: 1608 case PV_ID3_FRAME_ARTIST: 1609 case PV_ID3_FRAME_ALBUM: 1610 case PV_ID3_FRAME_YEAR: 1611 case PV_ID3_FRAME_TRACK_NUMBER: 1612 case PV_ID3_FRAME_GENRE: 1613 case PV_ID3_FRAME_COPYRIGHT: 1614 case PV_ID3_FRAME_DATE: 1615 case PV_ID3_FRAME_RECORDING_TIME: 1616 //new frames support 1617 case PV_ID3_FRAME_AUTHOR: 1618 case PV_ID3_FRAME_COMPOSER: 1619 case PV_ID3_FRAME_DESCRIPTION: 1620 case PV_ID3_FRAME_VERSION: 1621 case PV_ID3_FRAME_PART_OF_SET: 1622 1623 status = ReadStringValueFrame(aFrameType, PV_ID3_CHARSET_ISO88591, aSize); 1624 if (status != PVMFSuccess) 1625 { 1626 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataASCII: Error - ReadStringValueFrame failed. status=%d", status)); 1627 OSCL_LEAVE(OsclErrGeneral); 1628 } 1629 if (aFrameType == PV_ID3_FRAME_TITLE) 1630 iTitleFoundFlag = true; 1631 if (aFrameType == PV_ID3_FRAME_ARTIST) 1632 iArtistFoundFlag = true; 1633 if (aFrameType == PV_ID3_FRAME_ALBUM) 1634 iAlbumFoundFlag = true; 1635 if (aFrameType == PV_ID3_FRAME_YEAR) 1636 iYearFoundFlag = true; 1637 if (aFrameType == PV_ID3_FRAME_TRACK_NUMBER) 1638 iTrackNumberFoundFlag = true; 1639 if (aFrameType == PV_ID3_FRAME_GENRE) 1640 iGenereFoundFlag = true; 1641 1642 break; 1643 1644 default: 1645 break; 1646 } 1647 } 1648 1649 void PVID3ParCom::HandleID3V2FrameUnsupported(PVID3FrameType aFrameType, 1650 uint32 aPos, 1651 uint32 aSize) 1652 { 1653 // In Android, don't try to read unsupported metadata, because a) we don't 1654 // know what to do with it anyway, and b) we end up here for corrupted files 1655 // too, in which case the size is likely bogus and will result in running 1656 // out of RAM. 1657 #ifndef ANDROID 1658 OSCL_StackString<128> keyStr; 1659 PvmiKvpSharedPtr kvpPtr; 1660 PVMFStatus status = PVMFSuccess; 1661 if (iInputFile->Seek(aPos, Oscl_File::SEEKSET) == -1) 1662 { 1663 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataASCII: Error - iInputFile->Seek failed")); 1664 OSCL_LEAVE(OsclErrGeneral); 1665 } 1666 1667 status = ReadFrame(aFrameType, aSize); 1668 if (status != PVMFSuccess) 1669 { 1670 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataASCII: Error - ReadStringValueFrame failed. status=%d", status)); 1671 OSCL_LEAVE(OsclErrGeneral); 1672 } 1673 #endif 1674 } 1675 1676 //////////////////////////////////////////////////////////////////////////// 1677 void PVID3ParCom::HandleID3V2FrameDataUnicode16(PVID3FrameType aFrameType, 1678 uint32 aPos, 1679 uint32 aSize, 1680 uint32 aEndianType) 1681 { 1682 // seek to the beginning of the current frame data 1683 if (iInputFile->Seek(aPos, Oscl_File::SEEKSET) == -1) 1684 { 1685 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataUnicode16: Error - iInputFile->Seek failed")); 1686 OSCL_LEAVE(OsclErrGeneral); 1687 return; 1688 } 1689 1690 PVMFStatus status = PVMFSuccess; 1691 PVID3CharacterSet charSet; 1692 if (aEndianType == UNICODE_BIG_ENDIAN) 1693 charSet = PV_ID3_CHARSET_UTF16BE; 1694 else 1695 charSet = PV_ID3_CHARSET_UTF16; 1696 1697 switch (aFrameType) 1698 { 1699 1700 case PV_ID3_FRAME_TRACK_LENGTH: 1701 //is a numeric string and does not depend on text encoding. 1702 status = ReadTrackLengthFrame(aSize, charSet); 1703 if (status != PVMFSuccess) 1704 { 1705 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataUnicode16: Error - ReadTrackLengthFrame failed. status=%d", status)); 1706 OSCL_LEAVE(OsclErrGeneral); 1707 return; 1708 } 1709 break; 1710 case PV_ID3_FRAME_TITLE: 1711 case PV_ID3_FRAME_ARTIST: 1712 case PV_ID3_FRAME_ALBUM: 1713 case PV_ID3_FRAME_YEAR: 1714 case PV_ID3_FRAME_TRACK_NUMBER: 1715 case PV_ID3_FRAME_GENRE: 1716 case PV_ID3_FRAME_COPYRIGHT: 1717 case PV_ID3_FRAME_DATE: 1718 case PV_ID3_FRAME_RECORDING_TIME: 1719 //new frames support 1720 case PV_ID3_FRAME_AUTHOR: 1721 case PV_ID3_FRAME_COMPOSER: 1722 case PV_ID3_FRAME_DESCRIPTION: 1723 case PV_ID3_FRAME_VERSION: 1724 case PV_ID3_FRAME_PART_OF_SET: 1725 1726 status = ReadStringValueFrame(aFrameType, charSet, aSize); 1727 if (status != PVMFSuccess) 1728 { 1729 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataUnicode16: Error - ReadStringValueFrame failed. status=%d", status)); 1730 OSCL_LEAVE(OsclErrGeneral); 1731 return; 1732 } 1733 if (aFrameType == PV_ID3_FRAME_TITLE) 1734 iTitleFoundFlag = true; 1735 if (aFrameType == PV_ID3_FRAME_ARTIST) 1736 iArtistFoundFlag = true; 1737 if (aFrameType == PV_ID3_FRAME_ALBUM) 1738 iAlbumFoundFlag = true; 1739 if (aFrameType == PV_ID3_FRAME_YEAR) 1740 iYearFoundFlag = true; 1741 if (aFrameType == PV_ID3_FRAME_TRACK_NUMBER) 1742 iTrackNumberFoundFlag = true; 1743 if (aFrameType == PV_ID3_FRAME_GENRE) 1744 iGenereFoundFlag = true; 1745 1746 break; 1747 1748 default: 1749 break; 1750 } 1751 } 1752 1753 //////////////////////////////////////////////////////////////////////////// 1754 void PVID3ParCom::HandleID3V2FrameDataUTF8(PVID3FrameType aFrameType, 1755 uint32 aPos, 1756 uint32 aSize) 1757 { 1758 if (iInputFile->Seek(aPos, Oscl_File::SEEKSET) == -1) 1759 { 1760 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataUTF8: Error - iInputFile->Seek failed")); 1761 OSCL_LEAVE(OsclErrGeneral); 1762 } 1763 1764 PVMFStatus status = PVMFSuccess; 1765 switch (aFrameType) 1766 { 1767 1768 case PV_ID3_FRAME_TRACK_LENGTH: 1769 status = ReadTrackLengthFrame(aSize, PV_ID3_CHARSET_UTF8); 1770 if (status != PVMFSuccess) 1771 { 1772 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataUTF8: Error - ReadTrackLengthFrame failed. status=%d", status)); 1773 OSCL_LEAVE(OsclErrGeneral); 1774 } 1775 break; 1776 1777 case PV_ID3_FRAME_TITLE: 1778 case PV_ID3_FRAME_ARTIST: 1779 case PV_ID3_FRAME_ALBUM: 1780 case PV_ID3_FRAME_YEAR: 1781 case PV_ID3_FRAME_TRACK_NUMBER: 1782 case PV_ID3_FRAME_GENRE: 1783 case PV_ID3_FRAME_COPYRIGHT: 1784 case PV_ID3_FRAME_DATE: 1785 case PV_ID3_FRAME_RECORDING_TIME: 1786 //new frames support 1787 case PV_ID3_FRAME_AUTHOR: 1788 case PV_ID3_FRAME_COMPOSER: 1789 case PV_ID3_FRAME_DESCRIPTION: 1790 case PV_ID3_FRAME_VERSION: 1791 case PV_ID3_FRAME_PART_OF_SET: 1792 1793 status = ReadStringValueFrame(aFrameType, PV_ID3_CHARSET_UTF8, aSize); 1794 if (status != PVMFSuccess) 1795 { 1796 LOG_ERR((0, "PVID3ParCom::HandleID3V2FrameDataUTF8: Error - ReadStringValueFrame failed. status=%d", status)); 1797 OSCL_LEAVE(OsclErrGeneral); 1798 } 1799 if (aFrameType == PV_ID3_FRAME_TITLE) 1800 iTitleFoundFlag = true; 1801 if (aFrameType == PV_ID3_FRAME_ARTIST) 1802 iArtistFoundFlag = true; 1803 if (aFrameType == PV_ID3_FRAME_ALBUM) 1804 iAlbumFoundFlag = true; 1805 if (aFrameType == PV_ID3_FRAME_YEAR) 1806 iYearFoundFlag = true; 1807 if (aFrameType == PV_ID3_FRAME_TRACK_NUMBER) 1808 iTrackNumberFoundFlag = true; 1809 if (aFrameType == PV_ID3_FRAME_GENRE) 1810 iGenereFoundFlag = true; 1811 1812 break; 1813 1814 default: 1815 break; 1816 } 1817 } 1818 1819 //---------------------------------------------------------------------------- 1820 // FUNCTION NAME: PVID3ParCom::FrameSupportedID3V2(PVID3Version) 1821 //---------------------------------------------------------------------------- 1822 // INPUT AND OUTPUT DEFINITIONS 1823 // 1824 // Inputs: None 1825 // 1826 // Outputs: None 1827 // 1828 // Returns: 1829 // ID3V2FrameTypeReturnValue - The value that describes the current frame. 1830 // of type enum TID3V2FrameType 1831 // 1832 // Global Variables Used: 1833 // TID3V2FrameType - The enum table containing the supported frame types 1834 // 1835 //---------------------------------------------------------------------------- 1836 // FUNCTION DESCRIPTION 1837 // 1838 // This function detects the ID3V2FrameType and returns the enum value that 1839 // corresponds to the current frame. 1840 // 1841 //------------------------------------------------------------------------------ 1842 1843 PVID3ParCom::PVID3FrameType PVID3ParCom::FrameSupportedID3V2(PVID3Version aVersion, uint8* aframeid) 1844 { 1845 PVID3FrameType ID3V2FrameTypeReturnValue; 1846 uint8* pFrameID = (aframeid) ? aframeid : iID3TagInfo.iID3V2FrameID; 1847 1848 if (0xff == pFrameID[0]) 1849 { 1850 //possibly start of mp3 frame. Stop further parsing. 1851 return PV_ID3_FRAME_EEND; 1852 } 1853 1854 if (aVersion == PV_ID3_V2_2) 1855 { 1856 ID3V2FrameTypeReturnValue = FrameSupportedID3V2_2(); 1857 } 1858 else //for v2.3 & v2.4 1859 { 1860 uint8 endTestBuf[ID3V2_FRAME_NUM_BYTES_ID] = {0}; 1861 1862 if (oscl_memcmp(pFrameID, ID3_FRAME_ID_TITLE, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1863 { 1864 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_TITLE; 1865 iTitleFoundFlag = true; 1866 } 1867 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_ARTIST, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1868 { 1869 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_ARTIST; 1870 iArtistFoundFlag = true; 1871 } 1872 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_PART_OF_SET, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1873 { 1874 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_PART_OF_SET; 1875 } 1876 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_ALBUM, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1877 { 1878 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_ALBUM; 1879 iAlbumFoundFlag = true; 1880 } 1881 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_COPYRIGHT, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1882 { 1883 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_COPYRIGHT; 1884 } 1885 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_GENRE, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1886 { 1887 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_GENRE; 1888 iGenereFoundFlag = true; 1889 } 1890 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_TRACK_NUMBER, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1891 { 1892 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_TRACK_NUMBER; 1893 iTrackNumberFoundFlag = true; 1894 } 1895 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_TRACK_LENGTH, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1896 { 1897 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_TRACK_LENGTH; 1898 } 1899 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_COMMENT, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1900 { 1901 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_COMMENT; 1902 iCommentFoundFlag = true; 1903 } 1904 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_YEAR, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1905 { 1906 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_YEAR; 1907 iYearFoundFlag = true; 1908 } 1909 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_RECORDING_TIME, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1910 { 1911 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_RECORDING_TIME; 1912 iYearFoundFlag = true; 1913 } 1914 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_DATE, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1915 { 1916 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_DATE; 1917 } 1918 1919 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_ALBUMART, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1920 { 1921 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_APIC; 1922 } 1923 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_LYRICIST, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1924 { 1925 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_LYRICS; 1926 } 1927 1928 // For the seek frame. 1929 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_SEEK, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1930 { 1931 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_SEEK; 1932 } 1933 //new frames support 1934 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_AUTHOR, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1935 { 1936 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_AUTHOR; 1937 } 1938 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_COMPOSER, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1939 { 1940 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_COMPOSER; 1941 } 1942 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_DESCRIPTION, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1943 { 1944 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_DESCRIPTION; 1945 } 1946 else if (oscl_memcmp(pFrameID, ID3_FRAME_ID_VERSION, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1947 { 1948 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_VERSION; 1949 } 1950 else if (oscl_memcmp(pFrameID, endTestBuf, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1951 { 1952 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_EEND; 1953 } 1954 else if (oscl_memcmp(pFrameID, endTestBuf, ID3V2_FRAME_NUM_BYTES_ID) == 0) 1955 { 1956 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_EEND; 1957 } 1958 else 1959 { 1960 // Find whether frame is invalid or unsupported 1961 ID3V2FrameTypeReturnValue = FrameValidatedID3V2_4(pFrameID); 1962 } 1963 } 1964 return ID3V2FrameTypeReturnValue; 1965 } 1966 1967 //---------------------------------------------------------------------------- 1968 // FUNCTION NAME: PVID3ParCom::FrameSupportedID3V2_2(void) 1969 //---------------------------------------------------------------------------- 1970 // INPUT AND OUTPUT DEFINITIONS 1971 // 1972 // Inputs: None 1973 // 1974 // Outputs: None 1975 // 1976 // Returns: 1977 // ID3V2_2FrameTypeReturnValue - The value that describes the current frame. 1978 // of type enum TID3V2FrameType 1979 // 1980 // Global Variables Used: 1981 // TID3V2_2FrameType - The enum table containing the supported frame types 1982 // 1983 //---------------------------------------------------------------------------- 1984 // FUNCTION DESCRIPTION 1985 // 1986 // This function detects the ID3V2_2FrameType and returns the enum value that 1987 // corresponds to the current frame. 1988 // 1989 //------------------------------------------------------------------------------ 1990 1991 PVID3ParCom::PVID3FrameType PVID3ParCom::FrameSupportedID3V2_2(void) 1992 { 1993 uint8 endTestBuf[ID3V2_2_FRAME_NUM_BYTES_ID] = {0}; 1994 PVID3FrameType ID3V2_2FrameTypeReturnValue; 1995 1996 if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_TITLE, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 1997 { 1998 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_TITLE; 1999 iTitleFoundFlag = true; 2000 } 2001 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_ARTIST, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2002 { 2003 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_ARTIST; 2004 iArtistFoundFlag = true; 2005 } 2006 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_PART_OF_SET, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2007 { 2008 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_PART_OF_SET; 2009 } 2010 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_ALBUM, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2011 { 2012 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_ALBUM; 2013 iAlbumFoundFlag = true; 2014 } 2015 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_COPYRIGHT, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2016 { 2017 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_COPYRIGHT; 2018 } 2019 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_GENRE, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2020 { 2021 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_GENRE; 2022 iGenereFoundFlag = true; 2023 } 2024 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_TRACK_NUMBER, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2025 { 2026 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_TRACK_NUMBER; 2027 iTrackNumberFoundFlag = true; 2028 } 2029 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_TRACK_LENGTH, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2030 { 2031 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_TRACK_LENGTH; 2032 } 2033 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_COMMENT, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2034 { 2035 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_COMMENT; 2036 iCommentFoundFlag = true; 2037 } 2038 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_YEAR, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2039 { 2040 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_YEAR; 2041 iYearFoundFlag = true; 2042 } 2043 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_DATE, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2044 { 2045 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_DATE; 2046 } 2047 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_ALBUMART, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2048 { 2049 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_PIC; 2050 } 2051 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_LYRICIST, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2052 { 2053 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_LYRICS; 2054 } 2055 //new frames support 2056 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_AUTHOR, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2057 { 2058 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_AUTHOR; 2059 } 2060 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_COMPOSER, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2061 { 2062 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_COMPOSER; 2063 } 2064 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_DESCRIPTION, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2065 { 2066 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_DESCRIPTION; 2067 } 2068 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, ID3V2_2_FRAME_ID_VERSION, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2069 { 2070 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_VERSION; 2071 } 2072 2073 else if (oscl_memcmp(iID3TagInfo.iID3V2FrameID, endTestBuf, ID3V2_2_FRAME_NUM_BYTES_ID) == 0) 2074 { 2075 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_EEND; 2076 } 2077 2078 else 2079 { 2080 ID3V2_2FrameTypeReturnValue = PV_ID3_FRAME_UNRECOGNIZED; 2081 } 2082 2083 return ID3V2_2FrameTypeReturnValue; 2084 } 2085 2086 //---------------------------------------------------------------------------- 2087 // FUNCTION NAME: PVID3ParCom::EightBitToWideCharBufferTransfer( 2088 // const TPtr8& aPtrFrameData8, 2089 // uint32 aSize, 2090 // uint32 aEndianType, 2091 // TPtr16& aPtrFrameData16) 2092 //---------------------------------------------------------------------------- 2093 // INPUT AND OUTPUT DEFINITIONS 2094 // 2095 // Inputs: 2096 // aPtrFrameData8 - pointer to intput string format of either big 2097 // or little endian. 2098 // aSize - number of character elements in aPtrFrameData8 2099 // aEndianType - This describes if the encoded Unicode text in the 2100 // aPtrFrameData8 buffer is in big or little endian. 2101 // Outputs: 2102 // aPtrFrameDataWCBase - pointer to the output string in unicode format. 2103 // 2104 // Returns: size of data in aPtrFrameDataWCBase 2105 // 2106 // Global Variables Used: None 2107 // 2108 //---------------------------------------------------------------------------- 2109 // FUNCTION DESCRIPTION 2110 // 2111 // This function moves unicode data sotred in uint8 buffer to wchar buffer. 2112 // The endian is taken care of by this function as well. 2113 // 2114 //------------------------------------------------------------------------------ 2115 uint32 PVID3ParCom::EightBitToWideCharBufferTransfer(const uint8 * aPtrFrameData8, 2116 uint32 aSize, 2117 uint32 aEndianType, 2118 oscl_wchar * aPtrFrameDataWCBase) 2119 { 2120 if (aPtrFrameData8 == NULL || aPtrFrameDataWCBase == NULL) 2121 { 2122 return 0; 2123 } 2124 2125 oscl_wchar * aPtrFrameDataWC = aPtrFrameDataWCBase; 2126 uint16 tempFrameData16; 2127 oscl_wchar tempFrameDataWC = 0; 2128 uint32 index = 0; 2129 uint32 z = 0, x = 0; 2130 uint8 tempByteOne, tempByteTwo; 2131 if (aEndianType != UNICODE_BIG_ENDIAN) 2132 // Indication check of big-endian vs. little endian 2133 { 2134 z = 0; 2135 for (x = 0; x < (aSize >> 1); x++) 2136 { 2137 z = x << 1; 2138 tempByteOne = aPtrFrameData8[z]; 2139 tempByteTwo = aPtrFrameData8[z + 1]; 2140 if ((tempByteOne == 0) && (tempByteTwo == 0)) 2141 { 2142 x++; 2143 // End of string here and skip to start of next string. 2144 aPtrFrameDataWC[index++] = ((oscl_wchar)'\0'); 2145 } 2146 else 2147 { 2148 tempFrameData16 = (uint16)((((uint16)(tempByteTwo << 8)) | tempByteOne)); 2149 tempFrameDataWC = tempFrameData16; 2150 aPtrFrameDataWC[index++] = tempFrameDataWC; 2151 } 2152 } 2153 } 2154 else 2155 { 2156 z = 0; 2157 for (x = 0; x < (aSize >> 1); x++) 2158 { 2159 z = x << 1; 2160 tempByteOne = aPtrFrameData8[z]; 2161 tempByteTwo = aPtrFrameData8[z + 1]; 2162 if ((tempByteTwo == 0) && (tempByteOne == 0)) 2163 { 2164 x++; 2165 // End of string here and skip to start of next string. 2166 aPtrFrameDataWC[index++] = ((oscl_wchar)'\0'); 2167 } 2168 else 2169 { 2170 tempFrameData16 = (uint16)((((uint16)(tempByteOne << 8)) | tempByteTwo)); 2171 int32 l = sizeof(oscl_wchar); 2172 if (l == 4) 2173 tempFrameDataWC = (tempFrameData16 << 16) && 0xff00; 2174 else if (l == 2) 2175 tempFrameDataWC = tempFrameData16; 2176 else 2177 return 0; 2178 aPtrFrameDataWC[index++] = tempFrameDataWC; 2179 } 2180 } 2181 } 2182 return (index); 2183 } 2184 2185 uint32 PVID3ParCom::ConvertToSyncSafeInt(uint32 src) 2186 { 2187 uint32 dest = (src & 0x0FE00000) << 3; 2188 dest |= (src & 0x001FC000) << 2; 2189 dest |= (src & 0x00003f80) << 1; 2190 dest |= (src & 0x0000007f); 2191 2192 return dest; 2193 } 2194 2195 //////////////////////////////////////////////////////////////////////////// 2196 uint32 PVID3ParCom::SafeSynchIntToInt32(uint32 aSafeSynchInteger) 2197 { 2198 uint8 * pBuf = (uint8 *) & (aSafeSynchInteger); 2199 uint8 tmpByte = 0; 2200 int32 i = 0; 2201 uint32 integer = 0; 2202 2203 // This loop will calculate the correct size from the bytes designated for size 2204 // It is stored as a SynchSafe Integer. This means the 8th bit is reserved in 2205 // each byte and not used for integer precision.. The number is effectively 28 2206 // bits in length/precision. 2207 // Assumes: sizeof(uint32) = 4 Bytes 2208 for (i = 0; i < 4; i++) 2209 { 2210 #if (OSCL_BYTE_ORDER_LITTLE_ENDIAN) 2211 tmpByte = (uint8)(pBuf[i] & MASK127); 2212 #elif (OSCL_BYTE_ORDER_BIG_ENDIAN) 2213 tmpByte = pBuf[4-i-1] & MASK127; 2214 #else 2215 #error "Must Specify ENDIANNESS" 2216 #endif 2217 // now shift the data to it's correct place 2218 integer += tmpByte << VALID_BITS_IN_SYNC_SAFE_BYTE * i; 2219 } 2220 2221 return integer; 2222 } 2223 2224 //////////////////////////////////////////////////////////////////////////// 2225 bool PVID3ParCom::readByteData(PVFile* aInputFile, uint32 length, uint8 *aData) 2226 { 2227 if (length > 0) 2228 { 2229 uint32 bytesRead; 2230 bytesRead = aInputFile->Read(aData, 1, length); 2231 2232 if (bytesRead < (uint32)length) // read byte data failed 2233 { 2234 return false; 2235 } 2236 } 2237 return true; 2238 } 2239 2240 //////////////////////////////////////////////////////////////////////////// 2241 bool PVID3ParCom::read32(PVFile* aInputFile, uint32 &aData) 2242 { 2243 const int32 N = 4; 2244 uint8 bytes[N]; 2245 aData = 0; 2246 2247 int32 retVal = (int32)(aInputFile->Read((void*)bytes, 1, N)); 2248 2249 if (retVal < N) 2250 return false; 2251 2252 for (int32 i = 0; i < N; i++) 2253 aData = (aData << 8) | bytes[i]; 2254 2255 return true; 2256 } 2257 //////////////////////////////////////////////////////////////////////////// 2258 bool PVID3ParCom::read16(PVFile* aInputFile, uint16 &aData) 2259 { 2260 const int32 N = 2; 2261 uint8 bytes[N]; 2262 aData = 0; 2263 2264 int32 retVal = (int32)(aInputFile->Read((void*)bytes, 1, N)); 2265 2266 if (retVal < N) 2267 return false; 2268 2269 for (int32 i = 0; i < N; i++) 2270 aData = (uint16)((aData << 8) | bytes[i]); 2271 2272 return true; 2273 } 2274 2275 //////////////////////////////////////////////////////////////////////////// 2276 bool PVID3ParCom::read24(PVFile* aInputFile, uint32 &aData) 2277 { 2278 const int32 N = 3; 2279 uint8 bytes[N]; 2280 aData = 0; 2281 2282 int32 retVal = (int32)(aInputFile->Read((void*)bytes, 1, N)); 2283 2284 if (retVal < N) 2285 return false; 2286 2287 for (int32 i = 0; i < N; i++) 2288 aData = (aData << 8) | bytes[i]; 2289 2290 return true; 2291 } 2292 2293 //////////////////////////////////////////////////////////////////////////// 2294 bool PVID3ParCom::read8(PVFile* aInputFile, uint8 &aData) 2295 { 2296 aData = 0; 2297 2298 int32 retVal = (int32)(aInputFile->Read((void*) & aData, 1, 1)); 2299 2300 if (retVal < 1) 2301 return false; 2302 2303 return true; 2304 } 2305 2306 //////////////////////////////////////////////////////////////////////////// 2307 2308 PvmiKvpSharedPtr PVID3ParCom::AllocateKvp(OSCL_String& aKey, PvmiKvpValueType aValueType, uint32 aValueSize, bool &truncate) 2309 { 2310 uint8* myPtr = NULL; 2311 OsclRefCounter* refCounter; 2312 2313 uint aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA)); 2314 uint aligned_cleanup_size = oscl_mem_aligned_size(sizeof(PVID3ParComKvpCleanupDA)); 2315 uint aligned_kvp_size = oscl_mem_aligned_size(sizeof(PvmiKvp)); 2316 uint32 key_size = oscl_mem_aligned_size(aKey.get_size() + 1); 2317 uint32 total_size = aligned_refcnt_size + aligned_cleanup_size + 2318 aligned_kvp_size + key_size + aValueSize; 2319 2320 int32 error = 0; 2321 myPtr = (uint8*) AllocateValueArray(error, PVMI_KVPVALTYPE_UINT8PTR, total_size, &iAlloc); 2322 if ((error != OsclErrNone) || (!myPtr) || (total_size < aValueSize)) 2323 { 2324 if (myPtr) 2325 { 2326 iAlloc.deallocate(myPtr); 2327 } 2328 2329 char str_data_len[MAX_RANGE_INT_SIZE + 1] = {0}; 2330 oscl_snprintf(str_data_len, MAX_RANGE_INT_SIZE + 1, "%d", aValueSize); 2331 aKey += SEMI_COLON; 2332 aKey += KVP_VALTYPE_REQSIZE; 2333 aKey += _STRLIT_CHAR((char *)str_data_len); 2334 uint32 new_key_size = oscl_mem_aligned_size(aKey.get_size() + 1); 2335 error = OsclErrNone; 2336 total_size = aligned_refcnt_size + aligned_cleanup_size + aligned_kvp_size + new_key_size; 2337 myPtr = (uint8*) AllocateValueArray(error, PVMI_KVPVALTYPE_UINT8PTR, total_size, &iAlloc); 2338 truncate = true; 2339 if (OsclErrNone != error) 2340 { 2341 OSCL_LEAVE(OsclErrNoMemory); 2342 } 2343 } 2344 oscl_memset(myPtr, 0, total_size); 2345 2346 PVID3ParComKvpCleanupDA* kvpCleanup = OSCL_PLACEMENT_NEW(myPtr + aligned_refcnt_size, PVID3ParComKvpCleanupDA(&iAlloc)); 2347 refCounter = OSCL_PLACEMENT_NEW(myPtr, OsclRefCounterDA(myPtr, kvpCleanup)); 2348 myPtr += aligned_refcnt_size + aligned_cleanup_size; 2349 2350 PvmiKvp* kvp = OSCL_STATIC_CAST(PvmiKvp *, myPtr) ; 2351 myPtr += aligned_kvp_size; 2352 2353 kvp->key = OSCL_STATIC_CAST(char* , myPtr); 2354 myPtr += key_size; 2355 oscl_strncpy(kvp->key, aKey.get_cstr(), key_size); 2356 if (!truncate) 2357 { 2358 switch (aValueType) 2359 { 2360 case PVMI_KVPVALTYPE_WCHARPTR: 2361 kvp->value.pWChar_value = OSCL_STATIC_CAST(oscl_wchar*, myPtr); 2362 break; 2363 case PVMI_KVPVALTYPE_CHARPTR: 2364 kvp->value.pChar_value = OSCL_STATIC_CAST(char* , myPtr); 2365 break; 2366 case PVMI_KVPVALTYPE_UINT8PTR: 2367 kvp->value.pUint8_value = OSCL_STATIC_CAST(uint8*, myPtr); 2368 break; 2369 case PVMI_KVPVALTYPE_INT32PTR: 2370 kvp->value.pInt32_value = OSCL_STATIC_CAST(int32*, myPtr); 2371 break; 2372 case PVMI_KVPVALTYPE_UINT32PTR: 2373 kvp->value.pUint32_value = OSCL_STATIC_CAST(uint32*, myPtr); 2374 break; 2375 case PVMI_KVPVALTYPE_INT64PTR: 2376 kvp->value.pInt64_value = OSCL_STATIC_CAST(int64* , myPtr); 2377 break; 2378 case PVMI_KVPVALTYPE_UINT64PTR: 2379 kvp->value.pUint64_value = OSCL_STATIC_CAST(uint64* , myPtr); 2380 break; 2381 case PVMI_KVPVALTYPE_FLOATPTR: 2382 kvp->value.pFloat_value = OSCL_STATIC_CAST(float* , myPtr); 2383 break; 2384 case PVMI_KVPVALTYPE_DOUBLEPTR: 2385 kvp->value.pDouble_value = OSCL_STATIC_CAST(double*, myPtr); 2386 break; 2387 case PVMI_KVPVALTYPE_KSV: 2388 kvp->value.key_specific_value = OSCL_STATIC_CAST(OsclAny*, myPtr); 2389 default: 2390 break; 2391 } 2392 kvp->length = aValueSize; 2393 kvp->capacity = aValueSize; 2394 } 2395 else 2396 { 2397 kvp->length = 0; 2398 kvp->capacity = 0; 2399 2400 } 2401 PvmiKvpSharedPtr sharedPtr(kvp, refCounter); 2402 return sharedPtr; 2403 } 2404 2405 //////////////////////////////////////////////////////////////////////////// 2406 PVMFStatus PVID3ParCom::ConstructKvpKey(OSCL_String& aKey, PVID3FrameType aType, PVID3CharacterSet aCharSet) 2407 { 2408 aKey = _STRLIT_CHAR(""); 2409 2410 switch (aType) 2411 { 2412 case PV_ID3_FRAME_TITLE: 2413 aKey += _STRLIT_CHAR(KVP_KEY_TITLE); 2414 break; 2415 case PV_ID3_FRAME_ARTIST: 2416 aKey += _STRLIT_CHAR(KVP_KEY_ARTIST); 2417 break; 2418 case PV_ID3_FRAME_PART_OF_SET: 2419 aKey += _STRLIT_CHAR(KVP_KEY_PART_OF_SET); 2420 break; 2421 case PV_ID3_FRAME_ALBUM: 2422 aKey += _STRLIT_CHAR(KVP_KEY_ALBUM); 2423 break; 2424 case PV_ID3_FRAME_COPYRIGHT: 2425 aKey += _STRLIT_CHAR(KVP_KEY_COPYRIGHT); 2426 break; 2427 case PV_ID3_FRAME_GENRE: 2428 aKey += _STRLIT_CHAR(KVP_KEY_GENRE); 2429 if (aCharSet == PV_ID3_CHARSET_INVALID) 2430 { 2431 // ID3 V1 genre is a uint32 value 2432 aKey += SEMI_COLON; 2433 aKey += _STRLIT_CHAR(PVMI_KVPVALTYPE_STRING); 2434 aKey += _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING); 2435 aKey += SEMI_COLON; 2436 aKey += _STRLIT_CHAR(KVP_FORMAT_ID3V1); 2437 return PVMFSuccess; 2438 } 2439 break; 2440 case PV_ID3_FRAME_TRACK_NUMBER: 2441 aKey += _STRLIT_CHAR(KVP_KEY_TRACKINFO_TRACK_NUMBER); 2442 if (aCharSet == PV_ID3_CHARSET_INVALID) 2443 { 2444 // ID3 V1 track number is a uint32 value 2445 aKey += SEMI_COLON; 2446 aKey += _STRLIT_CHAR(PVMI_KVPVALTYPE_STRING); 2447 aKey += _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING); 2448 return PVMFSuccess; 2449 } 2450 break; 2451 case PV_ID3_FRAME_YEAR: 2452 aKey += _STRLIT_CHAR(KVP_KEY_YEAR); 2453 break; 2454 case PV_ID3_FRAME_DATE: 2455 aKey += _STRLIT_CHAR(KVP_KEY_DATE); 2456 break; 2457 case PV_ID3_FRAME_RECORDING_TIME: 2458 aKey += _STRLIT_CHAR(KVP_KEY_RECORDING_TIME); 2459 break; 2460 //new frames support 2461 case PV_ID3_FRAME_AUTHOR: 2462 aKey += _STRLIT_CHAR(KVP_KEY_AUTHOR); 2463 break; 2464 case PV_ID3_FRAME_COMPOSER: 2465 aKey += _STRLIT_CHAR(KVP_KEY_COMPOSER); 2466 break; 2467 case PV_ID3_FRAME_DESCRIPTION: 2468 aKey += _STRLIT_CHAR(KVP_KEY_DESCRIPTION); 2469 break; 2470 case PV_ID3_FRAME_VERSION: 2471 aKey += _STRLIT_CHAR(KVP_KEY_VERSION); 2472 break; 2473 case PV_ID3_FRAME_COMMENT: 2474 aKey += _STRLIT_CHAR(KVP_KEY_COMMENT); 2475 if ((iVersion != PV_ID3_V1_1) && (iVersion != PV_ID3_V1)) 2476 { 2477 aKey += SEMI_COLON; 2478 aKey += KVP_VALTYPE_LYRICS; 2479 } 2480 break; 2481 case PV_ID3_FRAME_TRACK_LENGTH: 2482 aKey += _STRLIT_CHAR(KVP_KEY_ID3DURATION); 2483 aKey += SEMI_COLON; 2484 aKey += _STRLIT_CHAR(KVP_VALTYPE_DURATION); 2485 return PVMFSuccess; // No character set for track length 2486 case PV_ID3_FRAME_PIC: 2487 case PV_ID3_FRAME_APIC: 2488 aKey += _STRLIT_CHAR(KVP_KEY_ALBUMART); 2489 aKey += SEMI_COLON; 2490 return PVMFSuccess; 2491 case PV_ID3_FRAME_LYRICS: 2492 aKey += _STRLIT_CHAR(KVP_KEY_LYRICS); 2493 aKey += SEMI_COLON; 2494 aKey += KVP_VALTYPE_LYRICS; 2495 break; 2496 case PV_ID3_FRAME_UNRECOGNIZED: 2497 case PV_ID3_FRAME_CANDIDATE: 2498 aKey += _STRLIT_CHAR(KVP_ID3V2_VALUE); 2499 aKey += FORWARD_SLASH; 2500 aKey += _STRLIT_CHAR((char *)iID3TagInfo.iID3V2FrameID); 2501 aKey += SEMI_COLON; 2502 aKey += _STRLIT_CHAR(KVP_VALTYPE_UINT8PTR_STRING); 2503 return PVMFSuccess; 2504 break; 2505 default: 2506 return PVMFErrNotSupported; 2507 } 2508 2509 2510 //add language code to lyrics key 2511 if ((aType == PV_ID3_FRAME_LYRICS) || (aType == PV_ID3_FRAME_COMMENT)) 2512 { 2513 //not valid for id3 v1 2514 if ((iVersion != PV_ID3_V1_1) && (iVersion != PV_ID3_V1)) 2515 { 2516 aKey += SEMI_COLON; 2517 aKey += _STRLIT_CHAR(KVP_PARAM_LANGUAGE_CODE); 2518 aKey += _STRLIT_CHAR((char*)iID3TagInfo.iID3V2LanguageID); 2519 return PVMFSuccess; 2520 } 2521 } 2522 aKey += SEMI_COLON; 2523 switch (aCharSet) 2524 { 2525 case PV_ID3_CHARSET_ISO88591: 2526 aKey += _STRLIT_CHAR(KVP_VALTYPE_ISO88591_CHAR); 2527 break; 2528 case PV_ID3_CHARSET_UTF16: 2529 aKey += _STRLIT_CHAR(KVP_VALTYPE_UTF16_WCHAR); 2530 break; 2531 case PV_ID3_CHARSET_UTF16BE: 2532 aKey += _STRLIT_CHAR(KVP_VALTYPE_UTF16BE_WCHAR); 2533 break; 2534 case PV_ID3_CHARSET_UTF8: 2535 aKey += _STRLIT_CHAR(KVP_VALTYPE_UTF8_CHAR); 2536 break; 2537 default: 2538 return PVMFErrNotSupported; 2539 } 2540 2541 aKey += NULL_CHARACTER; 2542 2543 return PVMFSuccess; 2544 } 2545 2546 //////////////////////////////////////////////////////////////////////////// 2547 PVMFStatus PVID3ParCom::ReadStringValueFrame(PVID3FrameType aFrameType, PVID3CharacterSet aCharSet, uint32 aValueSize) 2548 { 2549 // Construct key string 2550 OSCL_StackString<128> keyStr; 2551 if (ConstructKvpKey(keyStr, aFrameType, aCharSet) != PVMFSuccess) 2552 { 2553 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - ConstructKvpKey failed")); 2554 return PVMFErrNotSupported; 2555 } 2556 2557 // Allocate key-value pair 2558 int32 err = OsclErrNone; 2559 PvmiKvpSharedPtr kvpPtr; 2560 bool truncate = false; 2561 switch (aCharSet) 2562 { 2563 case PV_ID3_CHARSET_ISO88591: 2564 case PV_ID3_CHARSET_UTF8: 2565 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_CHARPTR, aValueSize + 1, truncate);); 2566 if (OsclErrNone != err || !kvpPtr) 2567 { 2568 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - AllocateKvp failed. err=%d", err)); 2569 return PVMFErrNoMemory; 2570 } 2571 2572 if (truncate) 2573 { 2574 iInputFile->Seek(aValueSize, Oscl_File::SEEKCUR); 2575 kvpPtr->length = 0; 2576 } 2577 else 2578 { 2579 if (readByteData(iInputFile, aValueSize, (uint8*)kvpPtr->value.pChar_value) == false) 2580 { 2581 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - readByteData failed")); 2582 return PVMFFailure; 2583 } 2584 2585 int32 valueLen = aValueSize; 2586 valueLen = oscl_strlen((char*)kvpPtr->value.pChar_value); 2587 2588 kvpPtr->value.pChar_value[valueLen] = NULL_TERM_CHAR; 2589 kvpPtr->length = valueLen + 1; 2590 } 2591 // Add to frame vector 2592 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2593 OSCL_FIRST_CATCH_ANY(err, 2594 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - iFrames.push_back failed. err=%d", err)); 2595 return PVMFErrNoMemory; 2596 ); 2597 break; 2598 2599 case PV_ID3_CHARSET_UTF16: 2600 case PV_ID3_CHARSET_UTF16BE: 2601 { 2602 // create buffers to store frame data 2603 uint8* ptrFrameData = NULL; 2604 ptrFrameData = (uint8*) AllocateValueArray(err, PVMI_KVPVALTYPE_UINT8PTR, aValueSize + 2, &iAlloc); 2605 if (OsclErrNone != err || !ptrFrameData) 2606 { 2607 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - frameData allocation failed")); 2608 return PVMFErrNoMemory; 2609 } 2610 oscl_memset(ptrFrameData, 0, aValueSize + 2); 2611 uint32 wchar_size = sizeof(oscl_wchar); //for platforms where wchar is 4 bytes. 2612 // Allocate key-value pair 2613 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_WCHARPTR, (wchar_size / 2) * (aValueSize + 2), truncate);); 2614 if (OsclErrNone != err || !kvpPtr) 2615 { 2616 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - AllocateKvp failed. err=%d", err)); 2617 return PVMFErrNoMemory; 2618 } 2619 2620 if (truncate) 2621 { 2622 iAlloc.deallocate(ptrFrameData); 2623 iInputFile->Seek(aValueSize, Oscl_File::SEEKCUR); 2624 kvpPtr->length = 0; 2625 } 2626 else 2627 { 2628 if (readByteData(iInputFile, aValueSize, ptrFrameData) == false) 2629 { 2630 iAlloc.deallocate(ptrFrameData); 2631 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - readByteData failed")); 2632 return PVMFFailure; 2633 } 2634 ptrFrameData[aValueSize] = 0; 2635 ptrFrameData[aValueSize+1] = 0; 2636 2637 uint32 endianType = UNICODE_LITTLE_ENDIAN; 2638 if (aCharSet == PV_ID3_CHARSET_UTF16BE) 2639 { 2640 endianType = UNICODE_BIG_ENDIAN; 2641 } 2642 2643 uint32 wcSize = EightBitToWideCharBufferTransfer(ptrFrameData, aValueSize, endianType, kvpPtr->value.pWChar_value); 2644 kvpPtr->value.pWChar_value[wcSize] = NULL_TERM_CHAR; 2645 iAlloc.deallocate(ptrFrameData); 2646 kvpPtr->length = wcSize; 2647 } 2648 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2649 OSCL_FIRST_CATCH_ANY(err, 2650 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - iFrame.push_back failed")); 2651 iAlloc.deallocate((OsclAny*)ptrFrameData); 2652 return PVMFErrNoMemory; 2653 ); 2654 } 2655 break; 2656 default: 2657 return PVMFFailure; 2658 } 2659 2660 return PVMFSuccess; 2661 } 2662 2663 2664 //////////////////////////////////////////////////////////////////////////// 2665 PVMFStatus PVID3ParCom::ReadFrame(PVID3FrameType aFrameType, uint32 aValueSize) 2666 { 2667 2668 // Construct key string 2669 OSCL_StackString<128> keyStr; 2670 if (ConstructKvpKey(keyStr, aFrameType, PV_ID3_CHARSET_INVALID) != PVMFSuccess) 2671 { 2672 LOG_ERR((0, "PVID3ParCom::ReadFrame: Error - ConstructKvpKey failed")); 2673 return PVMFErrNotSupported; 2674 } 2675 2676 // Allocate key-value pair 2677 int32 err = OsclErrNone; 2678 PvmiKvpSharedPtr kvpPtr; 2679 bool truncate = false; 2680 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_CHARPTR, aValueSize + 1 + VERSION_SIZE, truncate);); 2681 if (OsclErrNone != err || !kvpPtr) 2682 { 2683 LOG_ERR((0, "PVID3ParCom::ReadFrame: Error - AllocateKvp failed. err=%d", err)); 2684 return PVMFErrNoMemory; 2685 } 2686 2687 if (truncate) 2688 { 2689 iInputFile->Seek(aValueSize, Oscl_File::SEEKCUR); 2690 kvpPtr->length = 0; 2691 } 2692 else 2693 { 2694 kvpPtr->value.pUint8_value[0] = (uint8)iVersion; 2695 kvpPtr->value.pUint8_value[1] = 0; 2696 2697 if (readByteData(iInputFile, aValueSize, (uint8*)kvpPtr->value.pUint8_value + VERSION_SIZE) == false) 2698 { 2699 LOG_ERR((0, "PVID3ParCom::ReadFrame: Error - readByteData failed")); 2700 return PVMFFailure; 2701 } 2702 kvpPtr->value.pUint8_value[aValueSize+VERSION_SIZE] = 0; 2703 kvpPtr->length = aValueSize + VERSION_SIZE; 2704 } 2705 // Add to frame vector 2706 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2707 OSCL_FIRST_CATCH_ANY(err, 2708 LOG_ERR((0, "PVID3ParCom::ReadFrame: Error - iFrames.push_back failed. err=%d", err)); 2709 return PVMFErrNoMemory; 2710 ); 2711 2712 2713 return PVMFSuccess; 2714 } 2715 2716 2717 //////////////////////////////////////////////////////////////////////////// 2718 2719 // Read in a NULL terminated UNICODE string byte by byte and take most significant byte first 2720 PVMFStatus 2721 PVID3ParCom::readNullTerminatedUnicodeString(PVFile* aInputFile, OSCL_wHeapString<OsclMemAllocator> &aData, uint32 &bomSz) 2722 { 2723 uint8 buff[ID3_MAX_STRING_FRAME_LEN]; 2724 uint32 index = 0; 2725 uint16 endianCheck; 2726 if (read16(aInputFile, endianCheck) == false) 2727 { 2728 return PVMFFailure; 2729 } 2730 2731 iID3TagInfo.iTextType = PV_ID3_CHARSET_UTF16; 2732 uint32 endianType = 0; 2733 2734 //some id3 tools does not add BOM with null strings. 2735 if (endianCheck != 0) 2736 { 2737 bomSz = UNICODE_BOM_SIZE; 2738 // This frame's text strings are Unicode and the frame 2739 // does include a BOM value. (UTF-16) 2740 if (endianCheck == UNICODE_LITTLE_ENDIAN_INDICATOR_FULL) 2741 { 2742 endianType = UNICODE_LITTLE_ENDIAN; 2743 } 2744 else if (endianCheck == UNICODE_BIG_ENDIAN_INDICATOR_FULL) 2745 { 2746 endianType = UNICODE_BIG_ENDIAN; 2747 } 2748 //read frame data from file 2749 bool more = true; 2750 while (more && (index < ID3_MAX_STRING_FRAME_LEN)) 2751 { 2752 if (read8(iInputFile, buff[index]) == false) 2753 return PVMFFailure; 2754 2755 if ((index > 0) && (buff[index] == 0) && (buff[index -1] == 0)) 2756 more = false; 2757 index++; 2758 } 2759 2760 //read remaining characters if any. 2761 if (more) 2762 { 2763 uint16 temp = 1; 2764 while (temp != 0) 2765 if (read16(iInputFile, temp) == false) 2766 return PVMFFailure; 2767 } 2768 2769 } 2770 else 2771 { 2772 buff[0] = 0; 2773 buff[1] = 0; 2774 bomSz = 0; 2775 index = 2; 2776 } 2777 2778 int32 err = OsclErrNone; 2779 oscl_wchar *tmpData = NULL; 2780 tmpData = (oscl_wchar*) AllocateValueArray(err, PVMI_KVPVALTYPE_WCHARPTR, index); 2781 if (OsclErrNone != err || !tmpData) 2782 { 2783 LOG_ERR((0, "PVID3ParCom::readNullTerminatedUnicodeString: Error - allocation failed")); 2784 return PVMFErrNoMemory; 2785 } 2786 2787 uint32 wcSize = EightBitToWideCharBufferTransfer(buff, index, endianType, tmpData); 2788 tmpData[wcSize] = 0; 2789 aData = tmpData; 2790 OSCL_ARRAY_DELETE(tmpData); 2791 return PVMFSuccess; 2792 } 2793 2794 bool 2795 PVID3ParCom::readNullTerminatedAsciiString(PVFile* aInputFile, OSCL_HeapString<OsclMemAllocator> &aData) 2796 { 2797 uint8 buf[256]; 2798 int32 index = 0; 2799 2800 if (!read8(aInputFile, buf[index])) 2801 return PVMFFailure; 2802 2803 bool nextChar = (buf[index] == 0) ? false : true; 2804 2805 while (nextChar && (index < 256)) 2806 { 2807 index++; 2808 2809 if (!read8(aInputFile, buf[index])) 2810 return PVMFFailure; 2811 2812 nextChar = (buf[index] == 0) ? false : true; 2813 } 2814 2815 OSCL_HeapString<OsclMemAllocator> temp((const char *)buf); 2816 aData = temp; 2817 return true; 2818 } 2819 2820 PVMFStatus PVID3ParCom::ReadAlbumArtFrame(PVID3FrameType aFrameType, uint8 unicode, uint32 aFrameSize) 2821 { 2822 PvmfApicStruct* aApicStruct = NULL; 2823 uint8 picType; 2824 uint32 dataLen; 2825 OSCL_HeapString<OsclMemAllocator> ImageFormat; 2826 bool pic_as_url = false; 2827 bool truncate = false; 2828 int32 err = OsclErrNone; 2829 PvmiKvpSharedPtr kvpPtr; 2830 OSCL_StackString<128> keyStr; 2831 2832 if (ConstructKvpKey(keyStr, PV_ID3_FRAME_APIC, PV_ID3_CHARSET_INVALID) != PVMFSuccess) 2833 { 2834 LOG_ERR((0, "PVID3ParCom::ReadAlbumArtFrame: Error - ConstructKvpKey failed")); 2835 return PVMFErrNotSupported; 2836 } 2837 2838 switch (unicode) 2839 { 2840 case PV_ID3_CHARSET_ISO88591: 2841 case PV_ID3_CHARSET_UTF8: 2842 { 2843 OSCL_HeapString<OsclMemAllocator> description; 2844 2845 if (GetAlbumArtInfo(aFrameType, aFrameSize, ImageFormat, picType, description, dataLen) != PVMFSuccess) 2846 return PVMFFailure; 2847 2848 if (!oscl_strcmp(ImageFormat.get_cstr(), "-->")) 2849 { 2850 pic_as_url = true; 2851 break; 2852 } 2853 2854 keyStr += KVP_FORMAT_ALBUMART; 2855 keyStr += SEMI_COLON; 2856 keyStr += KVP_VALTYPE_ALBUMART; 2857 2858 //description and image format are stored as wchar. 2859 uint32 rfs = aFrameSize - (ImageFormat.get_size() + description.get_size()); 2860 uint32 wchar_size = sizeof(oscl_wchar); //for platforms that store wchar as 4 bytes. 2861 uint32 total_size = sizeof(PvmfApicStruct) + rfs + ((wchar_size) * (ImageFormat.get_size() + description.get_size())) + 2 * sizeof(oscl_wchar) ; 2862 2863 // Allocate key-value pair 2864 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_KSV, total_size, truncate);); 2865 if (OsclErrNone != err || !kvpPtr) 2866 { 2867 LOG_ERR((0, "PVID3ParCom::ReadAlbumArtFrame: Error - AllocateKvp failed. err=%d", err)); 2868 return PVMFFailure; 2869 } 2870 2871 if (truncate) 2872 { 2873 iInputFile->Seek(dataLen, Oscl_File::SEEKCUR); 2874 kvpPtr->capacity = 0; 2875 kvpPtr->length = 0; 2876 2877 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2878 OSCL_FIRST_CATCH_ANY(err, 2879 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - iFrame.push_back failed")); 2880 return PVMFErrNoMemory;); 2881 2882 return PVMFSuccess; 2883 2884 } 2885 2886 kvpPtr->capacity = total_size; 2887 kvpPtr->length = total_size; 2888 2889 //convert raw data to struct 2890 PVMFStatus status; 2891 status = ConvertAsciiDataToApic(ImageFormat.get_str(), description.get_str(), picType, 2892 dataLen, kvpPtr->value.key_specific_value, total_size); 2893 } 2894 break; 2895 2896 2897 case PV_ID3_CHARSET_UTF16: 2898 case PV_ID3_CHARSET_UTF16BE: 2899 { 2900 OSCL_wHeapString<OsclMemAllocator> description; 2901 if (GetAlbumArtInfo(aFrameType, aFrameSize, ImageFormat, picType, description, dataLen) != PVMFSuccess) 2902 return PVMFFailure; 2903 2904 if (!oscl_strcmp(ImageFormat.get_cstr(), "-->")) 2905 { 2906 pic_as_url = true; 2907 break; 2908 } 2909 2910 keyStr += KVP_FORMAT_ALBUMART; 2911 keyStr += SEMI_COLON; 2912 keyStr += KVP_VALTYPE_ALBUMART; 2913 2914 //image format is stored as wchar. 2915 uint32 rfs = aFrameSize - (ImageFormat.get_size() + (2 * oscl_strlen(description.get_str()))); 2916 uint32 wchar_size = sizeof(oscl_wchar); //for platforms that store wchar as 4 bytes. 2917 uint32 total_size = sizeof(PvmfApicStruct) + rfs + (wchar_size * (ImageFormat.get_size() + description.get_size())) + (2 * wchar_size); 2918 2919 // Allocate key-value pair 2920 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_KSV, total_size, truncate);); 2921 if (OsclErrNone != err || !kvpPtr) 2922 { 2923 LOG_ERR((0, "PVID3ParCom::ReadAlbumArtFrame: Error - AllocateKvp failed. err=%d", err)); 2924 return PVMFFailure; 2925 } 2926 2927 if (truncate) 2928 { 2929 iInputFile->Seek(dataLen, Oscl_File::SEEKCUR); 2930 kvpPtr->capacity = 0; 2931 kvpPtr->length = 0; 2932 2933 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2934 OSCL_FIRST_CATCH_ANY(err, 2935 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - iFrame.push_back failed")); 2936 return PVMFErrNoMemory;); 2937 2938 return PVMFSuccess; 2939 2940 } 2941 2942 kvpPtr->capacity = total_size; 2943 kvpPtr->length = total_size; 2944 2945 //convert raw data to struct 2946 PVMFStatus status; 2947 status = ConvertUnicodeDataToApic(ImageFormat.get_str(), description.get_str(), picType, 2948 dataLen , kvpPtr->value.key_specific_value, total_size); 2949 } 2950 break; 2951 default: 2952 return PVMFFailure; 2953 2954 } 2955 2956 if (pic_as_url) 2957 { 2958 2959 keyStr += KVP_VALTYPE_ISO88591_CHAR; 2960 bool truncate = false; 2961 // Allocate key-value pair 2962 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_CHARPTR, dataLen, truncate);); 2963 if (OsclErrNone != err || !kvpPtr) 2964 { 2965 LOG_ERR((0, "PVID3ParCom::ReadAlbumArtFrame: Error - AllocateKvp failed. err=%d", err)); 2966 return PVMFFailure; 2967 } 2968 2969 if (truncate) 2970 { 2971 iInputFile->Seek(dataLen, Oscl_File::SEEKCUR); 2972 kvpPtr->length = 0; 2973 2974 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2975 OSCL_FIRST_CATCH_ANY(err, 2976 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - iFrame.push_back failed")); 2977 return PVMFErrNoMemory;); 2978 2979 return PVMFSuccess; 2980 2981 } 2982 else 2983 { 2984 if (readByteData(iInputFile, dataLen, (uint8 *)kvpPtr->value.pChar_value) == false) 2985 return PVMFFailure; 2986 kvpPtr->value.pChar_value[dataLen] = NULL_TERM_CHAR; 2987 kvpPtr->length = dataLen; 2988 } 2989 } 2990 else 2991 { 2992 aApicStruct = OSCL_STATIC_CAST(PvmfApicStruct *, kvpPtr->value.key_specific_value); 2993 if (readByteData(iInputFile, dataLen, aApicStruct->iGraphicData) == false) 2994 return PVMFFailure; 2995 } 2996 2997 2998 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 2999 OSCL_FIRST_CATCH_ANY(err, 3000 LOG_ERR((0, "PVID3ParCom::ReadAlbumArtFrame: Error - iFrame.push_back failed")); 3001 return PVMFErrNoMemory; 3002 ); 3003 3004 return PVMFSuccess; 3005 } 3006 3007 PVMFStatus PVID3ParCom::ReadLyricsCommFrame(uint8 unicodeCheck, uint32 aFramesize, PVID3FrameType aFrameType) 3008 { 3009 3010 uint32 framesize = aFramesize; 3011 bool truncate = false; 3012 if (readByteData(iInputFile, ID3V2_LANGUAGE_SIZE, iID3TagInfo.iID3V2LanguageID) == false) 3013 { 3014 return PVMFFailure; 3015 } 3016 3017 iID3TagInfo.iID3V2LanguageID[ID3V2_LANGUAGE_SIZE] = 0; 3018 3019 //subtract 3 bytes of language from the frame size. 3020 framesize = aFramesize - ID3V2_LANGUAGE_SIZE ; 3021 if ((framesize == 0) || (framesize > aFramesize)) 3022 { 3023 return PVMFFailure; 3024 } 3025 //construct kvp for lyrics frame 3026 OSCL_StackString<128> keyStr; 3027 if (ConstructKvpKey(keyStr, aFrameType, (PVID3ParCom::PVID3CharacterSet)unicodeCheck) != PVMFSuccess) 3028 { 3029 LOG_ERR((0, "PVID3ParCom::ReadStringValueFrame: Error - ConstructKvpKey failed")); 3030 return PVMFErrNotSupported; 3031 } 3032 3033 int32 err = OsclErrNone; 3034 PvmiKvpSharedPtr kvpPtr; 3035 uint32 wchar_size = sizeof(oscl_wchar); //for platforms where wchar is 4 bytes. 3036 uint32 total_size = (wchar_size * framesize) + sizeof(PvmfLyricsCommStruct) + (2 * wchar_size) ; 3037 uint32 used_size = 0; 3038 // Allocate key-value pair 3039 OSCL_TRY(err, kvpPtr = AllocateKvp(keyStr, PVMI_KVPVALTYPE_KSV, total_size , truncate);); 3040 if (OsclErrNone != err || !kvpPtr) 3041 { 3042 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - AllocateKvp failed. err=%d", err)); 3043 return PVMFFailure; 3044 } 3045 3046 if (truncate) 3047 { 3048 iInputFile->Seek(framesize, Oscl_File::SEEKCUR); 3049 kvpPtr->capacity = 0; 3050 kvpPtr->length = 0; 3051 3052 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 3053 OSCL_FIRST_CATCH_ANY(err, 3054 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - iFrame.push_back failed")); 3055 return PVMFErrNoMemory;); 3056 3057 return PVMFSuccess; 3058 3059 } 3060 3061 PvmfLyricsCommStruct *lcStruct = NULL; 3062 uint8 *ptr = NULL; 3063 lcStruct = OSCL_STATIC_CAST(PvmfLyricsCommStruct *, kvpPtr->value.key_specific_value); 3064 ptr = (uint8 *)kvpPtr->value.key_specific_value; 3065 if (!ptr) 3066 { 3067 return PVMFFailure; 3068 } 3069 3070 ptr += sizeof(PvmfLyricsCommStruct); 3071 used_size += sizeof(PvmfLyricsCommStruct); 3072 3073 switch (unicodeCheck) 3074 { 3075 case PV_ID3_CHARSET_ISO88591: 3076 case PV_ID3_CHARSET_UTF8: 3077 { 3078 OSCL_HeapString<OsclMemAllocator> descriptor; 3079 3080 if (readNullTerminatedAsciiString(iInputFile, descriptor) == false) 3081 { 3082 iAlloc.deallocate(lcStruct); 3083 return PVMFFailure; 3084 } 3085 3086 uint32 desc_sz = descriptor.get_size(); 3087 framesize = framesize - desc_sz - 1 ; //subtract 1 for null character 3088 3089 if ((framesize > aFramesize) || (framesize == 0)) 3090 { 3091 lcStruct->iDescription = NULL; 3092 lcStruct->iData = NULL; 3093 break; 3094 } 3095 3096 lcStruct->iDescription = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3097 ptr += wchar_size * (desc_sz + 1); //1 for null char 3098 3099 used_size += wchar_size * (desc_sz + 1); 3100 if (used_size > total_size) 3101 return PVMFErrOverflow; 3102 if (desc_sz > 0) 3103 { 3104 uint32 sz = desc_sz + 1; 3105 oscl_UTF8ToUnicode((const char *)descriptor.get_cstr(), descriptor.get_size(), lcStruct->iDescription, sz); 3106 lcStruct->iDescription[sz] = 0; 3107 } 3108 else 3109 { 3110 lcStruct->iDescription[desc_sz] = 0; 3111 } 3112 3113 uint8 *data = NULL; 3114 uint32 datasz = framesize + 1; 3115 OSCL_TRY(err, data = (uint8*)iAlloc.allocate(datasz);); 3116 3117 if (OsclErrNone != err || !(data)) 3118 { 3119 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - allocation failed")); 3120 iInputFile->Seek(framesize, Oscl_File::SEEKCUR); 3121 3122 } 3123 3124 else 3125 { 3126 3127 if ((readByteData(iInputFile, framesize, data) == false)) 3128 { 3129 iAlloc.deallocate(data); 3130 return PVMFFailure; 3131 } 3132 3133 lcStruct->iData = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3134 used_size += datasz; 3135 3136 if (used_size > total_size) 3137 return PVMFErrOverflow; 3138 oscl_UTF8ToUnicode((const char *)data, framesize, lcStruct->iData, datasz); 3139 lcStruct->iData[datasz] = 0; 3140 3141 iAlloc.deallocate(data); 3142 } 3143 } 3144 3145 break; 3146 3147 case PV_ID3_CHARSET_UTF16: 3148 case PV_ID3_CHARSET_UTF16BE: 3149 { 3150 3151 uint32 bomSize = 0; 3152 OSCL_wHeapString<OsclMemAllocator> description ; 3153 3154 if (readNullTerminatedUnicodeString(iInputFile, description, bomSize) == false) 3155 { 3156 return PVMFFailure; 3157 } 3158 3159 uint32 desc_len = oscl_strlen(description.get_str()) ; 3160 framesize = framesize - (2 * desc_len) - 2 - bomSize; // description(2 byte unicode in id3 tag), null char, bom 3161 if ((framesize > aFramesize) || (framesize == 0)) 3162 { 3163 lcStruct->iDescription = NULL; 3164 lcStruct->iData = NULL; 3165 break; 3166 } 3167 3168 lcStruct->iDescription = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3169 ptr += wchar_size * (desc_len + 1); //1 for null char 3170 3171 used_size += wchar_size * (desc_len + 1); 3172 if (used_size > total_size) 3173 return PVMFErrOverflow; 3174 3175 if (desc_len > 0) 3176 { 3177 oscl_strncpy(lcStruct->iDescription, description.get_str(), desc_len); 3178 lcStruct->iDescription[desc_len + 1] = 0; 3179 } 3180 else 3181 { 3182 lcStruct->iDescription[desc_len] = 0; 3183 } 3184 3185 3186 uint16 endianCheck = 0; 3187 //check endian type 3188 if (read16(iInputFile, endianCheck) == false) 3189 { 3190 3191 return PVMFFailure; 3192 } 3193 3194 // This frame's text strings are Unicode and the frame 3195 // does include a BOM value. (UTF-16) 3196 iID3TagInfo.iTextType = PV_ID3_CHARSET_UTF16; 3197 uint32 endianType = 0; 3198 3199 if (endianCheck == UNICODE_LITTLE_ENDIAN_INDICATOR_FULL) 3200 { 3201 endianType = UNICODE_LITTLE_ENDIAN; 3202 } 3203 else if (endianCheck == UNICODE_BIG_ENDIAN_INDICATOR_FULL) 3204 { 3205 endianType = UNICODE_BIG_ENDIAN; 3206 } 3207 3208 framesize -= UNICODE_BOM_SIZE; 3209 if ((framesize > aFramesize) || (framesize == 0)) 3210 { 3211 lcStruct->iDescription = NULL; 3212 lcStruct->iData = NULL; 3213 break; 3214 } 3215 3216 uint8 *data = NULL; 3217 uint32 datasz = framesize + 2; 3218 int32 err = OsclErrNone; 3219 OSCL_TRY(err, data = (uint8*)iAlloc.allocate(datasz);); 3220 if (OsclErrNone != err || !(data)) 3221 { 3222 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - allocation failed")); 3223 truncate = true; 3224 } 3225 else 3226 { 3227 3228 oscl_memset(data, 0, datasz); 3229 if ((readByteData(iInputFile, framesize, data) == false)) 3230 { 3231 iAlloc.deallocate(data); 3232 return PVMFFailure; 3233 } 3234 lcStruct->iData = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3235 3236 used_size += wchar_size * (framesize / 2); //UCS-2 unicode 3237 if (used_size > total_size) 3238 return PVMFErrOverflow; 3239 3240 uint32 sz = EightBitToWideCharBufferTransfer(data, framesize, endianType , lcStruct->iData); 3241 lcStruct->iData[sz] = 0; 3242 3243 iAlloc.deallocate(data); 3244 } 3245 } 3246 break; 3247 3248 default: 3249 return PVMFFailure; 3250 3251 } 3252 3253 kvpPtr->capacity = (aFramesize - ID3V2_LANGUAGE_SIZE) + sizeof(PvmfLyricsCommStruct) ; 3254 kvpPtr->length = (aFramesize - ID3V2_LANGUAGE_SIZE) + sizeof(PvmfLyricsCommStruct) ; 3255 3256 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 3257 OSCL_FIRST_CATCH_ANY(err, 3258 LOG_ERR((0, "PVID3ParCom::ReadLyricsCommFrame: Error - iFrame.push_back failed")); 3259 return PVMFErrNoMemory; 3260 ); 3261 3262 3263 return PVMFSuccess; 3264 } 3265 3266 PVMFStatus PVID3ParCom::ConvertAsciiDataToApic(char* aMimeTypeID3, char* aDescriptionID3, 3267 uint8 aGraphicType, uint32 aGraphicDataLen, 3268 void *key_specific_value, uint32 total_size) 3269 { 3270 uint32 used_size = 0; 3271 uint8 *ptr = (uint8 *)key_specific_value; 3272 PvmfApicStruct* aAPICStruct = OSCL_STATIC_CAST(PvmfApicStruct*, key_specific_value); 3273 uint32 mime_string_size; 3274 uint32 description_size; 3275 mime_string_size = oscl_strlen(aMimeTypeID3) + 1; 3276 description_size = oscl_strlen(aDescriptionID3) + 1; 3277 ptr += sizeof(PvmfApicStruct); 3278 used_size += sizeof(PvmfApicStruct); 3279 if (used_size > total_size) 3280 return PVMFErrOverflow; 3281 aAPICStruct->iGraphicMimeType = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3282 ptr += sizeof(oscl_wchar) * (mime_string_size); 3283 used_size += sizeof(oscl_wchar) * (mime_string_size); 3284 if (used_size > total_size) 3285 return PVMFErrOverflow; 3286 aAPICStruct->iGraphicDescription = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3287 ptr += sizeof(oscl_wchar) * (description_size); 3288 used_size += sizeof(oscl_wchar) * (description_size); 3289 if (used_size > total_size) 3290 return PVMFErrOverflow; 3291 3292 oscl_memset(aAPICStruct->iGraphicDescription, 0 , description_size); 3293 oscl_memset(aAPICStruct->iGraphicMimeType , 0 , mime_string_size); 3294 oscl_UTF8ToUnicode((const char *)aDescriptionID3, description_size , aAPICStruct->iGraphicDescription, description_size); 3295 oscl_UTF8ToUnicode((const char *)aMimeTypeID3, mime_string_size, aAPICStruct->iGraphicMimeType, mime_string_size); 3296 3297 //push the data to PvmfApicStruct 3298 aAPICStruct->iGraphicType = aGraphicType; 3299 3300 aAPICStruct->iGraphicData = OSCL_STATIC_CAST(uint8 *, ptr); 3301 3302 aAPICStruct->iGraphicDataLen = aGraphicDataLen; 3303 3304 used_size += aGraphicDataLen; 3305 if (used_size > total_size) 3306 return PVMFErrOverflow; 3307 return PVMFSuccess; 3308 } 3309 3310 PVMFStatus PVID3ParCom::ConvertUnicodeDataToApic(char* aMimeTypeID3, oscl_wchar* aDescriptionID3, 3311 uint8 aGraphicType, uint32 aGraphicDataLen, 3312 void *key_specific_value, uint32 total_size) 3313 { 3314 uint32 used_size = 0; 3315 uint8 *ptr = (uint8 *)key_specific_value; 3316 PvmfApicStruct* aAPICStruct = OSCL_STATIC_CAST(PvmfApicStruct*, key_specific_value); 3317 uint32 mime_string_size; 3318 uint32 description_size; 3319 3320 mime_string_size = oscl_strlen(aMimeTypeID3) + 1; 3321 description_size = oscl_strlen(aDescriptionID3) + 1; 3322 3323 ptr += sizeof(PvmfApicStruct); 3324 used_size += sizeof(PvmfApicStruct); 3325 if (used_size > total_size) 3326 return PVMFErrOverflow; 3327 3328 aAPICStruct->iGraphicMimeType = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3329 ptr += sizeof(oscl_wchar) * mime_string_size; 3330 used_size += sizeof(oscl_wchar) * mime_string_size; 3331 if (used_size > total_size) 3332 return PVMFErrOverflow; 3333 aAPICStruct->iGraphicDescription = OSCL_STATIC_CAST(oscl_wchar *, ptr); 3334 ptr += sizeof(oscl_wchar) * description_size; 3335 used_size += sizeof(oscl_wchar) * description_size; 3336 if (used_size > total_size) 3337 return PVMFErrOverflow; 3338 //push the data to PvmfApicStruct 3339 oscl_memset(aAPICStruct->iGraphicDescription, '\0', sizeof(oscl_wchar)*description_size); 3340 oscl_memset(aAPICStruct->iGraphicMimeType , '\0', sizeof(oscl_wchar)*mime_string_size); 3341 oscl_UTF8ToUnicode((const char *)aMimeTypeID3, mime_string_size - 1, aAPICStruct->iGraphicMimeType, mime_string_size); 3342 aAPICStruct->iGraphicMimeType[mime_string_size] = 0; 3343 3344 oscl_strncpy(aAPICStruct->iGraphicDescription, aDescriptionID3, description_size); 3345 aAPICStruct->iGraphicDescription[description_size] = 0; 3346 aAPICStruct->iGraphicType = aGraphicType; 3347 aAPICStruct->iGraphicDataLen = aGraphicDataLen; 3348 aAPICStruct->iGraphicData = OSCL_STATIC_CAST(uint8 *, ptr); 3349 used_size += aGraphicDataLen; 3350 if (used_size > total_size) 3351 return PVMFErrOverflow; 3352 3353 return PVMFSuccess; 3354 } 3355 3356 PVMFStatus PVID3ParCom::GetAlbumArtInfo(PVID3FrameType aFrameType, uint32 aFrameSize, OSCL_HeapString<OsclMemAllocator> &aImageFormat, 3357 uint8 &aPicType, OSCL_HeapString<OsclMemAllocator> &aDescription, uint32 &aDataLen) 3358 { 3359 uint8 image_format[4] = {0}; 3360 PVMFStatus status = 0; 3361 uint32 size = 0; 3362 uint32 currentfilepos = 0 ; 3363 if (aFrameType == PV_ID3_FRAME_PIC) 3364 { 3365 if (readByteData(iInputFile, ID3V2_IMAGE_FORMAT_SIZE, image_format) == false) 3366 { 3367 return PVMFFailure; 3368 } 3369 else 3370 { 3371 aImageFormat = (char *)image_format; 3372 } 3373 if (read8(iInputFile, aPicType) == false) 3374 { 3375 return PVMFFailure; 3376 } 3377 3378 currentfilepos = iInputFile->Tell(); 3379 //read description from file 3380 status = readNullTerminatedAsciiString(iInputFile, aDescription); 3381 if (status != PVMFSuccess) 3382 { 3383 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3384 return PVMFFailure; 3385 } 3386 //get the graphic data len 3387 size = aDescription.get_size() + 1 ; // 1 byte for null char 3388 aDataLen = aFrameSize - (ID3V2_PIC_CONST_SIZE + size); 3389 if (aDataLen > aFrameSize) 3390 { 3391 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3392 aDataLen = 0; 3393 return PVMFFailure; 3394 } 3395 3396 3397 3398 } 3399 else if (aFrameType == PV_ID3_FRAME_APIC) 3400 { 3401 uint32 mimeSize; 3402 uint32 desSize; 3403 3404 currentfilepos = iInputFile->Tell(); 3405 status = readNullTerminatedAsciiString(iInputFile, aImageFormat); 3406 if (status != PVMFSuccess) 3407 { 3408 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3409 return PVMFFailure; 3410 } 3411 if (read8(iInputFile, aPicType) == false) 3412 { 3413 return PVMFFailure; 3414 } 3415 currentfilepos = iInputFile->Tell(); 3416 status = readNullTerminatedAsciiString(iInputFile, aDescription); 3417 if (status != PVMFSuccess) 3418 { 3419 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3420 return status; 3421 } 3422 3423 //get the graphic data len 3424 mimeSize = aImageFormat.get_size() + 1; //for null string 3425 desSize = aDescription.get_size() + 1; //for null string 3426 3427 aDataLen = aFrameSize - (ID3V2_APIC_CONST_SIZE + mimeSize + desSize); 3428 3429 if (aDataLen > aFrameSize) 3430 { 3431 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3432 aDataLen = 0; 3433 return PVMFFailure; 3434 } 3435 3436 3437 } 3438 return PVMFSuccess; 3439 } 3440 3441 PVMFStatus PVID3ParCom::GetAlbumArtInfo(PVID3FrameType aFrameType, uint32 aFrameSize, OSCL_HeapString<OsclMemAllocator> &aImageFormat, 3442 uint8 &aPicType, OSCL_wHeapString<OsclMemAllocator> &aDescription, uint32 &aDataLen) 3443 { 3444 uint8 image_format[4] = {0}; 3445 uint32 currentfilepos = 0; 3446 uint32 size = 0; 3447 if (aFrameType == PV_ID3_FRAME_PIC) 3448 { 3449 if (readByteData(iInputFile, ID3V2_IMAGE_FORMAT_SIZE, image_format) == false) 3450 { 3451 return PVMFFailure; 3452 } 3453 else 3454 { 3455 aImageFormat = (char *)image_format; 3456 } 3457 if (read8(iInputFile, aPicType) == false) 3458 { 3459 return PVMFFailure; 3460 } 3461 3462 uint32 bomSz = 0; 3463 currentfilepos = iInputFile->Tell(); 3464 //read description from file 3465 if (readNullTerminatedUnicodeString(iInputFile, aDescription, bomSz) == false) 3466 { 3467 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3468 return PVMFFailure; 3469 } 3470 3471 //get the graphic data len 3472 size = (2 * oscl_strlen(aDescription.get_str())) + bomSz + sizeof(oscl_wchar) * 1; //2 byte null character 3473 aDataLen = aFrameSize - (ID3V2_PIC_CONST_SIZE + size); 3474 if (aDataLen > aFrameSize) 3475 { 3476 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3477 aDataLen = 0; 3478 return PVMFFailure; 3479 } 3480 3481 3482 } 3483 else if (aFrameType == PV_ID3_FRAME_APIC) 3484 { 3485 uint32 mimeSize; 3486 uint32 desSize; 3487 currentfilepos = iInputFile->Tell(); 3488 //read the mime type information 3489 if (readNullTerminatedAsciiString(iInputFile, aImageFormat) == false) 3490 { 3491 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3492 return PVMFFailure; 3493 } 3494 //read the picture type information 3495 if (read8(iInputFile, aPicType) == false) 3496 { 3497 return PVMFFailure; 3498 } 3499 uint32 bomSz = 0; 3500 currentfilepos = iInputFile->Tell(); 3501 //read the null terminated description information 3502 if (readNullTerminatedUnicodeString(iInputFile, aDescription, bomSz) == false) 3503 { 3504 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3505 return PVMFFailure; 3506 } 3507 //get the graphic data len 3508 mimeSize = aImageFormat.get_size() + 1; 3509 desSize = (2 * oscl_strlen(aDescription.get_str())) + bomSz + sizeof(oscl_wchar) * 1; //2 bytes for null character 3510 aDataLen = aFrameSize - (ID3V2_APIC_CONST_SIZE + mimeSize + desSize); 3511 if (aDataLen > aFrameSize) 3512 { 3513 iInputFile->Seek(currentfilepos, Oscl_File::SEEKSET); 3514 aDataLen = 0; 3515 return PVMFFailure; 3516 } 3517 3518 3519 3520 } 3521 return PVMFSuccess; 3522 } 3523 3524 3525 //////////////////////////////////////////////////////////////////////////// 3526 PVMFStatus PVID3ParCom::ReadTrackLengthFrame(uint32 aValueSize, PVID3CharacterSet aCharSet) 3527 { 3528 OSCL_StackString<128> keyStr; 3529 if (ConstructKvpKey(keyStr, PV_ID3_FRAME_TRACK_LENGTH, PV_ID3_CHARSET_INVALID) != PVMFSuccess) 3530 { 3531 LOG_ERR((0, "PVID3ParCom::ReadTrackLengthFrame: Error - ConstructKvpKey failed")); 3532 return PVMFErrNotSupported; 3533 } 3534 3535 int32 err = OsclErrNone; 3536 uint8* ptrFrameData = NULL; 3537 ptrFrameData = (uint8*) AllocateValueArray(err, PVMI_KVPVALTYPE_UINT8PTR, aValueSize + 2, &iAlloc); 3538 if (OsclErrNone != err || !ptrFrameData) 3539 { 3540 LOG_ERR((0, "PVID3ParCom::ReadTrackLengthFrame: Error - ptrFrameData allocation failed")); 3541 return PVMFErrNoMemory; 3542 } 3543 3544 if (readByteData(iInputFile, aValueSize, ptrFrameData) == false) 3545 { 3546 iAlloc.deallocate((OsclAny*)ptrFrameData); 3547 LOG_ERR((0, "PVID3ParCom::ReadTrackLengthFrame: Error - readByteData failed")); 3548 return PVMFFailure; 3549 } 3550 ptrFrameData[aValueSize] = 0; 3551 ptrFrameData[aValueSize+1] = 0; 3552 3553 switch (aCharSet) 3554 { 3555 case PV_ID3_CHARSET_UTF16: 3556 case PV_ID3_CHARSET_UTF16BE: 3557 { 3558 //it uses 16-bit unicode 2.0 (ISO/IEC 10646-1:1993, UCS-2) 3559 3560 char* tmpData = NULL; 3561 int len = aValueSize / UNICODE_CHAR_SIZE + 1; 3562 tmpData = (char*) AllocateValueArray(err, PVMI_KVPVALTYPE_CHARPTR, len, &iAlloc); 3563 3564 if (sizeof(oscl_wchar) == UNICODE_CHAR_SIZE) 3565 { 3566 oscl_UnicodeToUTF8((oscl_wchar*)ptrFrameData, aValueSize / sizeof(oscl_wchar), tmpData, len); 3567 } 3568 else 3569 { 3570 oscl_wchar* tmpData2 = NULL; 3571 3572 tmpData2 = (oscl_wchar*) AllocateValueArray(err, PVMI_KVPVALTYPE_WCHARPTR, len); 3573 // convert 2 byte unicode data to 4 byte wchar data 3574 ExpandWChar2BytesTo4Bytes(tmpData2, (uint16*)ptrFrameData, len); 3575 3576 oscl_UnicodeToUTF8(tmpData2, aValueSize / UNICODE_CHAR_SIZE, tmpData, len); 3577 3578 OSCL_ARRAY_DELETE(tmpData2); 3579 } 3580 3581 // copy the UTF8 string back to ptrFrameData 3582 oscl_strncpy((char*)ptrFrameData, tmpData, len); 3583 3584 iAlloc.deallocate((OsclAny*)tmpData); 3585 } 3586 break; 3587 case PV_ID3_CHARSET_ISO88591: 3588 case PV_ID3_CHARSET_UTF8: 3589 break; 3590 default: 3591 return PVMFFailure; 3592 } 3593 3594 // The ID3 Track Length is a numeric string in milliseconds. 3595 uint32 duration = 0; 3596 int32 numericStringLen = oscl_strlen((const char*)ptrFrameData); 3597 3598 if (!PV_atoi((const char *)ptrFrameData, 'd', numericStringLen, duration)) 3599 { 3600 uint8* ptr = ptrFrameData; 3601 bool invalid_frame = false; 3602 while (ptr - ptrFrameData < numericStringLen) 3603 { 3604 // if the charater read is a digit or decimal point 3605 // then truncate it to integer value 3606 if (!(((*ptr >= ZERO_CHARACTER_ASCII_VALUE) && 3607 (*ptr <= NINE_CHARACTER_ASCII_VALUE)) || 3608 (*ptr == PERIOD_CHARACTER_ASCII_VALUE) || 3609 (*ptr == COMMA_CHARACTER_ASCII_VALUE))) 3610 { 3611 invalid_frame = true; 3612 break; 3613 } 3614 else if (*ptr == PERIOD_CHARACTER_ASCII_VALUE || 3615 *ptr == COMMA_CHARACTER_ASCII_VALUE) 3616 { 3617 numericStringLen = ptr - ptrFrameData; 3618 break; 3619 } 3620 ptr++; 3621 } 3622 3623 if (!invalid_frame) 3624 { 3625 numericStringLen = ptr - ptrFrameData; 3626 } 3627 else 3628 { 3629 iAlloc.deallocate((OsclAny*)ptrFrameData); 3630 numericStringLen = 0; 3631 return PVMFSuccess; 3632 } 3633 } 3634 3635 // Allocate key-value pair 3636 bool truncate = false; 3637 PvmiKvpSharedPtr kvpPtr; 3638 PVMFStatus status = PVMFSuccess; 3639 kvpPtr = HandleErrorForKVPAllocation(keyStr, PVMI_KVPVALTYPE_UINT32, 1, truncate, status); 3640 if (PVMFSuccess != status || !kvpPtr) 3641 { 3642 iAlloc.deallocate((OsclAny*)ptrFrameData); 3643 return PVMFErrNoMemory; 3644 } 3645 3646 kvpPtr->value.uint32_value = duration; // Track length in milliseconds 3647 kvpPtr->length = numericStringLen; 3648 3649 iAlloc.deallocate((OsclAny*)ptrFrameData); 3650 3651 OSCL_TRY(err, iFrames.push_back(kvpPtr);); 3652 OSCL_FIRST_CATCH_ANY(err, 3653 LOG_ERR((0, "PVID3ParCom::ReadTrackLengthFrame: Error - iFrame.push_back failed")); 3654 return PVMFErrNoMemory; 3655 ); 3656 3657 return PVMFSuccess; 3658 } 3659 3660 3661 //////////////////////////////////////////////////////////////////////////// 3662 PVMFStatus PVID3ParCom::GetKvpValueType(PvmiKvpSharedPtr aKvp, 3663 PvmiKvpValueType& aValueType, 3664 PVID3CharacterSet& aCharSet) 3665 { 3666 aValueType = GetValTypeFromKeyString(aKvp->key); 3667 aCharSet = PV_ID3_CHARSET_INVALID; 3668 char* param = NULL; 3669 switch (aValueType) 3670 { 3671 case PVMI_KVPVALTYPE_CHARPTR: 3672 aCharSet = PV_ID3_CHARSET_ISO88591; 3673 if (pv_mime_string_parse_param(aKvp->key, (char*) KVP_PARAM_CHAR_ENCODING_UTF8, param) > 0) 3674 aCharSet = PV_ID3_CHARSET_UTF8; 3675 break; 3676 case PVMI_KVPVALTYPE_WCHARPTR: 3677 aCharSet = PV_ID3_CHARSET_UTF16; 3678 if (pv_mime_string_parse_param(aKvp->key, (char*) KVP_PARAM_CHAR_ENCODING_UTF16BE, param) > 0) 3679 aCharSet = PV_ID3_CHARSET_UTF16BE; 3680 break; 3681 case PVMI_KVPVALTYPE_KSV: 3682 // Comment field 3683 break; 3684 case PVMI_KVPVALTYPE_UNKNOWN: 3685 return PVMFFailure; 3686 default: 3687 break; 3688 } 3689 3690 return PVMFSuccess; 3691 } 3692 3693 //////////////////////////////////////////////////////////////////////////// 3694 PVMFStatus PVID3ParCom::GetFrameTypeFromKvp(PvmiKvpSharedPtr aKvp, 3695 OSCL_String& aFrameID, 3696 PVID3FrameType& aFrameType) 3697 { 3698 return GetFrameTypeFromKvp(*aKvp, aFrameID, aFrameType); 3699 } 3700 3701 //////////////////////////////////////////////////////////////////////////// 3702 PVMFStatus PVID3ParCom::GetFrameTypeFromKvp(const PvmiKvp& aKvp, 3703 OSCL_String& aFrameID, 3704 PVID3FrameType& aFrameType) 3705 { 3706 if (iVersion == PV_ID3_V2_2) 3707 { 3708 if (pv_mime_strcmp(aKvp.key, KVP_KEY_TITLE) == 0) 3709 { 3710 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_TITLE); 3711 aFrameType = PV_ID3_FRAME_TITLE; 3712 } 3713 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ARTIST) == 0) 3714 { 3715 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_ARTIST); 3716 aFrameType = PV_ID3_FRAME_ARTIST; 3717 } 3718 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_PART_OF_SET) == 0) 3719 { 3720 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_PART_OF_SET); 3721 aFrameType = PV_ID3_FRAME_PART_OF_SET; 3722 } 3723 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ALBUM) == 0) 3724 { 3725 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_ALBUM); 3726 aFrameType = PV_ID3_FRAME_ALBUM; 3727 } 3728 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_TRACKINFO_TRACK_NUMBER) == 0) 3729 { 3730 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_TRACK_NUMBER); 3731 aFrameType = PV_ID3_FRAME_TRACK_NUMBER; 3732 } 3733 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_GENRE) == 0) 3734 { 3735 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_GENRE); 3736 aFrameType = PV_ID3_FRAME_GENRE; 3737 } 3738 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_YEAR) == 0) 3739 { 3740 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_YEAR); 3741 aFrameType = PV_ID3_FRAME_YEAR; 3742 } 3743 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_COPYRIGHT) == 0) 3744 { 3745 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_COPYRIGHT); 3746 aFrameType = PV_ID3_FRAME_COPYRIGHT; 3747 } 3748 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_COMMENT) == 0) 3749 { 3750 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_COMMENT); 3751 aFrameType = PV_ID3_FRAME_COMMENT; 3752 } 3753 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ID3DURATION) == 0) 3754 { 3755 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_TRACK_LENGTH); 3756 aFrameType = PV_ID3_FRAME_TRACK_LENGTH; 3757 } 3758 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_DATE) == 0) 3759 { 3760 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_DATE); 3761 aFrameType = PV_ID3_FRAME_DATE; 3762 } 3763 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ALBUMART) == 0) 3764 { 3765 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_ALBUMART); 3766 aFrameType = PV_ID3_FRAME_PIC; 3767 } 3768 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_LYRICS) == 0) 3769 { 3770 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_LYRICIST); 3771 aFrameType = PV_ID3_FRAME_LYRICS; 3772 } 3773 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_AUTHOR) == 0) 3774 { 3775 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_AUTHOR); 3776 aFrameType = PV_ID3_FRAME_AUTHOR; 3777 } 3778 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_COMPOSER) == 0) 3779 { 3780 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_COMPOSER); 3781 aFrameType = PV_ID3_FRAME_COMPOSER; 3782 } 3783 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_DESCRIPTION) >= 0) 3784 { 3785 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_DESCRIPTION); 3786 aFrameType = PV_ID3_FRAME_DESCRIPTION; 3787 } 3788 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_VERSION) == 0) 3789 { 3790 aFrameID = _STRLIT_CHAR(ID3V2_2_FRAME_ID_VERSION); 3791 aFrameType = PV_ID3_FRAME_VERSION; 3792 } 3793 else 3794 { 3795 LOG_ERR((0, "PVID3ParCom::GetFrameTypeFromKvp: Error : Frame type not supported for composing")); 3796 return PVMFErrNotSupported; 3797 } 3798 } 3799 else 3800 { 3801 if (pv_mime_strcmp(aKvp.key, KVP_KEY_TITLE) == 0) 3802 { 3803 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_TITLE); 3804 aFrameType = PV_ID3_FRAME_TITLE; 3805 } 3806 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ARTIST) == 0) 3807 { 3808 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_ARTIST); 3809 aFrameType = PV_ID3_FRAME_ARTIST; 3810 } 3811 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_PART_OF_SET) == 0) 3812 { 3813 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_PART_OF_SET); 3814 aFrameType = PV_ID3_FRAME_PART_OF_SET; 3815 } 3816 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ALBUM) == 0) 3817 { 3818 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_ALBUM); 3819 aFrameType = PV_ID3_FRAME_ALBUM; 3820 } 3821 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_TRACKINFO_TRACK_NUMBER) == 0) 3822 { 3823 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_TRACK_NUMBER); 3824 aFrameType = PV_ID3_FRAME_TRACK_NUMBER; 3825 } 3826 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_GENRE) == 0) 3827 { 3828 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_GENRE); 3829 aFrameType = PV_ID3_FRAME_GENRE; 3830 } 3831 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_YEAR) == 0) 3832 { 3833 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_YEAR); 3834 aFrameType = PV_ID3_FRAME_YEAR; 3835 } 3836 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_COPYRIGHT) == 0) 3837 { 3838 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_COPYRIGHT); 3839 aFrameType = PV_ID3_FRAME_COPYRIGHT; 3840 } 3841 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_COMMENT) == 0) 3842 { 3843 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_COMMENT); 3844 aFrameType = PV_ID3_FRAME_COMMENT; 3845 } 3846 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ID3DURATION) == 0) 3847 { 3848 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_TRACK_LENGTH); 3849 aFrameType = PV_ID3_FRAME_TRACK_LENGTH; 3850 } 3851 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_RECORDING_TIME) == 0) 3852 { 3853 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_RECORDING_TIME); 3854 aFrameType = PV_ID3_FRAME_RECORDING_TIME; 3855 } 3856 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_AUTHOR) == 0) 3857 { 3858 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_AUTHOR); 3859 aFrameType = PV_ID3_FRAME_AUTHOR; 3860 } 3861 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_COMPOSER) == 0) 3862 { 3863 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_COMPOSER); 3864 aFrameType = PV_ID3_FRAME_COMPOSER; 3865 } 3866 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_DESCRIPTION) == 0) 3867 { 3868 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_DESCRIPTION); 3869 aFrameType = PV_ID3_FRAME_DESCRIPTION; 3870 } 3871 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_VERSION) == 0) 3872 { 3873 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_VERSION); 3874 aFrameType = PV_ID3_FRAME_VERSION; 3875 } 3876 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_DATE) == 0) 3877 { 3878 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_DATE); 3879 aFrameType = PV_ID3_FRAME_DATE; 3880 } 3881 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_LYRICS) == 0) 3882 { 3883 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_LYRICIST); 3884 aFrameType = PV_ID3_FRAME_LYRICS; 3885 } 3886 else if (pv_mime_strcmp(aKvp.key, KVP_KEY_ALBUMART) == 0) 3887 { 3888 aFrameID = _STRLIT_CHAR(ID3_FRAME_ID_ALBUMART); 3889 aFrameType = PV_ID3_FRAME_APIC; 3890 } 3891 else 3892 { 3893 LOG_ERR((0, "PVID3ParCom::GetFrameTypeFromKvp: Error : Frame type not supported for composing")); 3894 return PVMFErrNotSupported; 3895 } 3896 } 3897 3898 return PVMFSuccess; 3899 } 3900 3901 //////////////////////////////////////////////////////////////////////////// 3902 PVMFStatus PVID3ParCom::GetID3v2FrameDataSize(PvmiKvpSharedPtr aKvp, 3903 PvmiKvpValueType aValueType, 3904 PVID3CharacterSet aCharSet, 3905 uint32& aSize) 3906 { 3907 aSize = 0; 3908 switch (aValueType) 3909 { 3910 case PVMI_KVPVALTYPE_CHARPTR: 3911 aSize += (BYTE_FOR_CHARACTERSET_FORMAT + oscl_strlen(aKvp->value.pChar_value) + 1); 3912 break; 3913 case PVMI_KVPVALTYPE_WCHARPTR: 3914 aSize += (BYTE_FOR_CHARACTERSET_FORMAT + 3915 (oscl_strlen(aKvp->value.pWChar_value) + 1) * sizeof(oscl_wchar)); 3916 break; 3917 case PVMI_KVPVALTYPE_KSV: 3918 // Comment field 3919 break; 3920 case PVMI_KVPVALTYPE_UINT32: 3921 uint32 value; 3922 value = aKvp->value.uint32_value; 3923 if (value == 0) 3924 return PVMFSuccess; 3925 while (value > 0) 3926 { 3927 value = value / 10; 3928 ++aSize; 3929 } 3930 break; 3931 default: 3932 return PVMFErrNotSupported; 3933 } 3934 3935 // Add 1 byte for BOM value to indicate byte order 3936 if (aCharSet == PV_ID3_CHARSET_UTF16) 3937 ++aSize; 3938 3939 return PVMFSuccess; 3940 } 3941 3942 //////////////////////////////////////////////////////////////////////////// 3943 PVMFStatus PVID3ParCom::ComposeID3v2Tag(OsclRefCounterMemFrag& aTag) 3944 { 3945 uint8* memFragPtr; 3946 uint32 index = 0; 3947 uint32 composedTagSize = 0; 3948 uint32 frameDataSize = 0; 3949 uint32 i = 0; 3950 char bufTrackLength[16]; 3951 oscl_wchar wbufTrackLength[16]; 3952 oscl_memset(bufTrackLength, 0, 16); 3953 oscl_memset(wbufTrackLength, 0, 16); 3954 PvmiKvpValueType kvpValueType; 3955 PVID3CharacterSet charSet; 3956 PVMFStatus status = PVMFSuccess; 3957 3958 // At least one frame should be present for a valid ID3 tag to be composed 3959 if (iFrames.empty()) 3960 { 3961 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - No Frames are available to add")); 3962 return PVMFFailure; 3963 } 3964 3965 // Calculate the size of composed ID3tag 3966 composedTagSize = GetID3TagSize(); 3967 if (composedTagSize == 0) 3968 { 3969 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - GetID3TagSize failed")); 3970 return PVMFFailure; 3971 } 3972 3973 //iUseMaxTagSize on but the max tag size set is smaller than the total tag size. 3974 if (iUseMaxTagSize && (iMaxTagSize < composedTagSize)) 3975 { 3976 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - Max tag size is smaller than size of composed tag")); 3977 return PVMFFailure; 3978 } 3979 3980 //if maxsize is greater than tagsize and padding is ON, allocate memory equal to iMaxTagSize 3981 if (iUseMaxTagSize && iUsePadding) 3982 composedTagSize = iMaxTagSize; 3983 3984 //if the fragment buffer size is not sufficient, allocate memory 3985 OsclMemoryFragment& my_memfrag = aTag.getMemFrag(); 3986 if (composedTagSize > aTag.getMemFragSize()) 3987 { 3988 OsclRefCounter* my_refcnt; 3989 3990 // Create mem frag for ID3 tag 3991 OsclMemAllocDestructDealloc<uint8> my_alloc; 3992 uint aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >)); 3993 uint8* myPtr = (uint8*) my_alloc.allocate(aligned_refcnt_size + composedTagSize); 3994 my_refcnt = OSCL_PLACEMENT_NEW(myPtr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(myPtr)); 3995 myPtr += aligned_refcnt_size; 3996 3997 my_memfrag.ptr = myPtr; 3998 my_memfrag.len = 0; 3999 4000 OsclRefCounterMemFrag mynewRefCntMemFrag(my_memfrag, my_refcnt, composedTagSize); 4001 4002 //frees the old memeory and make the RefCounterMemFrag point to newly allocated memory 4003 aTag = mynewRefCntMemFrag; 4004 } 4005 4006 memFragPtr = (uint8*)aTag.getMemFragPtr(); 4007 oscl_memset(memFragPtr, 0, composedTagSize); 4008 4009 // Form the tag header and place it into the tag buffer 4010 oscl_memcpy(memFragPtr, ID3_V2_IDENTIFIER, ID3V2_TAG_NUM_BYTES_ID); 4011 index += ID3V2_TAG_NUM_BYTES_ID; 4012 4013 // Store ID3 tag version 4014 memFragPtr[index++] = (uint8)iVersion; 4015 memFragPtr[index++] = 0; 4016 4017 // ID3v2 flags 4018 memFragPtr[index++] = ID3V2_FLAGS; 4019 4020 // Tag size (4 bytes) 4021 uint32 syncSafeInt = ConvertToSyncSafeInt(composedTagSize - 10); // Total Size of ID3 tag - 10 bytes for header 4022 #if (OSCL_BYTE_ORDER_LITTLE_ENDIAN) 4023 memFragPtr[index++] = (uint8)((syncSafeInt & 0xFF000000) >> 24); 4024 memFragPtr[index++] = (uint8)((syncSafeInt & 0x00FF0000) >> 16); 4025 memFragPtr[index++] = (uint8)((syncSafeInt & 0x0000FF00) >> 8); 4026 memFragPtr[index++] = (uint8)(syncSafeInt & 0x000000FF); 4027 #elif (OSCL_BYTE_ORDER_BIG_ENDIAN) 4028 uint32* sizePtr = (uint32*)(memFragPtr + index); 4029 *sizePtr = syncSafeInt; 4030 index += 4; 4031 #else 4032 #error "Byte order is not specified in OSCL" 4033 #endif 4034 4035 //iterate the frames and write into the tag buffer 4036 OSCL_StackString<4> frameID; 4037 PVID3FrameType frameType; 4038 for (i = 0; i < iFrames.size(); i++) 4039 { 4040 // 4 character Frame ID 4041 status = GetFrameTypeFromKvp(iFrames[i], frameID, frameType); 4042 4043 //ignore unsupported frames. 4044 if ((status == PVMFErrNotSupported) || (frameType == PV_ID3_FRAME_LYRICS) || 4045 (frameType == PV_ID3_FRAME_APIC) || (frameType == PV_ID3_FRAME_PIC) || 4046 (frameType == PV_ID3_FRAME_COMMENT)) 4047 { 4048 continue; 4049 } 4050 4051 if ((status != PVMFSuccess)) 4052 { 4053 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - GetFrameTypeFromKvp failed. status=%d", status)); 4054 return status; 4055 } 4056 if (iVersion == PV_ID3_V2_2) 4057 { 4058 oscl_memcpy(memFragPtr + index, frameID.get_cstr(), ID3V2_2_FRAME_NUM_BYTES_ID); 4059 index += ID3V2_2_FRAME_NUM_BYTES_ID; 4060 } 4061 else 4062 { 4063 oscl_memcpy(memFragPtr + index, frameID.get_cstr(), ID3V2_FRAME_NUM_BYTES_ID); 4064 index += ID3V2_FRAME_NUM_BYTES_ID; 4065 } 4066 status = GetKvpValueType(iFrames[i], kvpValueType, charSet); 4067 if (status != PVMFSuccess) 4068 { 4069 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - GetKvpValueType failed. status=%d", status)); 4070 return status; 4071 } 4072 4073 // Size of Frame (4 byte sync safe integer) 4074 status = GetID3v2FrameDataSize(iFrames[i], kvpValueType, charSet, frameDataSize); 4075 if (status != PVMFSuccess) 4076 { 4077 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - GetID3v2FrameDataSize failed. status=%d", status)); 4078 return status; 4079 } 4080 // syncSafeInt = ConvertToSyncSafeInt(frameDataSize); 4081 syncSafeInt = frameDataSize; 4082 4083 if (iVersion == PV_ID3_V2_2) 4084 { 4085 #if (OSCL_BYTE_ORDER_LITTLE_ENDIAN) 4086 memFragPtr[index++] = (uint8)((syncSafeInt & 0x00FF0000) >> 16); 4087 memFragPtr[index++] = (uint8)((syncSafeInt & 0x0000FF00) >> 8); 4088 memFragPtr[index++] = (uint8)(syncSafeInt & 0x000000FF); 4089 #elif (OSCL_BYTE_ORDER_BIG_ENDIAN) 4090 sizePtr = (uint32*)(memFragPtr + index); 4091 *sizePtr = syncSafeInt; 4092 index += 3; 4093 #else 4094 #error "Byte order not specified in OSCL" 4095 #endif 4096 4097 } 4098 else 4099 { 4100 #if (OSCL_BYTE_ORDER_LITTLE_ENDIAN) 4101 memFragPtr[index++] = (uint8)((syncSafeInt & 0xFF000000) >> 24); 4102 memFragPtr[index++] = (uint8)((syncSafeInt & 0x00FF0000) >> 16); 4103 memFragPtr[index++] = (uint8)((syncSafeInt & 0x0000FF00) >> 8); 4104 memFragPtr[index++] = (uint8)(syncSafeInt & 0x000000FF); 4105 #elif (OSCL_BYTE_ORDER_BIG_ENDIAN) 4106 sizePtr = (uint32*)(memFragPtr + index); 4107 *sizePtr = syncSafeInt; 4108 index += 4; 4109 #else 4110 #error "Byte order not specified in OSCL" 4111 #endif 4112 4113 //frame Flag for status messages 4114 memFragPtr[index++] = ID3V2_FLAGS; 4115 4116 //frame flag for format description 4117 memFragPtr[index++] = ID3V2_FLAGS; 4118 } 4119 4120 switch (kvpValueType) 4121 { 4122 case PVMI_KVPVALTYPE_CHARPTR: 4123 memFragPtr[index++] = (uint8) charSet; 4124 frameDataSize -= 2; // Minus 1 byte for the character set and 1 byte for NULL character 4125 oscl_memcpy(memFragPtr + index, iFrames[i]->value.pChar_value, frameDataSize); 4126 index += frameDataSize; 4127 memFragPtr[index++] = 0; // NULL terminate the string 4128 break; 4129 case PVMI_KVPVALTYPE_WCHARPTR: 4130 memFragPtr[index++] = (uint8)charSet; 4131 frameDataSize -= 3; // Minus 1 byte for the character set and 2 bytes for NULL character 4132 if (charSet == PV_ID3_CHARSET_UTF16) 4133 { 4134 #if (OSCL_BYTE_ORDER_LITTLE_ENDIAN) 4135 memFragPtr[index++] = UNICODE_LITTLE_ENDIAN_INDICATOR; 4136 memFragPtr[index++] = UNICODE_BIG_ENDIAN_INDICATOR; 4137 #elif (OSCL_BYTE_ORDER_BIG_ENDIAN) 4138 memFragPtr[index++] = UNICODE_BIG_ENDIAN_INDICATOR; 4139 memFragPtr[index++] = UNICODE_LITTLE_ENDIAN_INDICATOR; 4140 4141 #else 4142 #error "Byte order not specified" 4143 #endif 4144 frameDataSize -= 2; // Minus 1 byte for byte order 4145 } 4146 oscl_memcpy(memFragPtr + index, iFrames[i]->value.pWChar_value, frameDataSize); 4147 index += frameDataSize; 4148 memFragPtr[index++] = 0; // NULL terminate the string 4149 memFragPtr[index++] = 0; // NULL terminate the string 4150 break; 4151 case PVMI_KVPVALTYPE_UINT32: 4152 // Track length frame 4153 oscl_snprintf((char*)(memFragPtr + index), frameDataSize, "%d\0", iFrames[i]->value.uint32_value); 4154 break; 4155 case PVMI_KVPVALTYPE_KSV: 4156 // Comment frame 4157 memFragPtr[index++] = (uint8)charSet; 4158 frameDataSize -= 1; // Minus 1 byte for the character set 4159 break; 4160 default: 4161 LOG_ERR((0, "PVID3ParCom::ComposeID3v2Tag: Error - Unsupported key-value pair value type")); 4162 return PVMFErrNotSupported; 4163 } 4164 4165 } 4166 4167 //if padding is on and the tag size is less than the maximum tag specified, do the padding 4168 if (iUseMaxTagSize && iUsePadding && (index < iMaxTagSize)) 4169 { 4170 oscl_memset((OsclAny*)(memFragPtr + index), 0, (iMaxTagSize - index)); 4171 my_memfrag.len = iMaxTagSize; 4172 } 4173 else 4174 { 4175 //save the filesize into the memory fragment 4176 my_memfrag.len = index; 4177 } 4178 4179 return PVMFSuccess; 4180 } 4181 4182 //////////////////////////////////////////////////////////////////////////// 4183 PVID3ParCom::PVID3FrameType PVID3ParCom::FrameValidatedID3V2_4(uint8* aFrameID) 4184 { 4185 PVID3FrameType ID3V2FrameTypeReturnValue; 4186 4187 if ((oscl_memcmp(aFrameID, ID3_FRAME_ID_ENCRYPTION, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4188 (oscl_memcmp(aFrameID, ID3_FRAME_ID_AUDIO_SEEK_POINT_INDEX, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4189 (oscl_memcmp(aFrameID, ID3_FRAME_ID_COMMERCIAL_FRAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4190 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ENCRYPTION_REGISTRATION, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4191 (oscl_memcmp(aFrameID, ID3_FRAME_ID_EQUALIZATION2, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4192 (oscl_memcmp(aFrameID, ID3_FRAME_ID_EVENT_TIMING_CODES, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4193 (oscl_memcmp(aFrameID, ID3_FRAME_ID_GENERAL_ENCAPSULATED_OBJECT, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4194 (oscl_memcmp(aFrameID, ID3_FRAME_ID_GROUP_IDENTITY_REGISTRATION, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4195 (oscl_memcmp(aFrameID, ID3_FRAME_ID_LINKED_INFORMATION, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4196 (oscl_memcmp(aFrameID, ID3_FRAME_ID_MUSIC_CD_IDENTIFIER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4197 (oscl_memcmp(aFrameID, ID3_FRAME_ID_MPEG_LOCATION_LOOKUP_TABLE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4198 (oscl_memcmp(aFrameID, ID3_FRAME_ID_OWNERSHIP_FRAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4199 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PRIVATE_FRAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4200 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PLAY_COUNTER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4201 (oscl_memcmp(aFrameID, ID3_FRAME_ID_POPULARIMETER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4202 (oscl_memcmp(aFrameID, ID3_FRAME_ID_POSITION_SYNCH_FRAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4203 (oscl_memcmp(aFrameID, ID3_FRAME_ID_RECOMMENDED_BUFFER_SIZE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4204 (oscl_memcmp(aFrameID, ID3_FRAME_ID_RELATIVE_VOLUME_ADJUSTMENT2, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4205 (oscl_memcmp(aFrameID, ID3_FRAME_ID_REVERB, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4206 (oscl_memcmp(aFrameID, ID3_FRAME_ID_SYNCHRONIZED_LYRICS_TEXT, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4207 (oscl_memcmp(aFrameID, ID3_FRAME_ID_SYNCHRONIZED_TEMPO_CODES, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4208 (oscl_memcmp(aFrameID, ID3_FRAME_ID_BPM, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4209 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PLAYLIST_DELAY, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4210 (oscl_memcmp(aFrameID, ID3_FRAME_ID_FILE_TYPE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4211 (oscl_memcmp(aFrameID, ID3_FRAME_ID_CONTENT_GROUP_DESC, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4212 (oscl_memcmp(aFrameID, ID3_FRAME_ID_INITIAL_KEY, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4213 (oscl_memcmp(aFrameID, ID3_FRAME_ID_LANGUAGE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4214 (oscl_memcmp(aFrameID, ID3_FRAME_ID_MEDIA_TYPE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4215 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ORIGINAL_ALBUM, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4216 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ORIGINAL_FILENAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4217 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ORIGINAL_LYRICIST, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4218 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ORIGINAL_ARTIST, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4219 (oscl_memcmp(aFrameID, ID3_FRAME_ID_FILE_LICENSEE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4220 (oscl_memcmp(aFrameID, ID3_FRAME_ID_BAND, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4221 (oscl_memcmp(aFrameID, ID3_FRAME_ID_CONDUCTOR, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4222 (oscl_memcmp(aFrameID, ID3_FRAME_ID_MODIFIER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4223 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PART_OF_SET, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4224 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PUBLISHER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4225 (oscl_memcmp(aFrameID, ID3_FRAME_ID_INTERNET_RADIO_STATION_NAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4226 (oscl_memcmp(aFrameID, ID3_FRAME_ID_INTERNET_RADIO_STATION_OWNER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4227 (oscl_memcmp(aFrameID, ID3_FRAME_ID_RECORDING_CODE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4228 (oscl_memcmp(aFrameID, ID3_FRAME_ID_SOFTWARE_SETTING_ENCODE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4229 (oscl_memcmp(aFrameID, ID3_FRAME_ID_UNIQUE_FILE_IDENTIFIER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4230 (oscl_memcmp(aFrameID, ID3_FRAME_ID_TERMS_OF_USE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4231 (oscl_memcmp(aFrameID, ID3_FRAME_ID_COMMERCIAL_INFO, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4232 (oscl_memcmp(aFrameID, ID3_FRAME_ID_LEGAL_INFO, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4233 (oscl_memcmp(aFrameID, ID3_FRAME_ID_OFFICIAL_AUDIO_FILE_WEBPAGE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4234 (oscl_memcmp(aFrameID, ID3_FRAME_ID_OFFICIAL_ARTIST_WEBPAGE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4235 (oscl_memcmp(aFrameID, ID3_FRAME_ID_OFFICIAL_AUDIO__SOURCE_WEBPAGE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4236 (oscl_memcmp(aFrameID, ID3_FRAME_ID_OFFICIAL_RADIO_STATION_WEBPAGE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4237 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PAYMENT, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4238 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PUBLISHER_OFFICIAL_WEBPAGE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4239 (oscl_memcmp(aFrameID, ID3_FRAME_ID_USER_DEFINED_URL_LINK_FRAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4240 (oscl_memcmp(aFrameID, ID3_FRAME_ID_SIGNATURE_FRAME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4241 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ENCODING_TIME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4242 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ORIGINAL_RELEASE_TIME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4243 (oscl_memcmp(aFrameID, ID3_FRAME_ID_RELEASE_TIME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4244 (oscl_memcmp(aFrameID, ID3_FRAME_ID_TAGGING_TIME, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4245 (oscl_memcmp(aFrameID, ID3_FRAME_ID_INVOLVED_PEOPLE_LIST, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4246 (oscl_memcmp(aFrameID, ID3_FRAME_ID_MUSICIAN_CREDITS_LIST, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4247 (oscl_memcmp(aFrameID, ID3_FRAME_ID_MOOD, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4248 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PRODUCED_NOTICE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4249 (oscl_memcmp(aFrameID, ID3_FRAME_ID_ALBUM_SORT_ORDER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4250 (oscl_memcmp(aFrameID, ID3_FRAME_ID_PERFORMER_SORT_ORDER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4251 (oscl_memcmp(aFrameID, ID3_FRAME_ID_TITLE_SORT_ORDER, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4252 (oscl_memcmp(aFrameID, ID3_FRAME_ID_SET_SUBTITLE, ID3V2_FRAME_NUM_BYTES_ID) == 0) || 4253 (oscl_memcmp(aFrameID, ID3_FRAME_ID_USER_DEFINED_TEXT_INFO, ID3V2_FRAME_NUM_BYTES_ID) == 0) 4254 ) 4255 { 4256 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_UNRECOGNIZED; 4257 } 4258 // The frame ID made out of the characters capital A-Z and 0-9. 4259 else if (IS_POTENTIAL_FRAME_ID(aFrameID)) 4260 { 4261 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_CANDIDATE; 4262 } 4263 else 4264 { 4265 // Frame ID doesn't match with defined/possible frame Ids 4266 ID3V2FrameTypeReturnValue = PV_ID3_FRAME_INVALID; 4267 } 4268 return ID3V2FrameTypeReturnValue; 4269 } 4270 4271 PVMFStatus PVID3ParCom::PushFrameToFrameVector(PvmiKvpSharedPtr& aFrame, PvmiKvpSharedPtrVector& aFrameVector) 4272 { 4273 int32 err = OsclErrNone; 4274 OSCL_TRY(err, aFrameVector.push_back(aFrame);); 4275 OSCL_FIRST_CATCH_ANY(err, 4276 LOG_ERR((0, "PVID3ParCom::GetID3Frame: Error - aFrame.push_back failed")); 4277 return PVMFErrNoMemory;); 4278 return PVMFSuccess; 4279 } 4280 4281 OsclAny* PVID3ParCom::AllocateValueArray(int32& aLeaveCode, PvmiKvpValueType aValueType, int32 aNumElements, OsclMemAllocator* aMemAllocator) 4282 { 4283 int32 leaveCode = OsclErrNone; 4284 OsclAny* buffer = NULL; 4285 switch (aValueType) 4286 { 4287 case PVMI_KVPVALTYPE_WCHARPTR: 4288 if (aMemAllocator) 4289 { 4290 OSCL_TRY(leaveCode, 4291 buffer = (oscl_wchar*) aMemAllocator->ALLOCATE(aNumElements);); 4292 } 4293 else 4294 { 4295 OSCL_TRY(leaveCode, 4296 buffer = (oscl_wchar*) OSCL_ARRAY_NEW(oscl_wchar, aNumElements);); 4297 } 4298 break; 4299 4300 case PVMI_KVPVALTYPE_CHARPTR: 4301 if (aMemAllocator) 4302 { 4303 OSCL_TRY(leaveCode, 4304 buffer = (char*) aMemAllocator->ALLOCATE(aNumElements);); 4305 } 4306 else 4307 { 4308 OSCL_TRY(leaveCode, 4309 buffer = (char*) OSCL_ARRAY_NEW(char, aNumElements);); 4310 } 4311 break; 4312 case PVMI_KVPVALTYPE_UINT8PTR: 4313 if (aMemAllocator) 4314 { 4315 OSCL_TRY(leaveCode, 4316 buffer = (uint8*) aMemAllocator->ALLOCATE(aNumElements);); 4317 } 4318 else 4319 { 4320 OSCL_TRY(leaveCode, 4321 buffer = (uint8*) OSCL_ARRAY_NEW(char, aNumElements);); 4322 } 4323 break; 4324 default: 4325 break; 4326 } 4327 aLeaveCode = leaveCode; 4328 return buffer; 4329 } 4330 4331 PvmiKvpSharedPtr PVID3ParCom::HandleErrorForKVPAllocation(OSCL_String& aKey, PvmiKvpValueType aValueType, uint32 aValueSize, bool &truncate, PVMFStatus &aStatus) 4332 { 4333 PvmiKvpSharedPtr kvp; 4334 int32 err = OsclErrNone; 4335 aStatus = PVMFSuccess; 4336 OSCL_TRY(err, kvp = AllocateKvp(aKey, aValueType, aValueSize, truncate);); 4337 if (OsclErrNone != err) 4338 { 4339 LOG_ERR((0, "PVID3ParCom::SetID3Frame: Error - AllocateKvp failed")); 4340 aStatus = PVMFErrNoMemory; 4341 } 4342 return kvp; 4343 } 4344