160 class generic_codecvt<CharType, CodecvtImpl, 2> :
public std::codecvt<CharType, char, std::mbstate_t>,
163 typedef CharType uchar;
165 generic_codecvt(
size_t refs = 0) : std::codecvt<CharType, char, std::mbstate_t>(refs) {}
166 const CodecvtImpl& implementation()
const {
return *
static_cast<const CodecvtImpl*
>(
this); }
169 std::codecvt_base::result do_unshift(std::mbstate_t& s,
char* from,
char* ,
char*& next)
const override
171 if(*
reinterpret_cast<char*
>(&s) != 0)
172 return std::codecvt_base::error;
174 return std::codecvt_base::ok;
176 int do_encoding()
const noexcept override {
return 0; }
177 int do_max_length()
const noexcept override {
return implementation().max_encoding_length(); }
178 bool do_always_noconv()
const noexcept override {
return false; }
180 int do_length(std::mbstate_t& std_state,
const char* from,
const char* from_end,
size_t max)
const override
182 bool state = *
reinterpret_cast<char*
>(&std_state) != 0;
183 const char* save_from = from;
186 while(max > 0 && from < from_end) {
187 const char* prev_from = from;
188 const utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
200 *
reinterpret_cast<char*
>(&std_state) = state;
201 return static_cast<int>(from - save_from);
204 std::codecvt_base::result do_in(std::mbstate_t& std_state,
206 const char* from_end,
207 const char*& from_next,
210 uchar*& to_next)
const override
212 std::codecvt_base::result r = std::codecvt_base::ok;
218 bool low_surrogate_pending = *
reinterpret_cast<char*
>(&std_state) != 0;
220 while(to < to_end && from < from_end) {
221 const char* from_saved = from;
223 utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
227 r = std::codecvt_base::error;
232 r = std::codecvt_base::partial;
237 *to++ =
static_cast<uchar
>(ch);
247 const std::uint16_t w1 =
static_cast<std::uint16_t
>(0xD800 | (ch >> 10));
248 const std::uint16_t w2 =
static_cast<std::uint16_t
>(0xDC00 | (ch & 0x3FF));
249 if(!low_surrogate_pending) {
254 low_surrogate_pending = !low_surrogate_pending;
259 if(r == std::codecvt_base::ok && (from != from_end || low_surrogate_pending))
260 r = std::codecvt_base::partial;
261 *
reinterpret_cast<char*
>(&std_state) = low_surrogate_pending;
265 std::codecvt_base::result do_out(std::mbstate_t& std_state,
267 const uchar* from_end,
268 const uchar*& from_next,
271 char*& to_next)
const override
273 std::codecvt_base::result r = std::codecvt_base::ok;
280 std::uint16_t state = detail::read_state(std_state);
282 while(to < to_end && from < from_end) {
288 std::uint16_t w1 = state;
289 std::uint16_t w2 = *from;
292 if(0xDC00 <= w2 && w2 <= 0xDFFF) {
293 std::uint16_t vh = w1 - 0xD800;
294 std::uint16_t vl = w2 - 0xDC00;
295 ch = ((uint32_t(vh) << 10) | vl) + 0x10000;
298 r = std::codecvt_base::error;
303 if(0xD800 <= ch && ch <= 0xDBFF) {
308 state =
static_cast<uint16_t
>(ch);
311 }
else if(0xDC00 <= ch && ch <= 0xDFFF) {
315 r = std::codecvt_base::error;
320 r = std::codecvt_base::error;
323 const utf::code_point len = implementation().from_unicode(cvt_state, ch, to, to_end);
325 r = std::codecvt_base::partial;
328 r = std::codecvt_base::error;
337 if(r == std::codecvt_base::ok && (from != from_end || state != 0))
338 r = std::codecvt_base::partial;
339 detail::write_state(std_state, state);
349 class generic_codecvt<CharType, CodecvtImpl, 4> :
public std::codecvt<CharType, char, std::mbstate_t>,
352 typedef CharType uchar;
354 generic_codecvt(
size_t refs = 0) : std::codecvt<CharType, char, std::mbstate_t>(refs) {}
356 const CodecvtImpl& implementation()
const {
return *
static_cast<const CodecvtImpl*
>(
this); }
359 std::codecvt_base::result
360 do_unshift(std::mbstate_t& ,
char* from,
char* ,
char*& next)
const override
363 return std::codecvt_base::ok;
365 int do_encoding()
const noexcept override {
return 0; }
366 int do_max_length()
const noexcept override {
return implementation().max_encoding_length(); }
367 bool do_always_noconv()
const noexcept override {
return false; }
369 int do_length(std::mbstate_t& ,
const char* from,
const char* from_end,
size_t max)
const override
371 const char* start_from = from;
373 while(max > 0 && from < from_end) {
374 const char* save_from = from;
375 const utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
383 return static_cast<int>(from - start_from);
386 std::codecvt_base::result do_in(std::mbstate_t& ,
388 const char* from_end,
389 const char*& from_next,
392 uchar*& to_next)
const override
394 std::codecvt_base::result r = std::codecvt_base::ok;
397 while(to < to_end && from < from_end) {
398 const char* from_saved = from;
400 const utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
403 r = std::codecvt_base::error;
408 r = std::codecvt_base::partial;
416 if(r == std::codecvt_base::ok && from != from_end)
417 r = std::codecvt_base::partial;
421 std::codecvt_base::result do_out(std::mbstate_t& ,
423 const uchar* from_end,
424 const uchar*& from_next,
427 char*& to_next)
const override
429 std::codecvt_base::result r = std::codecvt_base::ok;
431 while(to < to_end && from < from_end) {
432 const std::uint32_t ch = *from;
434 r = std::codecvt_base::error;
437 const utf::code_point len = implementation().from_unicode(cvt_state, ch, to, to_end);
439 r = std::codecvt_base::partial;
442 r = std::codecvt_base::error;
450 if(r == std::codecvt_base::ok && from != from_end)
451 r = std::codecvt_base::partial;