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

  1. /***
  2. *mbstowcs.c - Convert multibyte char string to wide char string.
  3. *
  4. *       Copyright (c) 1990-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Convert a multibyte char string into the equivalent wide char string.
  8. *
  9. *******************************************************************************/
  10.  
  11.  
  12. #ifndef _MAC
  13. #include <internal.h>
  14. #include <locale.h>
  15. #include <setlocal.h>
  16. #include <errno.h>
  17. #endif  /* _MAC */
  18.  
  19. #include <cruntime.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <mtdll.h>
  23. #include <dbgint.h>
  24.  
  25. #include <stdio.h>
  26.  
  27. /***
  28. *size_t mbstowcs() - Convert multibyte char string to wide char string.
  29. *
  30. *Purpose:
  31. *       Convert a multi-byte char string into the equivalent wide char string,
  32. *       according to the LC_CTYPE category of the current locale.
  33. *       [ANSI].
  34. *
  35. *Entry:
  36. *       wchar_t *pwcs = pointer to destination wide character string buffer
  37. *       const char *s = pointer to source multibyte character string
  38. *       size_t      n = maximum number of wide characters to store
  39. *
  40. *Exit:
  41. *       If s != NULL, returns:  number of words modified (<=n)
  42. *               (size_t)-1 (if invalid mbcs)
  43. *
  44. *Exceptions:
  45. *       Returns (size_t)-1 if s is NULL or invalid mbcs character encountered
  46. *
  47. *******************************************************************************/
  48.  
  49. #ifdef _MT
  50.  
  51. size_t __cdecl mbstowcs
  52. (
  53.         wchar_t  *pwcs,
  54.         const char *s,
  55.         size_t n
  56.         )
  57. {
  58.         size_t retval;
  59.         int local_lock_flag;
  60.  
  61.         _lock_locale( local_lock_flag )
  62.         retval = _mbstowcs_lk(pwcs, s, n);
  63.         _unlock_locale( local_lock_flag )
  64.         return retval;
  65. }
  66. #endif  /* _MT */
  67.  
  68. #ifdef _MT
  69. size_t __cdecl _mbstowcs_lk
  70. #else  /* _MT */
  71. size_t __cdecl mbstowcs
  72. #endif  /* _MT */
  73.         (
  74.         wchar_t  *pwcs,
  75.         const char *s,
  76.         size_t n
  77.         )
  78. {
  79.         size_t count = 0;
  80.  
  81.         if (pwcs && n == 0)
  82.             /* dest string exists, but 0 bytes converted */
  83.             return (size_t) 0;
  84.  
  85.         _ASSERTE(s != NULL);
  86.  
  87. #ifndef _MAC
  88.  
  89.         /* if destination string exists, fill it in */
  90.         if (pwcs)
  91.         {
  92.             if (__lc_handle[LC_CTYPE] == _CLOCALEHANDLE)
  93.             {
  94.                 /* C locale: easy and fast */
  95.                 while (count < n)
  96.                 {
  97.                     *pwcs = (wchar_t) ((unsigned char)s[count]);
  98.                     if (!s[count])
  99.                         return count;
  100.                     count++;
  101.                     pwcs++;
  102.                 }
  103.                 return count;
  104.  
  105.             } else {
  106.                 int bytecnt, charcnt;
  107.                 unsigned char *p;
  108.  
  109.                 /* Assume that the buffer is large enough */
  110.                 if ( (count = MultiByteToWideChar( __lc_codepage,
  111.                                                    MB_PRECOMPOSED |
  112.                                                     MB_ERR_INVALID_CHARS,
  113.                                                    s,
  114.                                                    -1,
  115.                                                    pwcs,
  116.                                                    n )) != 0 )
  117.                     return count - 1; /* don't count NUL */
  118.  
  119.                 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  120.                 {
  121.                     errno = EILSEQ;
  122.                     return (size_t)-1;
  123.                 }
  124.  
  125.                 /* User-supplied buffer not large enough. */
  126.  
  127.                 /* How many bytes are in n characters of the string? */
  128.                 charcnt = n;
  129.                 for (p = (unsigned char *)s; (charcnt-- && *p); p++)
  130.                 {
  131.                     if (isleadbyte(*p))
  132.                         p++;
  133.                 }
  134.                 bytecnt = ((int) ((char *)p - (char *)s));
  135.  
  136.                 if ( (count = MultiByteToWideChar( __lc_codepage,
  137.                                                    MB_PRECOMPOSED,
  138.                                                    s,
  139.                                                    bytecnt,
  140.                                                    pwcs,
  141.                                                    n )) == 0 )
  142.                 {
  143.                     errno = EILSEQ;
  144.                     return (size_t)-1;
  145.                 }
  146.  
  147.                 return count; /* no NUL in string */
  148.             }
  149.         }
  150.         else { /* pwcs == NULL, get size only, s must be NUL-terminated */
  151.             if (__lc_handle[LC_CTYPE] == _CLOCALEHANDLE)
  152.                 return strlen(s);
  153.  
  154.             else {
  155.                 if ( (count = MultiByteToWideChar( __lc_codepage,
  156.                                                    MB_PRECOMPOSED |
  157.                                                     MB_ERR_INVALID_CHARS,
  158.                                                    s,
  159.                                                    -1,
  160.                                                    NULL,
  161.                                                    0 )) == 0 )
  162.                 {
  163.                     errno = EILSEQ;
  164.                     return (size_t)-1;
  165.                 }
  166.  
  167.                 return count - 1;
  168.             }
  169.         }
  170.  
  171. #else  /* _MAC */
  172.  
  173.         /* if destination string exists, fill it in */
  174.         if (pwcs)
  175.         {
  176.             /* C locale: easy and fast */
  177.             while (count < n)
  178.             {
  179.                 *pwcs = (wchar_t) ((unsigned char)s[count]);
  180.                 if (!s[count])
  181.                     return count;
  182.                 count++;
  183.                 pwcs++;
  184.             }
  185.             return count;
  186.  
  187.         } else { /* pwcs == NULL, get size only, s must be NUL-terminated */
  188.             return strlen(s);
  189.         }
  190.  
  191. #endif  /* _MAC */
  192. }
  193.