home *** CD-ROM | disk | FTP | other *** search
- /***
- *xstrxfrm.c - Transform a string using locale information
- *
- * Copyright (c) 1996-1998, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- * Transform a string using the locale information as set by
- * LC_COLLATE.
- *
- *Revision History:
- * 01-XX-96 PJP Created from strxfrm.c January 1996 by P.J. Plauger
- * 04-18-96 GJF Updated for current locale locking. Also, reformatted
- * and made several cosmetic changes.
- * 03-17-97 RDK Added error flag to __crtLCMapStringA.
- * 12-02-97 GJF Removed bogus codepage determination.
- * 01-12-98 GJF Use _lc_collate_cp codepage.
- *
- *******************************************************************************/
-
- #include <cruntime.h>
- #include <string.h>
- #include <xlocinfo.h> /* for _Collvec, _Strxfrm */
-
- #ifdef _WIN32
- #include <windows.h>
- #include <stdlib.h>
- #include <limits.h>
- #include <malloc.h>
- #include <locale.h>
- #include <setlocal.h>
- #include <awint.h>
- #include <mtdll.h>
- #endif /* _WIN32 */
-
- /* Define _CRTIMP2 */
- #ifndef _CRTIMP2
- #ifdef CRTDLL2
- #define _CRTIMP2 __declspec(dllexport)
- #else /* ndef CRTDLL2 */
- #ifdef _DLL
- #define _CRTIMP2 __declspec(dllimport)
- #else /* ndef _DLL */
- #define _CRTIMP2
- #endif /* _DLL */
- #endif /* CRTDLL2 */
- #endif /* _CRTIMP2 */
-
- /***
- *size_t _Strxfrm() - Transform a string using locale information
- *
- *Purpose:
- * Transform the string pointer to by _string2 and place the
- * resulting string into the array pointer to by _string1.
- * No more than _end1 - _string1 characters are place into the
- * resulting string (including the null).
- *
- * The transformation is such that if strcmp() is applied to
- * the two transformed strings, the return value is equal to
- * the result of strcoll() applied to the two original strings.
- * Thus, the conversion must take the locale LC_COLLATE info
- * into account.
- * [ANSI]
- *
- * The value of the following expression is the size of the array
- * needed to hold the transformation of the source string:
- *
- * 1 + strxfrm(NULL,string,0)
- *
- * NOTE: Currently, the C libraries support the "C" locale only.
- * Thus, _Strxfrm() simply resolves to strncpy()/strlen().
- *
- *Entry:
- * char *_string1 = pointer to beginning of result string
- * char *_end1 = pointer past end of result string
- * const char *_string2 = pointer to beginning of source string
- * const char *_end2 = pointer past end of source string
- * const _Collvec *ploc = pointer to locale info
- *
- *Exit:
- * Length of the transformed string.
- * If the value returned is too big, the contents of the
- * _string1 array are indeterminate.
- *
- *Exceptions:
- * Non-standard: if OM/API error, return INT_MAX.
- *
- *******************************************************************************/
-
- _CRTIMP2 size_t __cdecl _Strxfrm (
- char *_string1,
- char *_end1,
- const char *_string2,
- const char *_end2,
- const _Collvec *ploc
- )
- {
- size_t _n1 = _end1 - _string1;
- size_t _n2 = _end2 - _string2;
- #ifdef _WIN32
- int dstlen;
- int retval = INT_MAX; /* NON-ANSI: default if OM or API error */
- LCID handle;
- UINT codepage;
- #ifdef _MT
- int local_lock_flag;
-
- _lock_locale( local_lock_flag )
- #endif
-
- if (ploc == 0)
- {
- handle = __lc_handle[LC_COLLATE];
- codepage = __lc_collate_cp;
- }
- else
- {
- handle = ploc->_Hand;
- codepage = ploc->_Page;
- }
-
- if ((handle == _CLOCALEHANDLE) &&
- (codepage == _CLOCALECP))
- {
- _unlock_locale( local_lock_flag )
- #endif /* _WIN32 */
- if (_n2 <= _n1)
- memcpy(_string1, _string2, _n2);
- return _n2;
- #ifdef _WIN32
- }
-
- /* Inquire size of dst string in BYTES */
- if (0 == (dstlen = __crtLCMapStringA(handle,
- LCMAP_SORTKEY,
- _string2,
- _n2,
- NULL,
- 0,
- codepage,
- TRUE)))
- goto error_cleanup;
-
- retval = dstlen;
-
- /* if not enough room, return amount needed */
- if (dstlen > (int)(_n1))
- goto error_cleanup;
-
- /* Map src string to dst string */
- if (0 == __crtLCMapStringA(handle,
- LCMAP_SORTKEY,
- _string2,
- _n2,
- _string1,
- _n1,
- codepage,
- TRUE))
- goto error_cleanup;
-
- error_cleanup:
- _unlock_locale( local_lock_flag )
- return (size_t)retval;
- #endif /* _WIN32 */
- }
-