cryptoservices/certificateandkeymgmt/asn1/utf8strdec.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/asn1/utf8strdec.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,222 @@
+/*
+* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+* UTF8STR.CPP
+* This file contains the implementation of the UTF8 String ASN1 class.
+* The IA5 string can contain the following characters:
+* \<character set unknown pending arrival of ITU spec\>
+*
+*/
+
+
+
+
+/**
+ @file
+*/
+
+#include <asn1dec.h>
+
+TInt ConvertToUnicodeFromUtf8(TDes16& aUnicode, const TDesC8& aUtf8);
+
+EXPORT_C TASN1DecUTF8String::TASN1DecUTF8String(void)
+	{
+	}
+
+EXPORT_C HBufC* TASN1DecUTF8String::DecodeDERL(const TASN1DecGeneric& aSource)
+	{
+	return DecodeContentsL(aSource.GetContentDER());
+	}
+
+EXPORT_C HBufC* TASN1DecUTF8String::DecodeDERL(const TDesC8& aSource,TInt& aPos)
+
+	{
+	TPtrC8 Source=aSource.Mid(aPos);
+	TASN1DecGeneric gen(Source);
+	gen.InitL();
+	HBufC* res = DecodeContentsL(gen.GetContentDER());
+	aPos+=gen.LengthDER();
+	return res;
+	}
+
+HBufC* TASN1DecUTF8String::DecodeContentsL(const TDesC8& aSource)
+	{
+	HBufC* res = HBufC::NewLC(aSource.Length());
+	TPtr pRes = res->Des();
+	User::LeaveIfError(ConvertToUnicodeFromUtf8(pRes, aSource));
+	CleanupStack::Pop(res);
+	return res;
+	}
+
+/**
+ * Converts text encoded using the Unicode transformation format UTF-8
+ * into the Unicode UCS-2 character set.
+ *
+ * @param aUnicode	On return, contains the Unicode encoded output string.
+ * @param aUtf8		The UTF-8 encoded input string
+ * @return			The number of unconverted bytes left at the end of the
+ *					input descriptor, or one of the error values defined
+ *					in <code>TError</code>.
+ */
+TInt ConvertToUnicodeFromUtf8(TDes16& aUnicode, const TDesC8& aUtf8)
+	{
+	if (aUtf8.Length()==0)
+		{
+		aUnicode.SetLength(0);
+		return 0;
+		}
+	if (aUnicode.MaxLength()==0)
+		{
+		return aUtf8.Length();
+		}
+	TUint16* pointerToCurrentUnicodeCharacter=CONST_CAST(TUint16*, aUnicode.Ptr());
+	const TUint16* pointerToLastUnicodeCharacter=pointerToCurrentUnicodeCharacter+(aUnicode.MaxLength()-1);
+	const TUint8* pointerToCurrentUtf8Byte=aUtf8.Ptr();
+	const TUint8* pointerToLastUtf8Byte=pointerToCurrentUtf8Byte+(aUtf8.Length()-1);
+	TBool inputIsTruncated=EFalse;
+	TUint16 replacementcharacter = 0xFFFD;
+	FOREVER
+		{
+		//__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers8));
+		//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers3));
+		TUint currentUtf8Byte=*pointerToCurrentUtf8Byte;
+		if ((currentUtf8Byte&0x80)==0x00)
+			{
+			*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUtf8Byte);
+			}
+		else if ((currentUtf8Byte&0xe0)==0xc0)
+			{
+			//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers4));
+			if (pointerToCurrentUtf8Byte>=pointerToLastUtf8Byte)
+				{
+				--pointerToCurrentUnicodeCharacter;
+				--pointerToCurrentUtf8Byte;
+				inputIsTruncated=ETrue;
+				break;
+				}
+			TUint currentUnicodeCharacter=((currentUtf8Byte&0x1f)<<6);
+			++pointerToCurrentUtf8Byte;
+			currentUtf8Byte=*pointerToCurrentUtf8Byte;
+			if ((currentUtf8Byte&0xc0)==0x80)
+				{
+				currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
+				*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
+				}
+			else
+				{
+				*pointerToCurrentUnicodeCharacter=replacementcharacter;
+				}
+			}
+		else if ((currentUtf8Byte&0xf0)==0xe0)
+			{
+			//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers5));
+			if (pointerToLastUtf8Byte-pointerToCurrentUtf8Byte<2)
+				{
+				--pointerToCurrentUnicodeCharacter;
+				--pointerToCurrentUtf8Byte;
+				inputIsTruncated=ETrue;
+				break;
+				}
+			TUint currentUnicodeCharacter=((currentUtf8Byte&0x0f)<<12);
+			++pointerToCurrentUtf8Byte;
+			currentUtf8Byte=*pointerToCurrentUtf8Byte;
+			if ((currentUtf8Byte&0xc0)==0x80)
+				{
+				currentUnicodeCharacter|=((currentUtf8Byte&0x3f)<<6);
+				++pointerToCurrentUtf8Byte;
+				currentUtf8Byte=*pointerToCurrentUtf8Byte;
+				if ((currentUtf8Byte&0xc0)==0x80)
+					{
+					currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
+					*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
+					}
+				else
+					{
+					*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
+					}
+				}
+			else
+				{
+				*pointerToCurrentUnicodeCharacter=replacementcharacter;
+				}
+			
+			}
+		else if ((currentUtf8Byte&0xf8)==0xf0)
+			{
+			//__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers9));
+			if (pointerToCurrentUnicodeCharacter>=pointerToLastUnicodeCharacter)
+				{
+				--pointerToCurrentUnicodeCharacter;
+				--pointerToCurrentUtf8Byte;
+				break;
+				}
+			//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers6));
+			if (pointerToLastUtf8Byte-pointerToCurrentUtf8Byte<3)
+				{
+				--pointerToCurrentUnicodeCharacter;
+				--pointerToCurrentUtf8Byte;
+				inputIsTruncated=ETrue;
+				break;
+				}
+			TUint currentUnicodeCharacter=((currentUtf8Byte&0x07)<<8);
+			++pointerToCurrentUtf8Byte;
+			currentUtf8Byte=*pointerToCurrentUtf8Byte;
+			if ((currentUtf8Byte&0xc0)==0x80)
+				{
+				currentUnicodeCharacter|=((currentUtf8Byte&0x3f)<<2);
+				if (currentUnicodeCharacter>=0x0040)
+					{
+					currentUnicodeCharacter-=0x0040;
+					if (currentUnicodeCharacter<0x0400)
+						{
+						++pointerToCurrentUtf8Byte;
+						currentUtf8Byte=*pointerToCurrentUtf8Byte;
+						if ((currentUtf8Byte&0xc0)==0x80)
+							{
+							currentUnicodeCharacter|=((currentUtf8Byte&0x30)>>4);
+							*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, 0xd800|currentUnicodeCharacter);
+							currentUnicodeCharacter=((currentUtf8Byte&0x0f)<<6);
+							++pointerToCurrentUtf8Byte;
+							currentUtf8Byte=*pointerToCurrentUtf8Byte;
+							if ((currentUtf8Byte&0xc0)==0x80)
+								{
+								currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
+								++pointerToCurrentUnicodeCharacter;
+								*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, 0xdc00|currentUnicodeCharacter);
+								}
+							}
+						}
+					}
+				}
+			}
+		else
+			{
+			*pointerToCurrentUnicodeCharacter=replacementcharacter;
+			}
+		//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers7));
+		//__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers10));
+		if ((pointerToCurrentUtf8Byte>=pointerToLastUtf8Byte) || (pointerToCurrentUnicodeCharacter>=pointerToLastUnicodeCharacter))
+			{
+			break;
+			}
+		++pointerToCurrentUnicodeCharacter;
+		++pointerToCurrentUtf8Byte;
+		}
+	if ((pointerToCurrentUtf8Byte<aUtf8.Ptr()) && inputIsTruncated)
+		{
+		return KErrArgument;
+		}
+	aUnicode.SetLength((pointerToCurrentUnicodeCharacter-aUnicode.Ptr())+1);
+	return pointerToLastUtf8Byte-pointerToCurrentUtf8Byte;
+	}