diff -r 000000000000 -r 7f656887cf89 core/src/character_converter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/src/character_converter.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,129 @@ +// character_converter.cpp +// +// Copyright (c) 2005 - 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "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: +// Accenture - Initial contribution +// + + +#include "character_converter.h" + +const TInt KSlack = 20; + + +CCharacterConverter* CCharacterConverter::NewL(TInt aMaxBlockSize, RFs& aFs, TUint aCharset) + { + CCharacterConverter* self = new(ELeave) CCharacterConverter(aMaxBlockSize, aFs, aCharset); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CCharacterConverter::~CCharacterConverter() + { + delete iCharSets; + delete iConverter; + delete iNarrowBuf; + delete iWideBuf; + } + +const TDesC& CCharacterConverter::ConvertChunkL(const TDesC8& aNarrowBuf, TChunkType aType) + { + ASSERT(aNarrowBuf.Length() <= iMaxBlockSize); + + switch (aType) + { + case EFirst: + { + iCharConvState = CCnvCharacterSetConverter::KStateDefault; + iNarrowPtr = aNarrowBuf; + if (iCharset == 0) + { + // Only spend time autodetecting if we haven't been told the charset to use + const TUint16* p = (const TUint16*)aNarrowBuf.Ptr(); + if ((*p == 0xFEFF) || (*p == 0xFFFE)) + { + iNarrowPtr.Delete(0, 2); + iCharset = (*p == 0xFEFF) ? KCharacterSetIdentifierUnicodeLittle : KCharacterSetIdentifierUnicodeBig; + } + else + { + iCharSets = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs); + TInt confidenceLevel; + CCnvCharacterSetConverter::AutoDetectCharacterSetL(confidenceLevel, iCharset, *iCharSets, iNarrowPtr.Left(32)); + } + } + iConverter->PrepareToConvertToOrFromL(iCharset, iFs); + } // Deliberate fall through. + case EMiddle: + { + if (aType == EMiddle) + { + iNarrowPtr += aNarrowBuf; + } + TInt numUnconvertibleChars; + const TInt ret = iConverter->ConvertToUnicode(iWidePtr, iNarrowPtr, iCharConvState, numUnconvertibleChars); + iNumUnconvertibleChars += numUnconvertibleChars; + if (ret < 0) + { + User::Leave(ret); + } + else if (ret > KSlack) + { + User::Leave(KErrCorrupt); + } + else if (ret > 0) + { + iNarrowPtr = iNarrowPtr.Right(ret); + } + else + { + iNarrowPtr.Zero(); + } + break; + } + case ELast: + { + iNarrowPtr += aNarrowBuf; + TInt numUnconvertibleChars; + const TInt ret = iConverter->ConvertToUnicode(iWidePtr, iNarrowPtr, iCharConvState, numUnconvertibleChars); + iNumUnconvertibleChars += numUnconvertibleChars; + if (ret < 0) + { + User::Leave(ret); + } + else if (ret > 0) + { + User::Leave(KErrCorrupt); + } + iNarrowPtr.Zero(); + break; + } + default: + { + ASSERT(EFalse); + } + } + + return iWidePtr; + } + +CCharacterConverter::CCharacterConverter(TInt aMaxBlockSize, RFs& aFs, TUint aCharset) + : iFs(aFs), iMaxBlockSize(aMaxBlockSize), iNarrowPtr(NULL, 0), iWidePtr(NULL, 0), iCharset(aCharset) + { + } + +void CCharacterConverter::ConstructL() + { + iNarrowBuf = HBufC8::NewL(iMaxBlockSize + KSlack); + iWideBuf = HBufC16::NewL(iMaxBlockSize + KSlack); + iNarrowPtr.Set(iNarrowBuf->Des()); + iWidePtr.Set(iWideBuf->Des()); + iConverter = CCnvCharacterSetConverter::NewL(); + }