@@ -463,40 +463,65 @@ static void convertISO8859ToString8(
463463 tmp = NULL ;
464464}
465465
466- void ID3::Iterator::getString (String8 *id) const {
466+ // the 2nd argument is used to get the data following the \0 in a comment field
467+ void ID3::Iterator::getString (String8 *id, String8 *comment) const {
468+ getstring (id, false );
469+ if (comment != NULL ) {
470+ getstring (comment, true );
471+ }
472+ }
473+
474+ // comment fields (COM/COMM) contain an initial short descriptor, followed by \0,
475+ // followed by more data. The data following the \0 can be retrieved by setting
476+ // "otherdata" to true.
477+ void ID3::Iterator::getstring (String8 *id, bool otherdata) const {
467478 id->setTo (" " );
468479
469- if (mFrameData == NULL ) {
480+ const uint8_t *frameData = mFrameData ;
481+ if (frameData == NULL ) {
470482 return ;
471483 }
472484
485+ uint8_t encoding = *frameData;
486+
473487 if (mParent .mVersion == ID3_V1 || mParent .mVersion == ID3_V1_1) {
474488 if (mOffset == 126 || mOffset == 127 ) {
475489 // Special treatment for the track number and genre.
476490 char tmp[16 ];
477- sprintf (tmp, " %d" , (int )*mFrameData );
491+ sprintf (tmp, " %d" , (int )*frameData );
478492
479493 id->setTo (tmp);
480494 return ;
481495 }
482496
483- convertISO8859ToString8 (mFrameData , mFrameSize , id);
497+ convertISO8859ToString8 (frameData , mFrameSize , id);
484498 return ;
485499 }
486500
487501 size_t n = mFrameSize - getHeaderLength () - 1 ;
502+ if (otherdata) {
503+ // skip past the encoding, language, and the 0 separator
504+ frameData += 4 ;
505+ int32_t i = n - 4 ;
506+ while (--i >= 0 && *++frameData != 0 ) ;
507+ int skipped = (frameData - mFrameData );
508+ if (skipped >= n) {
509+ return ;
510+ }
511+ n -= skipped;
512+ }
488513
489- if (* mFrameData == 0x00 ) {
514+ if (encoding == 0x00 ) {
490515 // ISO 8859-1
491- convertISO8859ToString8 (mFrameData + 1 , n, id);
492- } else if (* mFrameData == 0x03 ) {
516+ convertISO8859ToString8 (frameData + 1 , n, id);
517+ } else if (encoding == 0x03 ) {
493518 // UTF-8
494- id->setTo ((const char *)(mFrameData + 1 ), n);
495- } else if (* mFrameData == 0x02 ) {
519+ id->setTo ((const char *)(frameData + 1 ), n);
520+ } else if (encoding == 0x02 ) {
496521 // UTF-16 BE, no byte order mark.
497522 // API wants number of characters, not number of bytes...
498523 int len = n / 2 ;
499- const char16_t *framedata = (const char16_t *) (mFrameData + 1 );
524+ const char16_t *framedata = (const char16_t *) (frameData + 1 );
500525 char16_t *framedatacopy = NULL ;
501526#if BYTE_ORDER == LITTLE_ENDIAN
502527 framedatacopy = new char16_t [len];
@@ -513,7 +538,7 @@ void ID3::Iterator::getString(String8 *id) const {
513538 // UCS-2
514539 // API wants number of characters, not number of bytes...
515540 int len = n / 2 ;
516- const char16_t *framedata = (const char16_t *) (mFrameData + 1 );
541+ const char16_t *framedata = (const char16_t *) (frameData + 1 );
517542 char16_t *framedatacopy = NULL ;
518543 if (*framedata == 0xfffe ) {
519544 // endianness marker doesn't match host endianness, convert
0 commit comments