~mingw-w64/mingw-w64/experimental

« back to all changes in this revision

Viewing changes to ros-privexp/mingw-w64-crt/misc/mbrtowc.c

  • Committer: NightStrike
  • Date: 2010-08-11 22:20:57 UTC
  • Revision ID: svn-v4:4407c894-4637-0410-b4f5-ada5f102cad1:experimental:3266
Branch for adding option for supporting ros

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * This file has no copyright assigned and is placed in the Public Domain.
 
3
 * This file is part of the w64 mingw-runtime package.
 
4
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 
5
 */
 
6
#ifndef WIN32_LEAN_AND_MEAN
 
7
#define WIN32_LEAN_AND_MEAN
 
8
#endif
 
9
#include "mb_wc_common.h"
 
10
#include <wchar.h>
 
11
#include <stdlib.h>
 
12
#include <errno.h>
 
13
#include <windows.h>
 
14
 
 
15
static int __MINGW_ATTRIB_NONNULL(1) __MINGW_ATTRIB_NONNULL(4)
 
16
__mbrtowc_cp (wchar_t * __restrict__ pwc, const char * __restrict__ s,
 
17
              size_t n, mbstate_t* __restrict__ ps,
 
18
              const unsigned int cp, const unsigned int mb_max) 
 
19
{
 
20
  union {
 
21
    mbstate_t val;
 
22
    char mbcs[4];
 
23
  }  shift_state;
 
24
 
 
25
 
 
26
  /* Do the prelim checks */
 
27
  if (s == NULL)
 
28
    return 0;
 
29
 
 
30
  if (n == 0)
 
31
    /* The standard doesn't mention this case explicitly. Tell
 
32
       caller that the conversion from a non-null s is incomplete. */
 
33
    return -2;
 
34
 
 
35
  /* Save the current shift state, in case we need it in DBCS case.  */
 
36
  shift_state.val = *ps;
 
37
  *ps = 0;
 
38
 
 
39
  if (!*s)
 
40
    {
 
41
      *pwc = 0;
 
42
      return 0;
 
43
    }
 
44
 
 
45
  if (mb_max > 1)
 
46
    {
 
47
      if (shift_state.mbcs[0] != 0)
 
48
        {
 
49
          /* Complete the mb char with the trailing byte.  */
 
50
          shift_state.mbcs[1] = *s;  /* the second byte */
 
51
          if (MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS,
 
52
                                  shift_state.mbcs, 2, pwc, 1)
 
53
                 == 0)
 
54
            {
 
55
              /* An invalid trailing byte */     
 
56
              errno = EILSEQ;
 
57
              return -1;
 
58
            }
 
59
          return 2;
 
60
        }
 
61
      else if (IsDBCSLeadByteEx (cp, *s))
 
62
        {
 
63
          /* If told to translate one byte, just save the leadbyte
 
64
             in *ps.  */
 
65
          if (n < 2)
 
66
            {
 
67
              ((char*) ps)[0] = *s; 
 
68
              return -2;
 
69
            }
 
70
          /* Else translate the first two bytes  */  
 
71
          else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS,
 
72
                                        s, 2, pwc, 1)
 
73
                    == 0)
 
74
            {
 
75
              errno = EILSEQ;
 
76
              return -1;
 
77
            }
 
78
          return 2;
 
79
        }
 
80
    }
 
81
 
 
82
  /* Fall through to single byte char  */ 
 
83
  if (cp == 0)
 
84
      *pwc = (wchar_t)(unsigned char)*s;
 
85
 
 
86
  else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, s, 1, pwc, 1)
 
87
            == 0)
 
88
    {
 
89
      errno = EILSEQ;
 
90
      return  -1;
 
91
    }
 
92
  return 1;
 
93
}
 
94
 
 
95
size_t
 
96
mbrtowc (wchar_t * __restrict__ pwc, const char * __restrict__ s,
 
97
         size_t n, mbstate_t* __restrict__ ps)
 
98
{
 
99
  static mbstate_t internal_mbstate = 0;
 
100
  wchar_t  byte_bucket = 0;
 
101
  wchar_t* dst = pwc ? pwc : &byte_bucket;
 
102
 
 
103
  return (size_t) __mbrtowc_cp (dst, s, n, ps ? ps : &internal_mbstate,
 
104
                                get_codepage(), MB_CUR_MAX);
 
105
}
 
106
 
 
107
 
 
108
size_t
 
109
mbsrtowcs (wchar_t* __restrict__ dst,  const char ** __restrict__ src,
 
110
           size_t len, mbstate_t* __restrict__ ps)
 
111
{
 
112
  int ret =0 ;
 
113
  size_t n = 0;
 
114
  static mbstate_t internal_mbstate = 0;
 
115
  mbstate_t* internal_ps = ps ? ps : &internal_mbstate;
 
116
  const unsigned int cp = get_codepage();
 
117
  const unsigned int mb_max = MB_CUR_MAX;
 
118
 
 
119
  if ( src == NULL || *src == NULL )    /* undefined behavior */
 
120
    return 0;
 
121
 
 
122
  if (dst != NULL)
 
123
    {
 
124
      while (n < len
 
125
             && (ret = __mbrtowc_cp(dst, *src, len - n,
 
126
                                    internal_ps, cp, mb_max))
 
127
                  > 0)
 
128
        {
 
129
          ++dst;
 
130
          *src += ret;
 
131
          n += ret;
 
132
        }
 
133
 
 
134
      if (n < len && ret == 0)
 
135
        *src = (char *)NULL;
 
136
    }
 
137
  
 
138
  else
 
139
    {
 
140
      wchar_t byte_bucket = 0;
 
141
      while (n < len
 
142
             && (ret = __mbrtowc_cp (&byte_bucket, *src, mb_max,
 
143
                                     internal_ps, cp, mb_max))
 
144
                  > 0)
 
145
        {
 
146
          *src += ret;
 
147
          n += ret;
 
148
        }
 
149
    }
 
150
  return n;
 
151
}
 
152
 
 
153
size_t
 
154
mbrlen (const char * __restrict__ s, size_t n,
 
155
        mbstate_t * __restrict__ ps)
 
156
{
 
157
  static mbstate_t s_mbstate = 0;
 
158
  wchar_t byte_bucket = 0;
 
159
  return __mbrtowc_cp (&byte_bucket, s, n, (ps) ? ps : &s_mbstate,
 
160
                       get_codepage(), MB_CUR_MAX);
 
161
}