/*** *wcsxfrm.c - Transform a wide-character string using locale information * * Copyright (c) 1988-2001, Microsoft Corporation. All rights reserved. * *Purpose: * Transform a wide-character string using the locale information as set by * LC_COLLATE. * *Revision History: * 09-09-91 ETC Created from strxfrm.c. * 12-09-91 ETC Updated api; Added multithread lock. * 12-18-91 ETC Changed back LCMAP_SORTKEYA --> LCMAP_SORTKEY. * 04-06-92 KRS Fix so it works without _INTL too. * 08-19-92 KRS Activate use of NLS API. * 09-02-92 SRW Get _INTL definition via ..\crt32.def * 12-15-92 KRS Fix return value to match ANSI/ISO Std. * 04-06-93 SKS Replace _CRTAPI* with __cdecl * 09-15-93 CFW Use ANSI conformant "__" names. * 09-22-93 CFW Use __crtxxx internal NLS API wrapper. * 09-23-93 CFW Complete re-write. Non-C locale totally broken. * 11-09-93 CFW Use LC_COLLATE code page for __crtxxx() conversion. * 02-07-94 CFW POSIXify. * 09-06-94 CFW Remove _INTL switch. * 10-25-94 GJF Sped up C locale, multi-thread case. * 01-10-95 CFW Debug CRT allocs. * 09-26-95 GJF New locking macro, and scheme, for functions which * reference the locale. * 10-11-95 BWT Fix NTSUBSET * 11-24-97 GJF Removed bogus codepage determination. * 01-12-98 GJF Use _lc_collate_cp codepage. * 07-16-98 GJF Revised multithread support based on threadlocinfo * struct. Also, use _alloca instead of _malloc_crt if * possible. * 01-04-99 GJF Changes for 64-bit size_t. * 04-30-99 PML Minor cleanup as part of 64-bit merge. * 12-10-99 GB Added support for recovery from stack overflow around * _alloca(). * 10-12-00 GB Changed the function to be similar to strxfrm() * *******************************************************************************/ #ifndef _POSIX_ #include #include #include #include #include #include #include #include #include #include #include /*** *size_t wcsxfrm() - Transform a string using locale information * *Purpose: * Transform the wide string pointed to by _string2 and place the * resulting wide string into the array pointed to by _string1. * No more than _count wide characters are placed into the * resulting string (including the null). * * The transformation is such that if wcscmp() is applied to * the two transformed strings, the return value is equal to * the result of wcscoll() applied to the two original strings. * Thus, the conversion must take the locale LC_COLLATE info * into account. * * In the C locale, wcsxfrm() simply resolves to wcsncpy()/wcslen(). * *Entry: * wchar_t *_string1 = result string * const wchar_t *_string2 = source string * size_t _count = max wide chars to move * * [If _count is 0, _string1 is permitted to be NULL.] * *Exit: * Length of the transformed string (not including the terminating * null). If the value returned is >= _count, the contents of the * _string1 array are indeterminate. * *Exceptions: * Non-standard: if OM/API error, return INT_MAX. * *******************************************************************************/ size_t __cdecl wcsxfrm ( wchar_t *_string1, const wchar_t *_string2, size_t _count ) { #ifdef _NTSUBSET_ if (_string1) wcsncpy(_string1, _string2, _count); return wcslen(_string2); #else int size = INT_MAX; #ifdef _MT pthreadlocinfo ptloci; #endif if ( _count > INT_MAX ) return (size_t)size; #ifdef _MT ptloci = _getptd()->ptlocinfo; if ( ptloci != __ptlocinfo ) ptloci = __updatetlocinfo(); if ( ptloci->lc_handle[LC_COLLATE] == _CLOCALEHANDLE ) #else if ( __lc_handle[LC_COLLATE] == _CLOCALEHANDLE ) #endif { wcsncpy(_string1, _string2, _count); return wcslen(_string2); } #ifdef _MT if ( 0 == (size = __crtLCMapStringW( ptloci->lc_handle[LC_COLLATE], #else if ( 0 == (size = __crtLCMapStringW( __lc_handle[LC_COLLATE], #endif LCMAP_SORTKEY, _string2, -1, NULL, 0, #ifdef _MT ptloci->lc_collate_cp )) ) #else __lc_collate_cp )) ) #endif { size = INT_MAX; } else { if ( (size_t)size <= _count) { #ifdef _MT if ( 0 == (size = __crtLCMapStringW( ptloci->lc_handle[LC_COLLATE], #else if ( 0 == (size = __crtLCMapStringW( __lc_handle[LC_COLLATE], #endif LCMAP_SORTKEY, _string2, -1, (wchar_t *)_string1, (int)_count, #ifdef _MT ptloci->lc_collate_cp )) ) #else __lc_collate_cp )) ) #endif { size = INT_MAX; /* default error */ } else { // Note that the size that LCMapStringW returns for // LCMAP_SORTKEY is number of bytes needed. That's why it // is safe to convert the buffer to wide char from end. _count = size--; for (;_count-- > 0;) { _string1[_count] = (wchar_t)((unsigned char *)_string1)[_count]; } } } else { size--; } } return (size_t)size; #endif /* _NTSUBSET_ */ } #endif /* _POSIX_ */