windows-nt/Source/XPSP1/NT/base/crts/crtw32/string/wcsxfrm.c

175 lines
5.8 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/***
*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 <cruntime.h>
#include <windows.h>
#include <string.h>
#include <limits.h>
#include <locale.h>
#include <setlocal.h>
#include <stdlib.h>
#include <mtdll.h>
#include <awint.h>
#include <dbgint.h>
#include <malloc.h>
/***
*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 */
}
}
}
return (size_t)size;
#endif /* _NTSUBSET_ */
}
#endif /* _POSIX_ */