home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / strxfrm.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  4KB  |  132 lines

  1. /***
  2. *strxfrm.c - Transform a string using locale information
  3. *
  4. *       Copyright (c) 1988-1998, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Transform a string using the locale information as set by
  8. *       LC_COLLATE.
  9. *
  10. *******************************************************************************/
  11.  
  12. #include <cruntime.h>
  13. #include <string.h>
  14.  
  15. #ifdef _WIN32
  16. #include <windows.h>
  17. #include <stdlib.h>
  18. #include <limits.h>
  19. #include <malloc.h>
  20. #include <locale.h>
  21. #include <setlocal.h>
  22. #include <awint.h>
  23. #include <mtdll.h>
  24. #endif  /* _WIN32 */
  25.  
  26. /***
  27. *size_t strxfrm() - Transform a string using locale information
  28. *
  29. *Purpose:
  30. *       Transform the string pointer to by _string2 and place the
  31. *       resulting string into the array pointer to by _string1.
  32. *       No more than _count characters are place into the
  33. *       resulting string (including the null).
  34. *
  35. *       The transformation is such that if strcmp() is applied to
  36. *       the two transformed strings, the return value is equal to
  37. *       the result of strcoll() applied to the two original strings.
  38. *       Thus, the conversion must take the locale LC_COLLATE info
  39. *       into account.
  40. *       [ANSI]
  41. *
  42. *       The value of the following expression is the size of the array
  43. *       needed to hold the transformation of the source string:
  44. *
  45. *           1 + strxfrm(NULL,string,0)
  46. *
  47. *       NOTE:  Currently, the C libraries support the "C" locale only.
  48. *       Thus, strxfrm() simply resolves to strncpy()/strlen().
  49. *
  50. *Entry:
  51. *       char *_string1       = result string
  52. *       const char *_string2 = source string
  53. *       size_t _count        = max chars to move
  54. *
  55. *       [If _count is 0, _string1 is permitted to be NULL.]
  56. *
  57. *Exit:
  58. *       Length of the transformed string (not including the terminating
  59. *       null).  If the value returned is >= _count, the contents of the
  60. *       _string1 array are indeterminate.
  61. *
  62. *Exceptions:
  63. *       Non-standard: if OM/API error, return INT_MAX.
  64. *
  65. *******************************************************************************/
  66.  
  67. size_t __cdecl strxfrm (
  68.         char *_string1,
  69.         const char *_string2,
  70.         size_t _count
  71.         )
  72. {
  73. #ifdef _WIN32
  74.         int dstlen;
  75.         int retval = INT_MAX;   /* NON-ANSI: default if OM or API error */
  76. #if defined (_MT)
  77.         int local_lock_flag;
  78. #endif  /* defined (_MT) */
  79.  
  80.         if ((__lc_handle[LC_COLLATE] == _CLOCALEHANDLE) &&
  81.             (__lc_codepage == _CLOCALECP)) {
  82. #endif  /* _WIN32 */
  83.             strncpy(_string1, _string2, _count);
  84.             return strlen(_string2);
  85. #ifdef _WIN32
  86.         }
  87.  
  88.         _lock_locale( local_lock_flag )
  89.  
  90. #if defined (_MT)
  91.         if ((__lc_handle[LC_COLLATE] == _CLOCALEHANDLE) &&
  92.             (__lc_codepage == _CLOCALECP)) {
  93.             _unlock_locale( local_lock_flag )
  94.             strncpy(_string1, _string2, _count);
  95.             return strlen(_string2);
  96.         }
  97. #endif  /* defined (_MT) */
  98.  
  99.         /* Inquire size of dst string in BYTES */
  100.         if ( 0 == (dstlen = __crtLCMapStringA( __lc_handle[LC_COLLATE],
  101.                                                LCMAP_SORTKEY,
  102.                                                _string2,
  103.                                                -1,
  104.                                                NULL,
  105.                                                0,
  106.                                                __lc_collate_cp,
  107.                                                TRUE )) )
  108.             goto error_cleanup;
  109.  
  110.         retval = dstlen;
  111.  
  112.         /* if not enough room, return amount needed */
  113.         if (dstlen > (int)_count)
  114.             goto error_cleanup;
  115.  
  116.         /* Map src string to dst string */
  117.         if ( 0 == __crtLCMapStringA( __lc_handle[LC_COLLATE],
  118.                                      LCMAP_SORTKEY,
  119.                                      _string2,
  120.                                      -1,
  121.                                      _string1,
  122.                                      _count,
  123.                                      __lc_collate_cp,
  124.                                      TRUE ) )
  125.             goto error_cleanup;
  126.  
  127. error_cleanup:
  128.         _unlock_locale( local_lock_flag )
  129.         return (size_t)retval;
  130. #endif  /* _WIN32 */
  131. }
  132.