genericopenlibs/cstdlib/LCHAR/MBWCCONV.CPP
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Rrun-time library routines for translating between multibyte and wide characters
       
    15 // mbstowcs, mbtowc, wcstombs, wctomb and mblen
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <utf.h>
       
    21 #include <stdlib.h>
       
    22 #include <string.h>
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 extern "C"
       
    28 {
       
    29 
       
    30 /**
       
    31 Converts the multibyte character addressed by s into the corresponding UNICODE
       
    32 character pwc
       
    33 @return the length, in bytes, of the multibyte character for which it found 
       
    34 a UNICODE equivalent
       
    35 @param pwc Is the address of a wide character, type wchar_t, 
       
    36 to receive the UNICODE equivalent of s.
       
    37 @param s Points to the multibyte character to be converted to UNICODE.
       
    38 @param n Is the maximum width, in bytes, for which to scan s for a valid multibyte
       
    39 sequence. Regardless of the value of n, no more than MB_CUR_MAX bytes are examined.
       
    40 */
       
    41 EXPORT_C int mbtowc (wchar_t *pwc, const char *s, size_t n)
       
    42 	{
       
    43 
       
    44 	int rval = 0;
       
    45 	if (s)
       
    46 		{
       
    47 		wchar_t wide;
       
    48 
       
    49 		//number of chars to convert has a max of MB_CUR_MAX
       
    50 		TInt maxlen = (n > MB_CUR_MAX ? MB_CUR_MAX : n);
       
    51 		
       
    52 		TPtrC8 src((const TUint8*)s, maxlen);
       
    53 		TPtr16 awc((TUint16*)&wide, 1);		//length of 1 as we only want 1 wide character
       
    54 
       
    55 		TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(awc, src);
       
    56 	
       
    57 		//return the number of chars converted which is the max number - the number not converted
       
    58 		//unless the character converted was the wide null character
       
    59 		if (ret >= 0)
       
    60 			{
       
    61 			rval = (L'\0' != wide) ? maxlen - ret : 0;
       
    62 
       
    63 			if (pwc)
       
    64 				*pwc = wide;	//only assign the return if we have a target
       
    65 			}
       
    66 		else
       
    67 			return -1;	//the conversion failed.
       
    68 
       
    69 		}
       
    70 	return rval;
       
    71 	}
       
    72 }
       
    73 
       
    74 
       
    75 extern "C"
       
    76 {
       
    77 
       
    78 EXPORT_C int mbstowcs (wchar_t *wstring, const char * string, size_t size)
       
    79 	{
       
    80 	//convert the string "string" to wide characters
       
    81 	//return number of wide characters
       
    82 
       
    83 	if (string)
       
    84 		{
       
    85 		
       
    86 		if (wstring)
       
    87 			{
       
    88 			TPtrC8 src((const TUint8*)string);
       
    89 			TPtr16 awc((TUint16*)wstring, size);		//max length of size
       
    90 
       
    91 			TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(awc, src);
       
    92 		
       
    93 			if (ret >= 0)
       
    94 				{
       
    95 				TUint len = awc.Length();	//return number of wide characters
       
    96 				if (len < size)
       
    97 					awc.ZeroTerminate();
       
    98 				return len;
       
    99 				}
       
   100 			else
       
   101 				return -1;	//the conversion failed.
       
   102 			}
       
   103 		else
       
   104 			{
       
   105 			//we have no output string.  
       
   106 			//ms say return len required
       
   107 			//gcc says nowt
       
   108 			return 1+strlen(string);	//max is could be
       
   109 			}
       
   110 		}
       
   111 	return 0;	
       
   112 	}
       
   113 
       
   114 
       
   115 	
       
   116 }
       
   117 
       
   118 
       
   119 
       
   120 extern "C"
       
   121 {
       
   122 
       
   123 /**
       
   124 Converts a wide character to a multibyte character
       
   125 @return If s is null, the return value is true (non-zero) if multibyte 
       
   126 characters have state-dependent encodings, or false (zero) if they do not.
       
   127 @param mbchar multibyte character
       
   128 @param wc wide character
       
   129 */
       
   130 EXPORT_C int wctomb (char * mbchar, wchar_t wc)
       
   131 	{
       
   132 	if (mbchar)
       
   133 		{
       
   134 		//deal with the special null character case
       
   135 		if (L'\0' == wc)
       
   136 			{
       
   137 			*mbchar = '\0';
       
   138 			return 1;
       
   139 			}
       
   140 
       
   141 		//so we have possible character which is not null
       
   142 		TPtr8 multi((TUint8*)mbchar, 0, MB_CUR_MAX);	//limit max length to MB_CUR_MAX
       
   143 		TPtrC16 wide ((const TUint16*)&wc);
       
   144 
       
   145 		TInt ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(multi, wide);
       
   146 
       
   147 		//ret has the number of wide characters left to convert, or an error
       
   148 		if (ret >= 0)	//we didn't get an error
       
   149 			//return the number of characters in the output
       
   150 			return multi.Length();
       
   151 		else
       
   152 			return -1;
       
   153 
       
   154 		}
       
   155 		//calling with a null dest string is used to initialise shift state
       
   156 		//we are only dealing with UTF8 which hasn't got one,
       
   157 		//therefore we always return 0.
       
   158 	else
       
   159 		return 0;
       
   160 	}
       
   161 }
       
   162 
       
   163 extern "C"
       
   164 {
       
   165 /**
       
   166 The wcstombs function converts a wide string to a string of multibyte
       
   167 characters.
       
   168 @return 
       
   169 @param string multibyte string
       
   170 @param wstring wide string
       
   171 @param size number of bytes written to.
       
   172 */
       
   173 EXPORT_C int wcstombs (char * string, const wchar_t * wstring, size_t size)
       
   174 	{
       
   175 	if (wstring)
       
   176 		{
       
   177 		if (string)
       
   178 			{
       
   179 			TPtr8 multi((TUint8*)string, size);	//limit max length to size
       
   180 			TPtrC16 wide((TText16*)wstring);
       
   181 
       
   182 			TInt ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(multi, wide);
       
   183 
       
   184 			if (ret >= 0)	//we didn't get an error
       
   185 				{
       
   186 				TUint len = multi.Length();
       
   187 				if (len < size)
       
   188 					multi.ZeroTerminate();
       
   189 				return len;			//null terminate
       
   190 				}
       
   191 			else
       
   192 				return -1;
       
   193 			}
       
   194 		else
       
   195 			{
       
   196 			//we have a null output string
       
   197 			//ms expects the length back.
       
   198 			//gcc says nothing about it.
       
   199 			//quick and dirty!!
       
   200 			return 1 + (MB_CUR_MAX * wcslen(wstring));		//max it can be
       
   201 			}
       
   202 		}
       
   203 	else
       
   204 		return 0;
       
   205 	}
       
   206 }
       
   207 
       
   208 
       
   209 
       
   210 extern "C"
       
   211 {
       
   212 /**
       
   213 If string is not a null pointer, the function returns the number of bytes in the 
       
   214 multibyte string 
       
   215 that constitute the next multibyte character, 
       
   216 or it returns -1 if the next n (or the remaining) bytes do not constitute a valid 
       
   217 multibyte character. mblen does not include the terminating null in the count of bytes. 
       
   218 @return the number of bytes in the multibyte string
       
   219 @param string 
       
   220 @param size 
       
   221 */
       
   222 EXPORT_C int mblen (const char *string, size_t size)
       
   223 	{
       
   224 	if (string)
       
   225 		{
       
   226 		wchar_t wide;
       
   227 
       
   228 		
       
   229 		//deal with an empty string without doing the conversion.
       
   230 		if ('\0' == *string)
       
   231 			return 0;
       
   232 
       
   233 		TInt maxlen = (size > MB_CUR_MAX ? MB_CUR_MAX : size);
       
   234 
       
   235 		TPtrC8 src((const TUint8*)string, maxlen);
       
   236 		TPtr16 awc((TUint16*)&wide, 1);		//length of 1 as we only want 1 wide character
       
   237 
       
   238 		TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(awc, src);
       
   239 	
       
   240 		//return the number of chars converted which is the max number - the number not converted
       
   241 		//unless the character converted was the wide null character
       
   242 		if (ret >= 0)
       
   243 			{
       
   244 			return ((L'\0' != wide) ? maxlen - ret : 0);
       
   245 			}
       
   246 		else
       
   247 			return -1;
       
   248 
       
   249 		}
       
   250 		//shift state would be initialised here if were using them
       
   251 		return 0;
       
   252 	}
       
   253 }