]> mj.ucw.cz Git - libucw.git/blob - charset/unistream.c
Improved and cleaned up the bucket library. The original "single operation
[libucw.git] / charset / unistream.c
1 /*
2  *      The UniCode Library: Reading and writing of UTF-8 on Fastbuf Streams
3  *
4  *      (c) 2001 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/fastbuf.h"
12 #include "charset/unicode.h"
13 #include "charset/unistream.h"
14
15 int
16 bget_utf8_slow(struct fastbuf *b)
17 {
18   int c = bgetc(b);
19   int code;
20
21   if (c < 0x80)                         /* Includes EOF */
22     return c;
23   if (c < 0xc0)                         /* Incorrect combination */
24     return UNI_REPLACEMENT;
25   if (c >= 0xf0)                        /* Too large, skip it */
26     {
27       while ((c = bgetc(b)) >= 0x80 && c < 0xc0)
28         ;
29       goto wrong;
30     }
31   if (c >= 0xe0)                        /* 3 bytes */
32     {
33       code = c & 0x0f;
34       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
35         goto wrong;
36       code = (code << 6) | (c & 0x3f);
37       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
38         goto wrong;
39       code = (code << 6) | (c & 0x3f);
40     }
41   else                                  /* 2 bytes */
42     {
43       code = c & 0x1f;
44       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
45         goto wrong;
46       code = (code << 6) | (c & 0x3f);
47     }
48   return code;
49
50  wrong:
51   if (c >= 0)
52     bungetc(b);
53   return UNI_REPLACEMENT;
54 }
55
56 void
57 bput_utf8_slow(struct fastbuf *b, uns u)
58 {
59   ASSERT(u < 65536);
60   if (u < 0x80)
61     bputc(b, u);
62   else
63     {
64       if (u < 0x800)
65         bputc(b, 0xc0 | (u >> 6));
66       else
67         {
68           bputc(b, 0xe0 | (u >> 12));
69           bputc(b, 0x80 | ((u >> 6) & 0x3f));
70         }
71       bputc(b, 0x80 | (u & 0x3f));
72     }
73 }