cryptoservices/certificateandkeymgmt/asn1/utf8strdec.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     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".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * UTF8STR.CPP
       
    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\>
       
    19 *
       
    20 */
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 /**
       
    26  @file
       
    27 */
       
    28 
       
    29 #include <asn1dec.h>
       
    30 
       
    31 TInt ConvertToUnicodeFromUtf8(TDes16& aUnicode, const TDesC8& aUtf8);
       
    32 
       
    33 EXPORT_C TASN1DecUTF8String::TASN1DecUTF8String(void)
       
    34 	{
       
    35 	}
       
    36 
       
    37 EXPORT_C HBufC* TASN1DecUTF8String::DecodeDERL(const TASN1DecGeneric& aSource)
       
    38 	{
       
    39 	return DecodeContentsL(aSource.GetContentDER());
       
    40 	}
       
    41 
       
    42 EXPORT_C HBufC* TASN1DecUTF8String::DecodeDERL(const TDesC8& aSource,TInt& aPos)
       
    43 
       
    44 	{
       
    45 	TPtrC8 Source=aSource.Mid(aPos);
       
    46 	TASN1DecGeneric gen(Source);
       
    47 	gen.InitL();
       
    48 	HBufC* res = DecodeContentsL(gen.GetContentDER());
       
    49 	aPos+=gen.LengthDER();
       
    50 	return res;
       
    51 	}
       
    52 
       
    53 HBufC* TASN1DecUTF8String::DecodeContentsL(const TDesC8& aSource)
       
    54 	{
       
    55 	HBufC* res = HBufC::NewLC(aSource.Length());
       
    56 	TPtr pRes = res->Des();
       
    57 	User::LeaveIfError(ConvertToUnicodeFromUtf8(pRes, aSource));
       
    58 	CleanupStack::Pop(res);
       
    59 	return res;
       
    60 	}
       
    61 
       
    62 /**
       
    63  * Converts text encoded using the Unicode transformation format UTF-8
       
    64  * into the Unicode UCS-2 character set.
       
    65  *
       
    66  * @param aUnicode	On return, contains the Unicode encoded output string.
       
    67  * @param aUtf8		The UTF-8 encoded input string
       
    68  * @return			The number of unconverted bytes left at the end of the
       
    69  *					input descriptor, or one of the error values defined
       
    70  *					in <code>TError</code>.
       
    71  */
       
    72 TInt ConvertToUnicodeFromUtf8(TDes16& aUnicode, const TDesC8& aUtf8)
       
    73 	{
       
    74 	if (aUtf8.Length()==0)
       
    75 		{
       
    76 		aUnicode.SetLength(0);
       
    77 		return 0;
       
    78 		}
       
    79 	if (aUnicode.MaxLength()==0)
       
    80 		{
       
    81 		return aUtf8.Length();
       
    82 		}
       
    83 	TUint16* pointerToCurrentUnicodeCharacter=CONST_CAST(TUint16*, aUnicode.Ptr());
       
    84 	const TUint16* pointerToLastUnicodeCharacter=pointerToCurrentUnicodeCharacter+(aUnicode.MaxLength()-1);
       
    85 	const TUint8* pointerToCurrentUtf8Byte=aUtf8.Ptr();
       
    86 	const TUint8* pointerToLastUtf8Byte=pointerToCurrentUtf8Byte+(aUtf8.Length()-1);
       
    87 	TBool inputIsTruncated=EFalse;
       
    88 	TUint16 replacementcharacter = 0xFFFD;
       
    89 	FOREVER
       
    90 		{
       
    91 		//__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers8));
       
    92 		//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers3));
       
    93 		TUint currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
    94 		if ((currentUtf8Byte&0x80)==0x00)
       
    95 			{
       
    96 			*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUtf8Byte);
       
    97 			}
       
    98 		else if ((currentUtf8Byte&0xe0)==0xc0)
       
    99 			{
       
   100 			//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers4));
       
   101 			if (pointerToCurrentUtf8Byte>=pointerToLastUtf8Byte)
       
   102 				{
       
   103 				--pointerToCurrentUnicodeCharacter;
       
   104 				--pointerToCurrentUtf8Byte;
       
   105 				inputIsTruncated=ETrue;
       
   106 				break;
       
   107 				}
       
   108 			TUint currentUnicodeCharacter=((currentUtf8Byte&0x1f)<<6);
       
   109 			++pointerToCurrentUtf8Byte;
       
   110 			currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
   111 			if ((currentUtf8Byte&0xc0)==0x80)
       
   112 				{
       
   113 				currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
       
   114 				*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
       
   115 				}
       
   116 			else
       
   117 				{
       
   118 				*pointerToCurrentUnicodeCharacter=replacementcharacter;
       
   119 				}
       
   120 			}
       
   121 		else if ((currentUtf8Byte&0xf0)==0xe0)
       
   122 			{
       
   123 			//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers5));
       
   124 			if (pointerToLastUtf8Byte-pointerToCurrentUtf8Byte<2)
       
   125 				{
       
   126 				--pointerToCurrentUnicodeCharacter;
       
   127 				--pointerToCurrentUtf8Byte;
       
   128 				inputIsTruncated=ETrue;
       
   129 				break;
       
   130 				}
       
   131 			TUint currentUnicodeCharacter=((currentUtf8Byte&0x0f)<<12);
       
   132 			++pointerToCurrentUtf8Byte;
       
   133 			currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
   134 			if ((currentUtf8Byte&0xc0)==0x80)
       
   135 				{
       
   136 				currentUnicodeCharacter|=((currentUtf8Byte&0x3f)<<6);
       
   137 				++pointerToCurrentUtf8Byte;
       
   138 				currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
   139 				if ((currentUtf8Byte&0xc0)==0x80)
       
   140 					{
       
   141 					currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
       
   142 					*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
       
   143 					}
       
   144 				else
       
   145 					{
       
   146 					*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, currentUnicodeCharacter);
       
   147 					}
       
   148 				}
       
   149 			else
       
   150 				{
       
   151 				*pointerToCurrentUnicodeCharacter=replacementcharacter;
       
   152 				}
       
   153 			
       
   154 			}
       
   155 		else if ((currentUtf8Byte&0xf8)==0xf0)
       
   156 			{
       
   157 			//__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers9));
       
   158 			if (pointerToCurrentUnicodeCharacter>=pointerToLastUnicodeCharacter)
       
   159 				{
       
   160 				--pointerToCurrentUnicodeCharacter;
       
   161 				--pointerToCurrentUtf8Byte;
       
   162 				break;
       
   163 				}
       
   164 			//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers6));
       
   165 			if (pointerToLastUtf8Byte-pointerToCurrentUtf8Byte<3)
       
   166 				{
       
   167 				--pointerToCurrentUnicodeCharacter;
       
   168 				--pointerToCurrentUtf8Byte;
       
   169 				inputIsTruncated=ETrue;
       
   170 				break;
       
   171 				}
       
   172 			TUint currentUnicodeCharacter=((currentUtf8Byte&0x07)<<8);
       
   173 			++pointerToCurrentUtf8Byte;
       
   174 			currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
   175 			if ((currentUtf8Byte&0xc0)==0x80)
       
   176 				{
       
   177 				currentUnicodeCharacter|=((currentUtf8Byte&0x3f)<<2);
       
   178 				if (currentUnicodeCharacter>=0x0040)
       
   179 					{
       
   180 					currentUnicodeCharacter-=0x0040;
       
   181 					if (currentUnicodeCharacter<0x0400)
       
   182 						{
       
   183 						++pointerToCurrentUtf8Byte;
       
   184 						currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
   185 						if ((currentUtf8Byte&0xc0)==0x80)
       
   186 							{
       
   187 							currentUnicodeCharacter|=((currentUtf8Byte&0x30)>>4);
       
   188 							*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, 0xd800|currentUnicodeCharacter);
       
   189 							currentUnicodeCharacter=((currentUtf8Byte&0x0f)<<6);
       
   190 							++pointerToCurrentUtf8Byte;
       
   191 							currentUtf8Byte=*pointerToCurrentUtf8Byte;
       
   192 							if ((currentUtf8Byte&0xc0)==0x80)
       
   193 								{
       
   194 								currentUnicodeCharacter|=(currentUtf8Byte&0x3f);
       
   195 								++pointerToCurrentUnicodeCharacter;
       
   196 								*pointerToCurrentUnicodeCharacter=STATIC_CAST(TUint16, 0xdc00|currentUnicodeCharacter);
       
   197 								}
       
   198 							}
       
   199 						}
       
   200 					}
       
   201 				}
       
   202 			}
       
   203 		else
       
   204 			{
       
   205 			*pointerToCurrentUnicodeCharacter=replacementcharacter;
       
   206 			}
       
   207 		//__ASSERT_DEBUG(pointerToCurrentUtf8Byte<=pointerToLastUtf8Byte, Panic(EPanicBadUtf8Pointers7));
       
   208 		//__ASSERT_DEBUG(pointerToCurrentUnicodeCharacter<=pointerToLastUnicodeCharacter, Panic(EPanicBadUnicodePointers10));
       
   209 		if ((pointerToCurrentUtf8Byte>=pointerToLastUtf8Byte) || (pointerToCurrentUnicodeCharacter>=pointerToLastUnicodeCharacter))
       
   210 			{
       
   211 			break;
       
   212 			}
       
   213 		++pointerToCurrentUnicodeCharacter;
       
   214 		++pointerToCurrentUtf8Byte;
       
   215 		}
       
   216 	if ((pointerToCurrentUtf8Byte<aUtf8.Ptr()) && inputIsTruncated)
       
   217 		{
       
   218 		return KErrArgument;
       
   219 		}
       
   220 	aUnicode.SetLength((pointerToCurrentUnicodeCharacter-aUnicode.Ptr())+1);
       
   221 	return pointerToLastUtf8Byte-pointerToCurrentUtf8Byte;
       
   222 	}