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

  1. /***
  2. *inithelp.c - Contains the __getlocaleinfo helper routine
  3. *
  4. *       Copyright (c) 1992-1997, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *  Contains the __getlocaleinfo helper routine.
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <stdlib.h>
  12. #include <cruntime.h>
  13. #include <locale.h>
  14. #include <setlocal.h>
  15. #include <awint.h>
  16. #include <dbgint.h>
  17.  
  18. /***
  19. *__getlocaleinfo - return locale data
  20. *
  21. *Purpose:
  22. *       Return locale data appropriate for the setlocale init functions.
  23. *       In particular, wide locale strings are converted to char strings
  24. *       or numeric depending on the value of the first parameter.
  25. *
  26. *       Memory is allocated for the char version of the data, and the
  27. *       calling function's pointer is set to it.  This pointer should later
  28. *       be used to free the data.  The wide-char data is fetched using
  29. *       GetLocaleInfo and converted to multibyte using WideCharToMultiByte.
  30. *
  31. *       *** For internal use by the __init_* functions only ***
  32. *
  33. *       *** Future optimization ***
  34. *       When converting a large number of wide-strings to multibyte, do
  35. *       not query the size of the result, but convert them one after
  36. *       another into a large character buffer.  The entire buffer can
  37. *       also be freed with one pointer.
  38. *
  39. *Entry:
  40. *       int lc_type - LC_STR_TYPE for string data, LC_INT_TYPE for numeric data
  41. *       LCID localehandle - LCID based on category and lang or ctry of __lc_id
  42. *       LCTYPE fieldtype - int or string value
  43. *       void *address - cast to either char * or char**
  44. *
  45. *Exit:
  46. *        0  success
  47. *       -1  failure
  48. *
  49. *Exceptions:
  50. *
  51. *******************************************************************************/
  52.  
  53. #if NO_ERROR == -1
  54. #error Need to use another error return code in __getlocaleinfo
  55. #endif  /* NO_ERROR == -1 */
  56.  
  57. #define STR_CHAR_CNT    128
  58. #define INT_CHAR_CNT    4
  59.  
  60. int __cdecl __getlocaleinfo (
  61.         int lc_type,
  62.         LCID localehandle,
  63.         LCTYPE fieldtype,
  64.         void *address
  65.         )
  66. {
  67.         if (lc_type == LC_STR_TYPE)
  68.         {
  69.             char **straddress = (char **)address;
  70.             unsigned char cbuffer[STR_CHAR_CNT];
  71.             unsigned char *pcbuffer = cbuffer;
  72.             int bufferused = 0; /* 1 indicates buffer points to malloc'ed memory */
  73.             int buffersize = STR_CHAR_CNT;
  74.             int outsize;
  75.  
  76.             if ((outsize = __crtGetLocaleInfoA(localehandle, fieldtype, pcbuffer, buffersize, 0))
  77.                 == 0)
  78.             {
  79.                 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  80.                     goto error;
  81.  
  82.                 /* buffersize too small, get required size and malloc new buffer */
  83.  
  84.                 if ((buffersize = __crtGetLocaleInfoA (localehandle, fieldtype, NULL, 0, 0))
  85.                     == 0)
  86.                     goto error;
  87.  
  88.                 if ((pcbuffer = (unsigned char *) _malloc_crt (buffersize * sizeof(unsigned char)))
  89.                     == NULL)
  90.                     goto error;
  91.  
  92.                 bufferused = 1;
  93.  
  94.                 if ((outsize = __crtGetLocaleInfoA (localehandle, fieldtype, pcbuffer, buffersize, 0))
  95.                     == 0)
  96.                     goto error;
  97.             }
  98.  
  99.             if ((*straddress = (char *) _malloc_crt (outsize * sizeof(char))) == NULL)
  100.                 goto error;
  101.  
  102.             strncpy(*straddress, pcbuffer, outsize);
  103.  
  104.             if (bufferused)
  105.                 _free_crt (pcbuffer);
  106.  
  107.             return 0;
  108.  
  109. error:
  110.             if (bufferused)
  111.                 _free_crt (pcbuffer);
  112.             return -1;
  113.  
  114.         } else if (lc_type == LC_INT_TYPE)
  115.         {
  116.             int i;
  117.             char c;
  118.             static wchar_t wcbuffer[INT_CHAR_CNT];
  119.             const int buffersize = INT_CHAR_CNT;
  120.             char *charaddress = (char *)address;
  121.  
  122.             if (__crtGetLocaleInfoW (localehandle, fieldtype, (LPWSTR)&wcbuffer, buffersize, 0) == 0)
  123.                 return -1;
  124.  
  125.             *(char *)charaddress = 0;
  126.  
  127.             /* assume GetLocaleInfoW returns valid ASCII integer in wcstr format */
  128.             for (i = 0; i < INT_CHAR_CNT; i++)
  129.             {
  130.                 if (isdigit(((unsigned char)c = (unsigned char)wcbuffer[i])))
  131.                     *(unsigned char *)charaddress = (unsigned char)(10 * (int)(*charaddress) + (c - '0'));
  132.                 else
  133.                     break;
  134.             }
  135.             return 0;
  136.         }
  137.         return -1;
  138. }
  139.