]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/locale/src/encoding/iconv_codepage.ipp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / locale / src / encoding / iconv_codepage.ipp
1 //
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
9 #define BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
10
11 #include <boost/locale/encoding.hpp>
12 #include "../util/iconv.hpp"
13 #include <errno.h>
14 #include "conv.hpp"
15 #include <assert.h>
16 #include <vector>
17
18 namespace boost {
19 namespace locale {
20 namespace conv {
21 namespace impl {
22
23 class iconverter_base {
24 public:
25
26 iconverter_base() :
27 cvt_((iconv_t)(-1))
28 {
29 }
30
31 ~iconverter_base()
32 {
33 close();
34 }
35
36 size_t conv(char const **inbufc,size_t *inchar_left,
37 char **outbuf,size_t *outchar_left)
38 {
39 char **inbuf = const_cast<char **>(inbufc);
40 return call_iconv(cvt_,inbuf,inchar_left,outbuf,outchar_left);
41 }
42
43 bool do_open(char const *to,char const *from,method_type how)
44 {
45 close();
46 cvt_ = iconv_open(to,from);
47 how_ = how;
48 return cvt_ != (iconv_t)(-1);
49 }
50
51 template<typename OutChar,typename InChar>
52 std::basic_string<OutChar> real_convert(InChar const *ubegin,InChar const *uend)
53 {
54 std::basic_string<OutChar> sresult;
55
56 sresult.reserve(uend - ubegin);
57
58 OutChar result[64];
59
60 char *out_start = reinterpret_cast<char *>(&result[0]);
61 char const *begin = reinterpret_cast<char const *>(ubegin);
62 char const *end = reinterpret_cast<char const *>(uend);
63
64 enum { normal , unshifting , done } state = normal;
65
66 while(state!=done) {
67
68 size_t in_left = end - begin;
69 size_t out_left = sizeof(result);
70
71 char *out_ptr = out_start;
72 size_t res = 0;
73 if(in_left == 0)
74 state = unshifting;
75
76 if(state == normal)
77 res = conv(&begin,&in_left,&out_ptr,&out_left);
78 else
79 res = conv(0,0,&out_ptr,&out_left);
80
81 int err = errno;
82
83 size_t output_count = (out_ptr - out_start) / sizeof(OutChar);
84
85 if(res!=0 && res!=(size_t)(-1)) {
86 if(how_ == stop) {
87 throw conversion_error();
88 }
89 }
90
91 sresult.append(&result[0],output_count);
92
93 if(res == (size_t)(-1)) {
94 if(err == EILSEQ || err == EINVAL) {
95 if(how_ == stop) {
96 throw conversion_error();
97 }
98
99 if(begin != end) {
100 begin+=sizeof(InChar);
101 if(begin >= end)
102 break;
103 }
104 else {
105 break;
106 }
107 }
108 else if (err==E2BIG) {
109 continue;
110 }
111 else {
112 // We should never get there
113 // but if we do
114 if(how_ == stop)
115 throw conversion_error();
116 else
117 break;
118 }
119 }
120 if(state == unshifting)
121 state = done;
122 }
123 return sresult;
124 }
125
126
127 private:
128
129 void close()
130 {
131 if(cvt_!=(iconv_t)(-1)) {
132 iconv_close(cvt_);
133 cvt_ = (iconv_t)(-1);
134 }
135 }
136
137 iconv_t cvt_;
138
139 method_type how_;
140
141 };
142
143 template<typename CharType>
144 class iconv_from_utf : public converter_from_utf<CharType>
145 {
146 public:
147
148 typedef CharType char_type;
149
150 virtual bool open(char const *charset,method_type how)
151 {
152 return self_.do_open(charset,utf_name<CharType>(),how);
153 }
154
155 virtual std::string convert(char_type const *ubegin,char_type const *uend)
156 {
157 return self_.template real_convert<char,char_type>(ubegin,uend);
158 }
159 virtual ~iconv_from_utf() {}
160 private:
161 iconverter_base self_;
162 };
163
164 class iconv_between: public converter_between
165 {
166 public:
167 virtual bool open(char const *to_charset,char const *from_charset,method_type how)
168 {
169 return self_.do_open(to_charset,from_charset,how);
170 }
171 virtual std::string convert(char const *begin,char const *end)
172 {
173 return self_.real_convert<char,char>(begin,end);
174 }
175 virtual ~iconv_between() {}
176 private:
177 iconverter_base self_;
178
179 };
180
181 template<typename CharType>
182 class iconv_to_utf : public converter_to_utf<CharType>
183 {
184 public:
185
186 typedef CharType char_type;
187 typedef std::basic_string<char_type> string_type;
188
189 virtual bool open(char const *charset,method_type how)
190 {
191 return self_.do_open(utf_name<CharType>(),charset,how);
192 }
193
194 virtual string_type convert(char const *begin,char const *end)
195 {
196 return self_.template real_convert<char_type,char>(begin,end);
197 }
198 virtual ~iconv_to_utf() {}
199 private:
200 iconverter_base self_;
201 };
202
203
204
205 } // impl
206 } // conv
207 } // locale
208 } // boost
209
210
211
212
213 #endif
214 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4