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