--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/metadatautility/Src/MetaDataParserID3v22.cpp Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,755 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This class implements parsing of ID3v2.2 according to the
+* specification found in www.id3.org. Note that only a selected
+* frames are supported at this time.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <libc/stdlib.h>
+
+#include "MetaDataParserID3v22.h"
+
+// CONSTANTS
+// (ID3v2.2 specification found in www.id3.org)
+const TInt KID3v2HeaderLength = 10;
+const TInt KID3v2FrameHeaderLength = 6;
+const TInt KID3v2FrameIdLength = 3;
+const TInt KID3v2GenreNameLength = 24;
+
+_LIT8( KID3v2FrameIdTitle, "TT2" );
+_LIT8( KID3v2FrameIdArtist, "TP1" );
+_LIT8( KID3v2FrameIdAlbum, "TAL" );
+_LIT8( KID3v2FrameIdYear, "TYE" );
+_LIT8( KID3v2FrameIdComment, "COM" );
+_LIT8( KID3v2FrameIdTrack, "TRK" );
+_LIT8( KID3v2FrameIdGenre, "TCO" );
+_LIT8( KID3v2FrameIdComposer, "TCM" );
+_LIT8( KID3v2FrameIdCopyright, "TCR" );
+_LIT8( KID3v2FrameIdOriginalArtist, "TOA" );
+_LIT8( KID3v2FrameIdUrl, "WAF" );
+_LIT8( KID3v2FrameIdUserUrl, "WXX" );
+_LIT8( KID3v2FrameIdJpeg, "PIC" );
+_LIT8( KID3v2FrameIdDuration, "TLE" );
+_LIT8( KID3v2FrameIdDate, "TDA" );
+_LIT8( KID3v2FrameIdRating, "POP" );
+
+_LIT8( KID3v2ImageFormatPng, "PNG" );
+_LIT8( KID3v2ImageFormatJpeg, "JPG" );
+
+
+// -----------------------------------------------------------------------------
+// (ID3v2.2 specification found in www.id3.org)
+//
+// $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00.
+// $01 UCS-2 encoded Unicode [UNICODE].
+// Terminated with $00 00.
+// -----------------------------------------------------------------------------
+const TInt KMetaDataParserAsciiEncoding = 0;
+const TInt KMetaDataParserUnicodeEncoding = 1;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::CMetaDataParserID3v22
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMetaDataParserID3v22::CMetaDataParserID3v22(
+ CMetaDataSource& aSource )
+ : CMetaDataParserID3v2(aSource)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::ConstructL()
+ {
+ User::LeaveIfError(iFs.Connect());
+ iExists = ETrue;
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::ConstructL - Done"));
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMetaDataParserID3v22* CMetaDataParserID3v22::NewL(
+ CMetaDataSource& aSource )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::NewL"));
+#endif
+ CMetaDataParserID3v22* self = new( ELeave ) CMetaDataParserID3v22( aSource );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Destructor
+CMetaDataParserID3v22::~CMetaDataParserID3v22()
+ {
+ iFs.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::PrepareToParseL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::PrepareToParseL()
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::PrepareToParseL"));
+#endif
+ // Most of validation was already done by builder.
+ TBuf8<KID3v2HeaderLength> header;
+ iSource->ReadL( 0, header );
+ // ID3v2.2 header consists of following parts:
+ // File identifier "ID3"
+ // Version $02 00
+ // Flags %xx000000
+ // Size 4 * %0xxxxxxx
+
+ // Read the data length
+ iFrameDataSize = 0;
+ for ( TInt i = 6; i < 10; i++ )
+ {
+ iFrameDataSize <<= 7;
+ iFrameDataSize |= header[i] & 0x7f;
+ }
+
+ iFrameOffset = KID3v2HeaderLength;
+ // iFrameDataSize is the entire size of ID3 tag including the header
+ iFrameDataSize += iFrameOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetNextFieldL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetNextFieldL(
+ TMetaDataFieldId& aFieldId,
+ TInt& aFrameHeaderSize,
+ TInt& aFrameSize )
+ {
+ TBuf8<KID3v2FrameHeaderLength> frameHeader;
+ iSource->ReadL( iFrameOffset, frameHeader );
+ // ID3v2.2 frame header consists of following parts:
+ // Frame identifier $xx xx xx
+ // Size $xx xx xx
+
+ aFrameSize = 0;
+
+ if(!frameHeader.Length())
+ User::Leave(KErrCorrupt);
+
+ for ( TInt i = 3; i < 6; i++ )
+ {
+ aFrameSize <<= 8;
+ aFrameSize |= frameHeader[i];
+ }
+
+ aFrameHeaderSize = KID3v2FrameHeaderLength;
+ TPtrC8 frameId = frameHeader.Left( KID3v2FrameIdLength );
+ _LIT8(KEMPTY, "\0\0\0");
+ TBuf8<3> empty (KEMPTY);
+ if ( aFrameSize == 0 && frameId == empty)
+ {
+ // We have hit the padding -> no more fields to read
+ aFieldId = EUnknownMetaDataField;
+ aFrameHeaderSize = 0;
+ return;
+ }
+ else if (aFrameSize == 0)
+ {
+ aFieldId = EUnknownMetaDataField;
+ return;
+ }
+
+ if ( frameId.Compare( KID3v2FrameIdTitle ) == 0 )
+ {
+ aFieldId = EMetaDataSongTitle;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdArtist ) == 0 )
+ {
+ aFieldId = EMetaDataArtist;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdAlbum ) == 0 )
+ {
+ aFieldId = EMetaDataAlbum;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdYear ) == 0 )
+ {
+ aFieldId = EMetaDataYear;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdComment ) == 0 )
+ {
+ aFieldId = EMetaDataComment;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdTrack ) == 0 )
+ {
+ aFieldId = EMetaDataAlbumTrack;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdGenre ) == 0 )
+ {
+ aFieldId = EMetaDataGenre;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdComposer ) == 0 )
+ {
+ aFieldId = EMetaDataComposer;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdCopyright ) == 0 )
+ {
+ aFieldId = EMetaDataCopyright;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdOriginalArtist ) == 0 )
+ {
+ aFieldId = EMetaDataOriginalArtist;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdUrl ) == 0 )
+ {
+ aFieldId = EMetaDataUrl;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdUserUrl ) == 0 )
+ {
+ aFieldId = EMetaDataUserUrl;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdJpeg ) == 0 )
+ {
+ aFieldId = EMetaDataJpeg;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdDuration ) == 0 )
+ {
+ aFieldId = EMetaDataDuration;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdDate ) == 0 )
+ {
+ aFieldId = EMetaDataDate;
+ }
+ else if ( frameId.Compare( KID3v2FrameIdRating ) == 0 )
+ {
+ aFieldId = EMetaDataRating;
+ }
+ else
+ {
+ aFieldId = EUnknownMetaDataField;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetUserUrlL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetUserUrlL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v23::GetUserUrlL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt encoding = (TInt) (des.Left(1))[0];
+
+ if(encoding == 0x00)
+ {
+ _LIT8(KNULL, "\0");
+ TInt descOffset = des.Find(KNULL);
+ if(descOffset + 2 > aSize)
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return; // empty frame
+ }
+ TPtrC8 info = des.Mid(descOffset + 2);
+ TInt length = info.Length();
+ if ( length )
+ {
+ HBufC* data16 = HBufC::NewLC( length );
+ TPtr unicode( data16->Des() );
+ unicode.Copy( info );
+ iContainer->AppendL( EMetaDataUserUrl, unicode );
+ CleanupStack::PopAndDestroy(); // data16
+ }
+ }
+ else
+ {
+ _LIT8(KNULL, "\0\0");
+ TInt descOffset = des.Find(KNULL);
+ if(descOffset + 3 > aSize)
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return; // empty frame
+ }
+ TPtrC8 info = des.Mid(descOffset + 3);
+ TInt length = info.Length();
+ if ( length )
+ {
+ HBufC* data16 = HBufC::NewLC( length );
+ TPtr unicode( data16->Des() );
+ unicode.Copy( info );
+ iContainer->AppendL( EMetaDataUserUrl, unicode );
+ CleanupStack::PopAndDestroy(); // data16
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // frame
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetTextInfoL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetTextInfoL(
+ TMetaDataFieldId aFieldId,
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetTextInfoL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt encoding = (TInt) (des.Left(1))[0];
+ TPtrC8 info = StripTrailingZeroes( des.Mid(1), encoding);
+ TInt length = info.Length();
+ if ( length )
+ {
+ HBufC* data16 = HBufC::NewLC( length );
+ TPtr unicode( data16->Des() );
+ if ( ConvertToUnicodeL(encoding, info, unicode) == KErrNone )
+ {
+ iContainer->AppendL( aFieldId, unicode );
+ }
+ CleanupStack::PopAndDestroy(); // data16
+ }
+
+ CleanupStack::PopAndDestroy(); // frame
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetGenreL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetGenreL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetGenreL"));
+#endif
+
+ HandleV2GetGenreL( aSize, KID3v2FrameHeaderLength, KID3v2GenreNameLength );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetTextYearL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetTextYearL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetTextYearL"));
+#endif
+ GetTextInfoL( EMetaDataYear, aSize );
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetCommentL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetCommentL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetCommentL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ if(aSize <= 4) // emppty frame
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+ TInt encoding = (TInt) (des.Left(1))[0];
+ // Skip over TextEncoding(1 byte) and Language(3 bytes)
+ TPtr8 text = des.MidTPtr(4);
+ // Skip over Content description from Comment
+ TInt contentDesLength;
+ if(encoding == 0)
+ {
+ _LIT8(KNull, "\0");
+ contentDesLength = text.Find(KNull);
+ text = text.MidTPtr(contentDesLength + 1);
+ }
+ else
+ {
+ _LIT8(KNull, "\0\0");
+ contentDesLength = text.Find(KNull);
+ text = text.MidTPtr(contentDesLength + 2);
+ }
+ TPtrC8 info = StripTrailingZeroes( text, encoding);
+ TInt length = info.Length();
+ if ( length )
+ {
+ HBufC* data16 = HBufC::NewLC( length );
+ TPtr unicode( data16->Des() );
+ if ( ConvertToUnicodeL(encoding, info, unicode) == KErrNone )
+ {
+ iContainer->AppendL( EMetaDataComment, unicode );
+ }
+ CleanupStack::PopAndDestroy(); // data16
+ }
+
+ CleanupStack::PopAndDestroy(); // frame
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetUrlL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetUrlL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetUrlL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ // Ignore information followed by termination $00
+ TInt trueEnd( des.Locate(0) );
+ if ( trueEnd == KErrNotFound )
+ {
+ trueEnd = des.Length();
+ }
+
+ TPtrC8 info = des.Left( trueEnd );
+ TInt length = info.Length();
+ if ( length )
+ {
+ HBufC* data16 = HBufC::NewLC( length );
+ TPtr unicode( data16->Des() );
+ unicode.Copy( info );
+ iContainer->AppendL( EMetaDataUrl, unicode );
+ CleanupStack::PopAndDestroy(); // data16
+ }
+
+ CleanupStack::PopAndDestroy(); // frame
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetJpegL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetJpegL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetJpegL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt encoding = (TInt) (des.Left(1))[0];
+
+ TPtrC8 imageFormat = des.Mid(1, 3);
+ if ( imageFormat.Compare( KID3v2ImageFormatJpeg ) != 0 &&
+ imageFormat.Compare( KID3v2ImageFormatPng ) != 0 )
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+
+ if(des.Length() < 5)
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+
+ TInt pictureType = (TInt) (des.Mid(4, 1))[0];
+ if ( !NeedRetrieveAlbumArt(pictureType) )
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+
+ TInt picOffset;
+ TPtrC8 text8 = des.Mid(5);
+ if ( encoding == KMetaDataParserAsciiEncoding )
+ {
+ picOffset = text8.Locate(0);
+ if ( picOffset == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+
+ picOffset++; // Description termination mark ($00)
+ }
+ else if ( encoding == KMetaDataParserUnicodeEncoding )
+ {
+ _LIT8(KNULL, "\0\0"); // 2 bytes of NULL
+ picOffset = text8.Find(KNULL);
+ if ( picOffset == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+ if (picOffset % 2) // check for offset odd number
+ {
+ picOffset++; // add 1 for word boundary
+ }
+ picOffset += 2; // Description termination mark ($00 00)
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+ TPtrC8 pic = des.Mid(picOffset + 5);
+ TInt length = pic.Length();
+ if ( length )
+ {
+ // save the offset and the size for retrieving the album art later
+ iAlbumOffset = picOffset + 5;
+ iAlbumType = pictureType;
+
+ if (iAlbumPtr)
+ {
+ delete iAlbumPtr; // delete the previous buffer
+ }
+
+ CleanupStack::Pop(); // frame - pop from Cleanup stack
+ iAlbumPtr = frame; // save the buffer
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetDurationL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetDurationL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v23::GetDurationL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt encoding = (TInt) (des.Left(1))[0];
+ TPtrC8 info = StripTrailingZeroes( des.Mid(1), encoding ); // $00
+ TInt length = info.Length();
+ if ( length )
+ {
+ TReal sec = (TReal) atoi((char*)info.Ptr()) / 1000;
+ TBuf16<10> info1;
+ info1.Num(sec, TRealFormat (9, 3));
+ iContainer->AppendL( EMetaDataDuration, info1 );
+ }
+
+ CleanupStack::PopAndDestroy(); // frame
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetTextDateL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetTextDateL(
+ TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetTextDateL"));
+#endif
+ GetTextInfoL( EMetaDataDate, aSize );
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::GetRatingL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v22::GetRatingL( TInt aSize )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::GetRatingL"));
+#endif
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + KID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+ _LIT8(KNull, "\0");
+ TInt offset = des.Find(KNull);
+ if(offset == KErrNotFound)
+ {
+ return;
+ }
+ TUint8 rating = des[offset + 1];
+ if ( rating > 0)
+ {
+ TBuf<8> data16;
+ data16.AppendNum(rating);
+ iContainer->AppendL( EMetaDataRating, data16 );
+ }
+ CleanupStack::PopAndDestroy(); // frame
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v22::ConvertToUnicodeL
+// -----------------------------------------------------------------------------
+//
+TInt CMetaDataParserID3v22::ConvertToUnicodeL(
+ TInt aEncoding,
+ const TDesC8& aDesc,
+ TDes16& aUnicode )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::ConvertToUnicodeL"));
+#endif
+ TPtrC8 unicodeData;
+ TUint characterSetId = 0;
+ TInt err;
+
+ CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC();
+ TInt state = CCnvCharacterSetConverter::KStateDefault;
+
+ if ( aEncoding == KMetaDataParserAsciiEncoding )
+ {
+ if(iAutoDetectChinese || iAutoDetectRussian || iAutoDetectJapanese)
+ {
+ err = AutoDetectL(aDesc, aUnicode);
+ CleanupStack::PopAndDestroy(); // charSetConv
+ return err;
+ }
+ else
+ {
+ // ISO-8859-1
+ characterSetId = KCharacterSetIdentifierIso88591;
+ unicodeData.Set( aDesc );
+ }
+ }
+ else if ( aEncoding == KMetaDataParserUnicodeEncoding )
+ {
+ // USC-2 with BOM
+ TInt bom = UnicodeBOM(aDesc);
+ if ( bom == KUnicodeBOMBigEndian )
+ {
+ //characterSetId = KCharacterSetIdentifierUcs2;
+ characterSetId = KCharacterSetIdentifierUnicodeBig;
+ // Skip BOM & Terminate marks
+ unicodeData.Set( aDesc.Mid( 2, aDesc.Length() - 2 ) );
+ }
+ else if ( bom == KUnicodeBOMLittleEndian )
+ {
+ characterSetId = KCharacterSetIdentifierUnicodeLittle;
+ // Skip BOM & Terminate marks
+ unicodeData.Set( aDesc.Mid( 2, aDesc.Length() - 2 ) );
+ }
+ else
+ {
+ // USC-2 Big Endian without BOM
+ characterSetId = KCharacterSetIdentifierUnicodeBig;
+ unicodeData.Set( aDesc );
+ }
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ charSetConv->PrepareToConvertToOrFromL(characterSetId, *iCharacterSet, iFs);
+ err = charSetConv->ConvertToUnicode(aUnicode, unicodeData, state);
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v22::ConvertToUnicode :-> Tag Size[%d] Unicode Tag Size[%d]Bytes Unconverted[%d]"),
+ unicodeData.Length(), aUnicode.Length(), err);
+#endif
+
+ CleanupStack::PopAndDestroy(); // charSetConv
+ return err;
+ }
+
+// End of File