First public contribution.
2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
16 * This file contains the implementation of the UTF8 String ASN1 class.
17 * The IA5 string can contain the following characters:
18 * \<character set unknown pending arrival of ITU spec\>
29 TInt ConvertToUnicodeFromUtf8(TDes16& aUnicode, const TDesC8& aUtf8);
31 EXPORT_C TASN1DecUTF8String::TASN1DecUTF8String(void)
35 EXPORT_C HBufC* TASN1DecUTF8String::DecodeDERL(const TASN1DecGeneric& aSource)
37 return DecodeContentsL(aSource.GetContentDER());
40 EXPORT_C HBufC* TASN1DecUTF8String::DecodeDERL(const TDesC8& aSource,TInt& aPos)
43 TPtrC8 Source=aSource.Mid(aPos);
44 TASN1DecGeneric gen(Source);
46 HBufC* res = DecodeContentsL(gen.GetContentDER());
47 aPos+=gen.LengthDER();
51 HBufC* TASN1DecUTF8String::DecodeContentsL(const TDesC8& aSource)
53 HBufC* res = HBufC::NewLC(aSource.Length());
54 TPtr pRes = res->Des();
55 User::LeaveIfError(ConvertToUnicodeFromUtf8(pRes, aSource));
56 CleanupStack::Pop(res);
61 * Converts text encoded using the Unicode transformation format UTF-8
62 * into the Unicode UCS-2 character set.
64 * @param aUnicode On return, contains the Unicode encoded output string.
65 * @param aUtf8 The UTF-8 encoded input string
66 * @return The number of unconverted bytes left at the end of the
67 * input descriptor, or one of the error values defined
68 * in <code>TError</code>.
70 TInt ConvertToUnicodeFromUtf8(TDes16& aUnicode, const TDesC8& aUtf8)
72 if (aUtf8.Length()==0)
74 aUnicode.SetLength(0);
77 if (aUnicode.MaxLength()==0)
79 return aUtf8.Length();
81 TUint16* pointerToCurrentUnicodeCharacter=CONST_CAST(TUint16*, aUnicode.Ptr());
82 const TUint16* pointerToLastUnicodeCharacter=pointerToCurrentUnicodeCharacter+(aUnicode.MaxLength()-1);
83 const TUint8* pointerToCurrentUtf8Byte=aUtf8.Ptr();
84 const TUint8* pointerToLastUtf8Byte=pointerToCurrentUtf8Byte+(aUtf8.Length()-1);
85 TBool inputIsTruncated=EFalse;
86 TUint16 replacementcharacter = 0xFFFD;
89 //__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers8));
90 //__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers3));
91 TUint currentUtf8Byte=*pointerToCurrentUtf8Byte;
92 if ((currentUtf8Byte&0x80)==0x00)
94 *pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUtf8Byte);
96 else if ((currentUtf8Byte&0xe0)==0xc0)
98 //__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers4));
99 if (pointerToCurrentUtf8Byte>=pointerToLastUtf8Byte)
101 --pointerToCurrentUnicodeCharacter;
102 --pointerToCurrentUtf8Byte;
103 inputIsTruncated=ETrue;
106 TUint currentUnicodeCharacter=((currentUtf8Byte&0x1f)<<6);
107 ++pointerToCurrentUtf8Byte;
108 currentUtf8Byte=*pointerToCurrentUtf8Byte;
109 if ((currentUtf8Byte&0xc0)==0x80)
111 currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
112 *pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
116 *pointerToCurrentUnicodeCharacter=replacementcharacter;
119 else if ((currentUtf8Byte&0xf0)==0xe0)
121 //__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers5));
122 if (pointerToLastUtf8Byte-pointerToCurrentUtf8Byte<2)
124 --pointerToCurrentUnicodeCharacter;
125 --pointerToCurrentUtf8Byte;
126 inputIsTruncated=ETrue;
129 TUint currentUnicodeCharacter=((currentUtf8Byte&0x0f)<<12);
130 ++pointerToCurrentUtf8Byte;
131 currentUtf8Byte=*pointerToCurrentUtf8Byte;
132 if ((currentUtf8Byte&0xc0)==0x80)
134 currentUnicodeCharacter|=((currentUtf8Byte&0x3f)<<6);
135 ++pointerToCurrentUtf8Byte;
136 currentUtf8Byte=*pointerToCurrentUtf8Byte;
137 if ((currentUtf8Byte&0xc0)==0x80)
139 currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
140 *pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
144 *pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
149 *pointerToCurrentUnicodeCharacter=replacementcharacter;
153 else if ((currentUtf8Byte&0xf8)==0xf0)
155 //__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers9));
156 if (pointerToCurrentUnicodeCharacter>=pointerToLastUnicodeCharacter)
158 --pointerToCurrentUnicodeCharacter;
159 --pointerToCurrentUtf8Byte;
162 //__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers6));
163 if (pointerToLastUtf8Byte-pointerToCurrentUtf8Byte<3)
165 --pointerToCurrentUnicodeCharacter;
166 --pointerToCurrentUtf8Byte;
167 inputIsTruncated=ETrue;
170 TUint currentUnicodeCharacter=((currentUtf8Byte&0x07)<<8);
171 ++pointerToCurrentUtf8Byte;
172 currentUtf8Byte=*pointerToCurrentUtf8Byte;
173 if ((currentUtf8Byte&0xc0)==0x80)
175 currentUnicodeCharacter|=((currentUtf8Byte&0x3f)<<2);
176 if (currentUnicodeCharacter>=0x0040)
178 currentUnicodeCharacter-=0x0040;
179 if (currentUnicodeCharacter<0x0400)
181 ++pointerToCurrentUtf8Byte;
182 currentUtf8Byte=*pointerToCurrentUtf8Byte;
183 if ((currentUtf8Byte&0xc0)==0x80)
185 currentUnicodeCharacter|=((currentUtf8Byte&0x30)>>4);
186 *pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, 0xd800|currentUnicodeCharacter);
187 currentUnicodeCharacter=((currentUtf8Byte&0x0f)<<6);
188 ++pointerToCurrentUtf8Byte;
189 currentUtf8Byte=*pointerToCurrentUtf8Byte;
190 if ((currentUtf8Byte&0xc0)==0x80)
192 currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
193 ++pointerToCurrentUnicodeCharacter;
194 *pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, 0xdc00|currentUnicodeCharacter);
203 *pointerToCurrentUnicodeCharacter=replacementcharacter;
205 //__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers7));
206 //__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers10));
207 if ((pointerToCurrentUtf8Byte>=pointerToLastUtf8Byte) || (pointerToCurrentUnicodeCharacter>=pointerToLastUnicodeCharacter))
211 ++pointerToCurrentUnicodeCharacter;
212 ++pointerToCurrentUtf8Byte;
214 if ((pointerToCurrentUtf8Byte<aUtf8.Ptr()) && inputIsTruncated)
218 aUnicode.SetLength((pointerToCurrentUnicodeCharacter-aUnicode.Ptr())+1);
219 return pointerToLastUtf8Byte-pointerToCurrentUtf8Byte;