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

  1. /***
  2. *xstrxfrm.c - Transform a string using locale information
  3. *
  4. *       Copyright (c) 1996-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. *Revision History:
  11. *       01-XX-96  PJP   Created from strxfrm.c January 1996 by P.J. Plauger
  12. *       04-18-96  GJF   Updated for current locale locking. Also, reformatted
  13. *                       and made several cosmetic changes.
  14. *       03-17-97  RDK   Added error flag to __crtLCMapStringA.
  15. *       12-02-97  GJF   Removed bogus codepage determination.
  16. *       01-12-98  GJF   Use _lc_collate_cp codepage.
  17. *
  18. *******************************************************************************/
  19.  
  20. #include <cruntime.h>
  21. #include <string.h>
  22. #include <xlocinfo.h>   /* for _Collvec, _Strxfrm */
  23.  
  24. #ifdef  _WIN32
  25. #include <windows.h>
  26. #include <stdlib.h>
  27. #include <limits.h>
  28. #include <malloc.h>
  29. #include <locale.h>
  30. #include <setlocal.h>
  31. #include <awint.h>
  32. #include <mtdll.h>
  33. #endif  /* _WIN32 */
  34.  
  35. /* Define _CRTIMP2 */
  36. #ifndef _CRTIMP2
  37. #ifdef  CRTDLL2
  38. #define _CRTIMP2 __declspec(dllexport)
  39. #else   /* ndef CRTDLL2 */
  40. #ifdef  _DLL
  41. #define _CRTIMP2 __declspec(dllimport)
  42. #else   /* ndef _DLL */
  43. #define _CRTIMP2
  44. #endif  /* _DLL */
  45. #endif  /* CRTDLL2 */
  46. #endif  /* _CRTIMP2 */
  47.  
  48. /***
  49. *size_t _Strxfrm() - Transform a string using locale information
  50. *
  51. *Purpose:
  52. *       Transform the string pointer to by _string2 and place the
  53. *       resulting string into the array pointer to by _string1.
  54. *       No more than _end1 - _string1 characters are place into the
  55. *       resulting string (including the null).
  56. *
  57. *       The transformation is such that if strcmp() is applied to
  58. *       the two transformed strings, the return value is equal to
  59. *       the result of strcoll() applied to the two original strings.
  60. *       Thus, the conversion must take the locale LC_COLLATE info
  61. *       into account.
  62. *       [ANSI]
  63. *
  64. *       The value of the following expression is the size of the array
  65. *       needed to hold the transformation of the source string:
  66. *
  67. *               1 + strxfrm(NULL,string,0)
  68. *
  69. *       NOTE:  Currently, the C libraries support the "C" locale only.
  70. *       Thus, _Strxfrm() simply resolves to strncpy()/strlen().
  71. *
  72. *Entry:
  73. *       char *_string1       = pointer to beginning of result string
  74. *       char *_end1          = pointer past end of result string
  75. *       const char *_string2 = pointer to beginning of source string
  76. *       const char *_end2    = pointer past end of source string
  77. *       const _Collvec *ploc = pointer to locale info
  78. *
  79. *Exit:
  80. *       Length of the transformed string.
  81. *       If the value returned is too big, the contents of the
  82. *       _string1 array are indeterminate.
  83. *
  84. *Exceptions:
  85. *       Non-standard: if OM/API error, return INT_MAX.
  86. *
  87. *******************************************************************************/
  88.  
  89. _CRTIMP2 size_t __cdecl _Strxfrm (
  90.         char *_string1,
  91.         char *_end1,
  92.         const char *_string2,
  93.         const char *_end2,
  94.         const _Collvec *ploc
  95.         )
  96. {
  97.         size_t _n1 = _end1 - _string1;
  98.         size_t _n2 = _end2 - _string2;
  99. #ifdef  _WIN32
  100.         int dstlen;
  101.         int retval = INT_MAX;   /* NON-ANSI: default if OM or API error */
  102.         LCID handle;
  103.         UINT codepage;
  104. #ifdef  _MT
  105.         int local_lock_flag;
  106.  
  107.         _lock_locale( local_lock_flag )
  108. #endif
  109.  
  110.         if (ploc == 0)
  111.         {
  112.             handle = __lc_handle[LC_COLLATE];
  113.             codepage = __lc_collate_cp;
  114.         }
  115.         else
  116.         {
  117.             handle = ploc->_Hand;
  118.             codepage = ploc->_Page;
  119.         }
  120.  
  121.         if ((handle == _CLOCALEHANDLE) &&
  122.             (codepage == _CLOCALECP)) 
  123.         {
  124.             _unlock_locale( local_lock_flag )
  125. #endif  /* _WIN32 */
  126.             if (_n2 <= _n1)
  127.                 memcpy(_string1, _string2, _n2);
  128.             return _n2;
  129. #ifdef  _WIN32
  130.         }
  131.  
  132.         /* Inquire size of dst string in BYTES */
  133.         if (0 == (dstlen = __crtLCMapStringA(handle,
  134.                                              LCMAP_SORTKEY, 
  135.                                              _string2, 
  136.                                              _n2, 
  137.                                              NULL, 
  138.                                              0, 
  139.                                              codepage,
  140.                                              TRUE)))
  141.                 goto error_cleanup;
  142.  
  143.         retval = dstlen;
  144.  
  145.         /* if not enough room, return amount needed */
  146.         if (dstlen > (int)(_n1))
  147.             goto error_cleanup;
  148.  
  149.         /* Map src string to dst string */
  150.         if (0 == __crtLCMapStringA(handle,
  151.                                    LCMAP_SORTKEY, 
  152.                                    _string2, 
  153.                                    _n2, 
  154.                                    _string1, 
  155.                                    _n1, 
  156.                                    codepage,
  157.                                    TRUE))
  158.             goto error_cleanup;
  159.  
  160. error_cleanup:
  161.         _unlock_locale( local_lock_flag )
  162.         return (size_t)retval;
  163. #endif  /* _WIN32 */
  164. }
  165.