4 ucs2_conversion::result
5 ucs2_conversion::do_in(mbstate_t&,
6 const char* from
, const char* from_end
, const char*& from_next
,
7 wchar_t* to
, wchar_t* to_limit
, wchar_t*& to_next
) const
9 size_t max_input
= (from_end
- from
) & ~1;
10 size_t max_output
= (to_limit
- to
);
11 size_t count
= std::min(max_input
/2, max_output
);
17 for (;count
--; from_next
+= 2, ++to_next
) {
18 unsigned char c1
= *from_next
, c2
= *(from_next
+ 1);
19 *to_next
= c1
| c2
<< 8;
21 if (to_next
== to
&& from_next
== from_end
- 1) res
= partial
;
25 ucs2_conversion::result
26 ucs2_conversion::do_out(mbstate_t&,
27 const wchar_t* from
, const wchar_t* from_end
, const wchar_t*& from_next
,
28 char* to
, char* to_limit
, char*& to_next
) const
30 size_t max_input
= (from_end
- from
);
31 size_t max_output
= (to_limit
- to
) & ~1;
32 size_t count
= std::min(max_input
, max_output
/2);
36 for (;count
--; ++from_next
, to_next
+= 2) {
37 *(to_next
+ 0) = (char)(*from_next
& 0xFF);
38 *(to_next
+ 1) = (char)(*from_next
>> 8 & 0xFF);
43 typedef unsigned char uchar
;
46 take_6_bits(unsigned value
, size_t right_position
)
48 return uchar((value
>> right_position
) & 63);
54 most_signifant_bit_position(unsigned value
)
59 for(; half
> 0; half
>>= 1) {
60 if (1u << (result
+ half
) <= value
) result
+= half
;
63 //return *lower_bound(range(0u, 31u), \x -> (1 << x <= value));
68 utf8_conversion::result
69 utf8_conversion::do_in(mbstate_t&,
70 const char* from
, const char* from_end
, const char*& from_next
,
71 wchar_t* to
, wchar_t* to_limit
, wchar_t*& to_next
) const
76 for(; to_next
< to_limit
&& from_next
< from_end
; ++to_next
) {
78 if (uchar(*from_next
) < 0x80) *to_next
= uchar(*from_next
++);
81 // 111zxxxx : z = 0 xxxx are data bits
82 size_t zero_bit_pos
= most_signifant_bit_position(~*from_next
);
83 size_t extra_bytes
= 7 - zero_bit_pos
;
85 if (size_t(from_end
- from_next
) < extra_bytes
+ 1)
88 *to_next
= uchar(*from_next
++) & (wchar_t)((1 << (zero_bit_pos
- 1)) - 1);
90 for (;extra_bytes
--; ++from_next
) {
91 *to_next
= *to_next
<< 6 | uchar(*from_next
) & 63;
100 utf8_conversion::result
101 utf8_conversion::do_out(mbstate_t&,
102 const wchar_t* from
, const wchar_t* from_end
, const wchar_t*& from_next
,
103 char* to
, char* to_limit
, char*& to_next
) const
108 for (;from_next
< from_end
; ++from_next
) {
110 unsigned symbol
= *from_next
;
113 if (to_next
< to_limit
)
114 *to_next
++ = (unsigned char)symbol
;
119 size_t msb_pos
= most_signifant_bit_position(symbol
);
120 size_t extra_bytes
= msb_pos
/ 6;
122 if (size_t(to_limit
- to_next
) >= extra_bytes
+ 1) {
124 *to_next
= uchar(0xFF80 >> extra_bytes
);
125 *to_next
++ |= take_6_bits(symbol
, extra_bytes
*6);
128 *to_next
++ = 0x80 | take_6_bits(symbol
, extra_bytes
*6);