sl@0: // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Rrun-time library routines for translating between multibyte and wide characters sl@0: // mbstowcs, mbtowc, wcstombs, wctomb and mblen sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: sl@0: sl@0: sl@0: extern "C" sl@0: { sl@0: sl@0: /** sl@0: Converts the multibyte character addressed by s into the corresponding UNICODE sl@0: character pwc sl@0: @return the length, in bytes, of the multibyte character for which it found sl@0: a UNICODE equivalent sl@0: @param pwc Is the address of a wide character, type wchar_t, sl@0: to receive the UNICODE equivalent of s. sl@0: @param s Points to the multibyte character to be converted to UNICODE. sl@0: @param n Is the maximum width, in bytes, for which to scan s for a valid multibyte sl@0: sequence. Regardless of the value of n, no more than MB_CUR_MAX bytes are examined. sl@0: */ sl@0: EXPORT_C int mbtowc (wchar_t *pwc, const char *s, size_t n) sl@0: { sl@0: sl@0: int rval = 0; sl@0: if (s) sl@0: { sl@0: wchar_t wide; sl@0: sl@0: //number of chars to convert has a max of MB_CUR_MAX sl@0: TInt maxlen = (n > MB_CUR_MAX ? MB_CUR_MAX : n); sl@0: sl@0: TPtrC8 src((const TUint8*)s, maxlen); sl@0: TPtr16 awc((TUint16*)&wide, 1); //length of 1 as we only want 1 wide character sl@0: sl@0: TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(awc, src); sl@0: sl@0: //return the number of chars converted which is the max number - the number not converted sl@0: //unless the character converted was the wide null character sl@0: if (ret >= 0) sl@0: { sl@0: rval = (L'\0' != wide) ? maxlen - ret : 0; sl@0: sl@0: if (pwc) sl@0: *pwc = wide; //only assign the return if we have a target sl@0: } sl@0: else sl@0: return -1; //the conversion failed. sl@0: sl@0: } sl@0: return rval; sl@0: } sl@0: } sl@0: sl@0: sl@0: extern "C" sl@0: { sl@0: sl@0: EXPORT_C int mbstowcs (wchar_t *wstring, const char * string, size_t size) sl@0: { sl@0: //convert the string "string" to wide characters sl@0: //return number of wide characters sl@0: sl@0: if (string) sl@0: { sl@0: sl@0: if (wstring) sl@0: { sl@0: TPtrC8 src((const TUint8*)string); sl@0: TPtr16 awc((TUint16*)wstring, size); //max length of size sl@0: sl@0: TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(awc, src); sl@0: sl@0: if (ret >= 0) sl@0: { sl@0: TUint len = awc.Length(); //return number of wide characters sl@0: if (len < size) sl@0: awc.ZeroTerminate(); sl@0: return len; sl@0: } sl@0: else sl@0: return -1; //the conversion failed. sl@0: } sl@0: else sl@0: { sl@0: //we have no output string. sl@0: //ms say return len required sl@0: //gcc says nowt sl@0: return 1+strlen(string); //max is could be sl@0: } sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: sl@0: sl@0: } sl@0: sl@0: sl@0: sl@0: extern "C" sl@0: { sl@0: sl@0: /** sl@0: Converts a wide character to a multibyte character sl@0: @return If s is null, the return value is true (non-zero) if multibyte sl@0: characters have state-dependent encodings, or false (zero) if they do not. sl@0: @param mbchar multibyte character sl@0: @param wc wide character sl@0: */ sl@0: EXPORT_C int wctomb (char * mbchar, wchar_t wc) sl@0: { sl@0: if (mbchar) sl@0: { sl@0: //deal with the special null character case sl@0: if (L'\0' == wc) sl@0: { sl@0: *mbchar = '\0'; sl@0: return 1; sl@0: } sl@0: sl@0: //so we have possible character which is not null sl@0: TPtr8 multi((TUint8*)mbchar, 0, MB_CUR_MAX); //limit max length to MB_CUR_MAX sl@0: TPtrC16 wide ((const TUint16*)&wc); sl@0: sl@0: TInt ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(multi, wide); sl@0: sl@0: //ret has the number of wide characters left to convert, or an error sl@0: if (ret >= 0) //we didn't get an error sl@0: //return the number of characters in the output sl@0: return multi.Length(); sl@0: else sl@0: return -1; sl@0: sl@0: } sl@0: //calling with a null dest string is used to initialise shift state sl@0: //we are only dealing with UTF8 which hasn't got one, sl@0: //therefore we always return 0. sl@0: else sl@0: return 0; sl@0: } sl@0: } sl@0: sl@0: extern "C" sl@0: { sl@0: /** sl@0: The wcstombs function converts a wide string to a string of multibyte sl@0: characters. sl@0: @return sl@0: @param string multibyte string sl@0: @param wstring wide string sl@0: @param size number of bytes written to. sl@0: */ sl@0: EXPORT_C int wcstombs (char * string, const wchar_t * wstring, size_t size) sl@0: { sl@0: if (wstring) sl@0: { sl@0: if (string) sl@0: { sl@0: TPtr8 multi((TUint8*)string, size); //limit max length to size sl@0: TPtrC16 wide((TText16*)wstring); sl@0: sl@0: TInt ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(multi, wide); sl@0: sl@0: if (ret >= 0) //we didn't get an error sl@0: { sl@0: TUint len = multi.Length(); sl@0: if (len < size) sl@0: multi.ZeroTerminate(); sl@0: return len; //null terminate sl@0: } sl@0: else sl@0: return -1; sl@0: } sl@0: else sl@0: { sl@0: //we have a null output string sl@0: //ms expects the length back. sl@0: //gcc says nothing about it. sl@0: //quick and dirty!! sl@0: return 1 + (MB_CUR_MAX * wcslen(wstring)); //max it can be sl@0: } sl@0: } sl@0: else sl@0: return 0; sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: extern "C" sl@0: { sl@0: /** sl@0: If string is not a null pointer, the function returns the number of bytes in the sl@0: multibyte string sl@0: that constitute the next multibyte character, sl@0: or it returns -1 if the next n (or the remaining) bytes do not constitute a valid sl@0: multibyte character. mblen does not include the terminating null in the count of bytes. sl@0: @return the number of bytes in the multibyte string sl@0: @param string sl@0: @param size sl@0: */ sl@0: EXPORT_C int mblen (const char *string, size_t size) sl@0: { sl@0: if (string) sl@0: { sl@0: wchar_t wide; sl@0: sl@0: sl@0: //deal with an empty string without doing the conversion. sl@0: if ('\0' == *string) sl@0: return 0; sl@0: sl@0: TInt maxlen = (size > MB_CUR_MAX ? MB_CUR_MAX : size); sl@0: sl@0: TPtrC8 src((const TUint8*)string, maxlen); sl@0: TPtr16 awc((TUint16*)&wide, 1); //length of 1 as we only want 1 wide character sl@0: sl@0: TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(awc, src); sl@0: sl@0: //return the number of chars converted which is the max number - the number not converted sl@0: //unless the character converted was the wide null character sl@0: if (ret >= 0) sl@0: { sl@0: return ((L'\0' != wide) ? maxlen - ret : 0); sl@0: } sl@0: else sl@0: return -1; sl@0: sl@0: } sl@0: //shift state would be initialised here if were using them sl@0: return 0; sl@0: } sl@0: }