5 ucs2_conversion::result
6 ucs2_conversion::do_in(mbstate_t&,
7 const char* from
, const char* from_end
, const char*& from_next
,
8 wchar_t* to
, wchar_t* to_limit
, wchar_t*& to_next
) const
10 size_t max_input
= (from_end
- from
) & ~1;
11 size_t max_output
= (to_limit
- to
);
12 size_t count
= min(max_input
/2, max_output
);
18 for (;count
--; from_next
+= 2, ++to_next
) {
19 unsigned char c1
= *from_next
, c2
= *(from_next
+ 1);
20 *to_next
= c1
| c2
<< 8;
22 if (to_next
== to
&& from_next
== from_end
- 1) res
= partial
;
26 ucs2_conversion::result
27 ucs2_conversion::do_out(mbstate_t&,
28 const wchar_t* from
, const wchar_t* from_end
, const wchar_t*& from_next
,
29 char* to
, char* to_limit
, char*& to_next
) const
31 size_t max_input
= (from_end
- from
);
32 size_t max_output
= (to_limit
- to
) & ~1;
33 size_t count
= min(max_input
, max_output
/2);
37 for (;count
--; ++from_next
, to_next
+= 2) {
38 *(to_next
+ 0) = (char)(*from_next
& 0xFF);
39 *(to_next
+ 1) = (char)(*from_next
>> 8 & 0xFF);
44 typedef unsigned char uchar
;
47 take_6_bits(unsigned value
, size_t right_position
)
49 return uchar((value
>> right_position
) & 63);
55 most_signifant_bit_position(unsigned value
)
60 for(; half
> 0; half
>>= 1) {
61 if (1u << (result
+ half
) <= value
) result
+= half
;
64 //return *lower_bound(range(0u, 31u), \x -> (1 << x <= value));
69 utf8_conversion::result
70 utf8_conversion::do_in(mbstate_t&,
71 const char* from
, const char* from_end
, const char*& from_next
,
72 wchar_t* to
, wchar_t* to_limit
, wchar_t*& to_next
) const
77 for(; to_next
< to_limit
&& from_next
< from_end
; ++to_next
) {
79 if (uchar(*from_next
) < 0x80) *to_next
= uchar(*from_next
++);
82 // 111zxxxx : z = 0 xxxx are data bits
83 size_t zero_bit_pos
= most_signifant_bit_position(~*from_next
);
84 size_t extra_bytes
= 7 - zero_bit_pos
;
86 if (size_t(from_end
- from_next
) < extra_bytes
+ 1)
89 *to_next
= uchar(*from_next
++) & (wchar_t)((1 << (zero_bit_pos
- 1)) - 1);
91 for (;extra_bytes
--; ++from_next
) {
92 *to_next
= *to_next
<< 6 | uchar(*from_next
) & 63;
101 utf8_conversion::result
102 utf8_conversion::do_out(mbstate_t&,
103 const wchar_t* from
, const wchar_t* from_end
, const wchar_t*& from_next
,
104 char* to
, char* to_limit
, char*& to_next
) const
109 for (;from_next
< from_end
; ++from_next
) {
111 unsigned symbol
= *from_next
;
114 if (to_next
< to_limit
)
115 *to_next
++ = (unsigned char)symbol
;
120 size_t msb_pos
= most_signifant_bit_position(symbol
);
121 size_t extra_bytes
= msb_pos
/ 6;
123 if (size_t(to_limit
- to_next
) >= extra_bytes
+ 1) {
125 *to_next
= uchar(0xFF80 >> extra_bytes
);
126 *to_next
++ |= take_6_bits(symbol
, extra_bytes
*6);
129 *to_next
++ = 0x80 | take_6_bits(symbol
, extra_bytes
*6);