]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.3.3/config/locale/generic/codecvt_members.cc
Inital import
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.3.3 / config / locale / generic / codecvt_members.cc
1 // std::codecvt implementation details, generic version -*- C++ -*-
2
3 // Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 //
32 // ISO C++ 14882: 22.2.1.5 - Template class codecvt
33 //
34
35 // Written by Benjamin Kosnik <bkoz@redhat.com>
36
37 #include <locale>
38 #include <cstdlib>  // For MB_CUR_MAX
39 #include <climits>  // For MB_LEN_MAX
40 #include <cstring>
41
42 _GLIBCXX_BEGIN_NAMESPACE(std)
43
44   // Specializations.
45 #ifdef _GLIBCXX_USE_WCHAR_T
46   codecvt_base::result
47   codecvt<wchar_t, char, mbstate_t>::
48   do_out(state_type& __state, const intern_type* __from, 
49          const intern_type* __from_end, const intern_type*& __from_next,
50          extern_type* __to, extern_type* __to_end,
51          extern_type*& __to_next) const
52   {
53     result __ret = ok;
54     // The conversion must be done using a temporary destination buffer
55     // since it is not possible to pass the size of the buffer to wcrtomb
56     state_type __tmp_state(__state);
57
58     // The conversion must be done by calling wcrtomb in a loop rather
59     // than using wcsrtombs because wcsrtombs assumes that the input is
60     // zero-terminated.
61
62     // Either we can upper bound the total number of external characters to
63     // something smaller than __to_end - __to or the conversion must be done
64     // using a temporary destination buffer since it is not possible to
65     // pass the size of the buffer to wcrtomb
66     if (MB_CUR_MAX * (__from_end - __from) - (__to_end - __to) <= 0)
67       while (__from < __from_end)
68         {
69           const size_t __conv = wcrtomb(__to, *__from, &__tmp_state);
70           if (__conv == static_cast<size_t>(-1))
71             {
72               __ret = error;
73               break;
74             }
75           __state = __tmp_state;
76           __to += __conv;
77           __from++;
78         }
79     else
80       {
81         extern_type __buf[MB_LEN_MAX];
82         while (__from < __from_end && __to < __to_end)
83           {
84             const size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
85             if (__conv == static_cast<size_t>(-1))
86               {
87                 __ret = error;
88                 break;
89               }
90             else if (__conv > static_cast<size_t>(__to_end - __to))
91               {
92                 __ret = partial;
93                 break;
94               }
95             
96             memcpy(__to, __buf, __conv);
97             __state = __tmp_state;
98             __to += __conv;
99             __from++;
100           }
101       }
102
103     if (__ret == ok && __from < __from_end)
104       __ret = partial;
105
106     __from_next = __from;
107     __to_next = __to;
108     return __ret; 
109   }
110   
111   codecvt_base::result
112   codecvt<wchar_t, char, mbstate_t>::
113   do_in(state_type& __state, const extern_type* __from, 
114         const extern_type* __from_end, const extern_type*& __from_next,
115         intern_type* __to, intern_type* __to_end,
116         intern_type*& __to_next) const
117   {
118     result __ret = ok;
119     // This temporary state object is neccessary so __state won't be modified
120     // if [__from, __from_end) is a partial multibyte character.
121     state_type __tmp_state(__state);
122
123     // Conversion must be done by calling mbrtowc in a loop rather than
124     // by calling mbsrtowcs because mbsrtowcs assumes that the input
125     // sequence is zero-terminated.
126     while (__from < __from_end && __to < __to_end)
127       {
128         size_t __conv = mbrtowc(__to, __from, __from_end - __from,
129                                 &__tmp_state);
130         if (__conv == static_cast<size_t>(-1))
131           {
132             __ret = error;
133             break;
134           }
135         else if (__conv == static_cast<size_t>(-2))
136           {
137             // It is unclear what to return in this case (see DR 382).
138             __ret = partial;
139             break;
140           }
141         else if (__conv == 0)
142           {
143             // XXX Probably wrong for stateful encodings
144             __conv = 1;
145             *__to = L'\0';
146           }
147
148         __state = __tmp_state;
149         __to++;
150         __from += __conv;
151       }
152
153     // It is not clear that __from < __from_end implies __ret != ok
154     // (see DR 382).
155     if (__ret == ok && __from < __from_end)
156       __ret = partial;
157
158     __from_next = __from;
159     __to_next = __to;
160     return __ret; 
161   }
162
163   int 
164   codecvt<wchar_t, char, mbstate_t>::
165   do_encoding() const throw()
166   {
167     // XXX This implementation assumes that the encoding is
168     // stateless and is either single-byte or variable-width.
169     int __ret = 0;
170     if (MB_CUR_MAX == 1)
171       __ret = 1;
172     return __ret;
173   }  
174
175   int 
176   codecvt<wchar_t, char, mbstate_t>::
177   do_max_length() const throw()
178   {
179     // XXX Probably wrong for stateful encodings.
180     int __ret = MB_CUR_MAX;
181     return __ret;
182   }
183   
184   int 
185   codecvt<wchar_t, char, mbstate_t>::
186   do_length(state_type& __state, const extern_type* __from,
187             const extern_type* __end, size_t __max) const
188   {
189     int __ret = 0;
190     state_type __tmp_state(__state);
191
192     while (__from < __end && __max)
193       {
194         size_t __conv = mbrtowc(NULL, __from, __end - __from, &__tmp_state);
195         if (__conv == static_cast<size_t>(-1))
196           {
197             // Invalid source character
198             break;
199           }
200         else if (__conv == static_cast<size_t>(-2))
201           {
202             // Remainder of input does not form a complete destination
203             // character.
204             break;
205           }
206         else if (__conv == 0)
207           {
208             // XXX Probably wrong for stateful encodings
209             __conv = 1;
210           }
211
212         __state = __tmp_state;
213         __from += __conv;
214         __ret += __conv;
215         __max--;
216       }
217
218     return __ret; 
219   }
220 #endif
221
222 _GLIBCXX_END_NAMESPACE