2 * UCW Library: Reading and writing of UTF-8 on Fastbuf Streams
4 * (c) 2001--2004 Martin Mares <mj@ucw.cz>
5 * (c) 2004 Robert Spalek <robert@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
12 #include "lib/fastbuf.h"
13 #include "lib/unicode.h"
14 #include "lib/ff-unicode.h"
15 #include "lib/ff-binary.h"
18 bget_utf8_slow(struct fastbuf *b, uns repl)
23 if (c < 0x80) /* Includes EOF */
25 if (c < 0xc0) /* Incorrect combination */
27 if (c >= 0xf0) /* Too large, skip it */
29 while ((c = bgetc(b)) >= 0x80 && c < 0xc0)
33 if (c >= 0xe0) /* 3 bytes */
36 if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
38 code = (code << 6) | (c & 0x3f);
39 if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
41 code = (code << 6) | (c & 0x3f);
46 if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
48 code = (code << 6) | (c & 0x3f);
59 bget_utf8_32_slow(struct fastbuf *b, uns repl)
65 if (c < 0x80) /* Includes EOF */
67 if (c < 0xc0) /* Incorrect combination */
94 else /* Too large, skip it */
96 while ((c = bgetc(b)) >= 0x80 && c < 0xc0)
102 if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
104 code = (code << 6) | (c & 0x3f);
115 bput_utf8_slow(struct fastbuf *b, uns u)
123 bputc(b, 0xc0 | (u >> 6));
126 bputc(b, 0xe0 | (u >> 12));
127 bputc(b, 0x80 | ((u >> 6) & 0x3f));
129 bputc(b, 0x80 | (u & 0x3f));
134 bput_utf8_32_slow(struct fastbuf *b, uns u)
136 ASSERT(u < (1U<<31));
142 bputc(b, 0xc0 | (u >> 6));
146 bputc(b, 0xe0 | (u >> 12));
150 bputc(b, 0xf0 | (u >> 18));
154 bputc(b, 0xf8 | (u >> 24));
157 bputc(b, 0xfc | (u >> 30));
158 bputc(b, 0x80 | ((u >> 24) & 0x3f));
160 bputc(b, 0x80 | ((u >> 18) & 0x3f));
162 bputc(b, 0x80 | ((u >> 12) & 0x3f));
164 bputc(b, 0x80 | ((u >> 6) & 0x3f));
166 bputc(b, 0x80 | (u & 0x3f));
171 bget_utf16_be_slow(struct fastbuf *b, uns repl)
175 uns u = bgetw_be(b), x, y;
178 if ((x = u - 0xd800) >= 0x800)
180 if (x >= 0x400 || bpeekc(b) < 0 || (y = bgetw_be(b) - 0xdc00) >= 0x400)
182 return 0x10000 + (x << 10) + y;
186 bget_utf16_le_slow(struct fastbuf *b, uns repl)
190 uns u = bgetw_le(b), x, y;
193 if ((x = u - 0xd800) >= 0x800)
195 if (x >= 0x400 || bpeekc(b) < 0 || (y = bgetw_le(b) - 0xdc00) >= 0x400)
197 return 0x10000 + (x << 10) + y;