os/ossrv/genericopenlibs/cstdlib/LCHAR/MBWCCONV.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 }