--- /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();
+ }