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

  1. /***
  2. *a_str.c - A version of GetStringType.
  3. *
  4. *       Copyright (c) 1993-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Use either GetStringTypeA or GetStringTypeW depending on which is
  8. *       unstubbed.
  9. *
  10. *******************************************************************************/
  11.  
  12. #include <cruntime.h>
  13. #include <internal.h>
  14. #include <stdlib.h>
  15. #include <setlocal.h>
  16. #include <locale.h>
  17. #include <awint.h>
  18. #include <dbgint.h>
  19.  
  20. #define USE_W   1
  21. #define USE_A   2
  22.  
  23. /***
  24. *int __cdecl __crtGetStringTypeA - Get type information about an ANSI string.
  25. *
  26. *Purpose:
  27. *       Internal support function. Assumes info in ANSI string format. Tries
  28. *       to use NLS API call GetStringTypeA if available and uses GetStringTypeW
  29. *       if it must. If neither are available it fails and returns FALSE.
  30. *
  31. *Entry:
  32. *       DWORD    dwInfoType  - see NT\Chicago docs
  33. *       LPCSTR   lpSrcStr    - char (byte) string for which character types
  34. *                              are requested
  35. *       int      cchSrc      - char (byte) count of lpSrcStr (including NULL
  36. *                              if any)
  37. *       LPWORD   lpCharType  - word array to receive character type information
  38. *                              (must be twice the size of lpSrcStr)
  39. *       int      code_page   - for MB/WC conversion. If 0, use __lc_codepage
  40. *       int      lcid        - for A call, specify LCID, If 0, use
  41. *                              __lc_handle[LC_CTYPE].
  42. *       BOOL     bError      - TRUE if MB_ERR_INVALID_CHARS set on call to
  43. *                              MultiByteToWideChar when GetStringTypeW used.
  44. *
  45. *Exit:
  46. *       Success: TRUE
  47. *       Failure: FALSE
  48. *
  49. *Exceptions:
  50. *
  51. *******************************************************************************/
  52.  
  53. BOOL __cdecl __crtGetStringTypeA(
  54.         DWORD    dwInfoType,
  55.         LPCSTR   lpSrcStr,
  56.         int      cchSrc,
  57.         LPWORD   lpCharType,
  58.         int      code_page,
  59.         int      lcid,
  60.         BOOL     bError
  61.         )
  62. {
  63.         static int f_use = 0;
  64.  
  65.         /*
  66.          * Look for unstubbed 'preferred' flavor. Otherwise use available
  67.          * flavor. Must actually call the function to ensure it's not a stub.
  68.          * (Always try wide version first so WinNT can process codepage correctly.)
  69.          */
  70.  
  71.         if (0 == f_use)
  72.         {
  73.             unsigned short dummy;
  74.  
  75.             if (0 != GetStringTypeW(CT_CTYPE1, L"\0", 1, &dummy))
  76.                 f_use = USE_W;
  77.  
  78.             else if (0 != GetStringTypeA(0, CT_CTYPE1, "\0", 1, &dummy))
  79.                 f_use = USE_A;
  80.  
  81.             else
  82.                 return FALSE;
  83.         }
  84.  
  85.         /* Use "A" version */
  86.  
  87.         if (USE_A == f_use)
  88.         {
  89.             if (0 == lcid)
  90.                 lcid = __lc_handle[LC_CTYPE];
  91.  
  92.             return GetStringTypeA(lcid, dwInfoType, lpSrcStr, cchSrc, lpCharType);
  93.         }
  94.  
  95.         /* Use "W" version */
  96.  
  97.         if (USE_W == f_use)
  98.         {
  99.             int retval;
  100.             int buff_size;
  101.             wchar_t *wbuffer;
  102.  
  103.             /*
  104.              * Convert string and return the requested information. Note that
  105.              * we are converting to a wide character string so there is not a
  106.              * one-to-one correspondence between number of multibyte chars in the
  107.              * input string and the number of wide chars in the buffer. However,
  108.              * there had *better be* a one-to-one correspondence between the
  109.              * number of multibyte characters and the number of WORDs in the
  110.              * return buffer.
  111.              */
  112.  
  113.             /*
  114.              * Use __lc_codepage for conversion if code_page not specified
  115.              */
  116.  
  117.             if (0 == code_page)
  118.                 code_page = __lc_codepage;
  119.  
  120.             /* find out how big a buffer we need */
  121.             if ( 0 == (buff_size = MultiByteToWideChar( code_page,
  122.                                                         bError ?
  123.                                                             MB_PRECOMPOSED |
  124.                                                             MB_ERR_INVALID_CHARS
  125.                                                             : MB_PRECOMPOSED,
  126.                                                         lpSrcStr,
  127.                                                         cchSrc,
  128.                                                         NULL,
  129.                                                         0 )) )
  130.                 return FALSE;
  131.  
  132.             /* allocate enough space for wide chars */
  133.             __try {
  134.                 wbuffer = (wchar_t *)_alloca( sizeof(wchar_t) * buff_size );
  135.                 (void)memset( wbuffer, 0, sizeof(wchar_t) * buff_size );
  136.             }
  137.             __except( EXCEPTION_EXECUTE_HANDLER ) {
  138.                 wbuffer = NULL;
  139.             }
  140.  
  141.             if ( wbuffer == NULL )
  142.                 return FALSE;
  143.  
  144.             /* do the conversion */
  145.             if ( 0 == (retval = MultiByteToWideChar( code_page,
  146.                                                      MB_PRECOMPOSED,
  147.                                                      lpSrcStr,
  148.                                                      cchSrc,
  149.                                                      wbuffer,
  150.                                                      buff_size )) )
  151.                 return FALSE;
  152.  
  153.             /* obtain result */
  154.             return GetStringTypeW(dwInfoType, wbuffer, retval, lpCharType);
  155.         }
  156.         else   /* f_use is neither USE_A nor USE_W */
  157.             return FALSE;
  158. }
  159.