99 enum { supportUnicode = 1 };
101 template<
typename OutputStream>
103 if (codepoint <= 0x7F)
104 os.Put(
static_cast<Ch>(codepoint & 0xFF));
105 else if (codepoint <= 0x7FF) {
106 os.Put(
static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
107 os.Put(
static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
109 else if (codepoint <= 0xFFFF) {
110 os.Put(
static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
111 os.Put(
static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
112 os.Put(
static_cast<Ch>(0x80 | (codepoint & 0x3F)));
116 os.Put(
static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
117 os.Put(
static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
118 os.Put(
static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
119 os.Put(
static_cast<Ch>(0x80 | (codepoint & 0x3F)));
123 template<
typename OutputStream>
125 if (codepoint <= 0x7F)
127 else if (codepoint <= 0x7FF) {
128 PutUnsafe(
os,
static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
131 else if (codepoint <= 0xFFFF) {
132 PutUnsafe(
os,
static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
133 PutUnsafe(
os,
static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
138 PutUnsafe(
os,
static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
139 PutUnsafe(
os,
static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
140 PutUnsafe(
os,
static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
145 template <
typename InputStream>
146 static bool Decode(
InputStream& is,
unsigned* codepoint) {
147#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
148#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
149#define TAIL() COPY(); TRANS(0x70)
150 typename InputStream::Ch
c = is.Take();
152 *codepoint =
static_cast<unsigned char>(
c);
156 unsigned char type = GetRange(
static_cast<unsigned char>(
c));
160 *codepoint = (0xFFu >>
type) &
static_cast<unsigned char>(
c);
164 case 2: TAIL();
return result;
165 case 3: TAIL(); TAIL();
return result;
166 case 4: COPY(); TRANS(0x50); TAIL();
return result;
167 case 5: COPY(); TRANS(0x10); TAIL(); TAIL();
return result;
168 case 6: TAIL(); TAIL(); TAIL();
return result;
169 case 10: COPY(); TRANS(0x20); TAIL();
return result;
170 case 11: COPY(); TRANS(0x60); TAIL(); TAIL();
return result;
171 default:
return false;
178 template <
typename InputStream,
typename OutputStream>
180#define COPY() os.Put(c = is.Take())
181#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
182#define TAIL() COPY(); TRANS(0x70)
189 switch (GetRange(
static_cast<unsigned char>(
c))) {
190 case 2: TAIL();
return result;
191 case 3: TAIL(); TAIL();
return result;
192 case 4: COPY(); TRANS(0x50); TAIL();
return result;
193 case 5: COPY(); TRANS(0x10); TAIL(); TAIL();
return result;
194 case 6: TAIL(); TAIL(); TAIL();
return result;
195 case 10: COPY(); TRANS(0x20); TAIL();
return result;
196 case 11: COPY(); TRANS(0x60); TAIL(); TAIL();
return result;
197 default:
return false;
204 static unsigned char GetRange(
unsigned char c) {
207 static const unsigned char type[] = {
208 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
209 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
210 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
211 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
212 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
213 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
214 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
215 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
216 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
217 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
222 template <
typename InputByteStream>
225 typename InputByteStream::Ch
c = Take(is);
226 if (
static_cast<unsigned char>(
c) != 0xEFu)
return c;
228 if (
static_cast<unsigned char>(
c) != 0xBBu)
return c;
230 if (
static_cast<unsigned char>(
c) != 0xBFu)
return c;
235 template <
typename InputByteStream>
238 return static_cast<Ch>(is.Take());
241 template <
typename OutputByteStream>
244 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xEFu));
245 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xBBu));
246 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xBFu));
249 template <
typename OutputByteStream>
252 os.Put(
static_cast<typename OutputByteStream::Ch
>(
c));