core/src/character_converter.cpp
changeset 0 7f656887cf89
--- /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();
+	}