]> mj.ucw.cz Git - libucw.git/blob - charset/unistream.c
UTF8_SKIP now recognizes the real end of the UTF-8 character
[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
7 #include "lib/lib.h"
8 #include "lib/fastbuf.h"
9 #include "charset/unicode.h"
10 #include "charset/unistream.h"
11
12 int
13 bget_utf8_slow(struct fastbuf *b)
14 {
15   int c = bgetc(b);
16   int code;
17
18   if (c < 0x80)                         /* Includes EOF */
19     return c;
20   if (c < 0xc0)                         /* Incorrect combination */
21     return UNI_REPLACEMENT;
22   if (c >= 0xf0)                        /* Too large, skip it */
23     {
24       while ((c = bgetc(b)) >= 0x80 && c < 0xc0)
25         ;
26       goto wrong;
27     }
28   if (c >= 0xe0)                        /* 3 bytes */
29     {
30       code = c & 0x0f;
31       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
32         goto wrong;
33       code = (code << 6) | (c & 0x3f);
34       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
35         goto wrong;
36       code = (code << 6) | (c & 0x3f);
37     }
38   else                                  /* 2 bytes */
39     {
40       code = c & 0x1f;
41       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
42         goto wrong;
43       code = (code << 6) | (c & 0x3f);
44     }
45   return code;
46
47  wrong:
48   if (c >= 0)
49     bungetc(b);
50   return UNI_REPLACEMENT;
51 }
52
53 void
54 bput_utf8_slow(struct fastbuf *b, uns u)
55 {
56   ASSERT(u < 65536);
57   if (u < 0x80)
58     bputc(b, u);
59   else
60     {
61       if (u < 0x800)
62         bputc(b, 0xc0 | (u >> 6));
63       else
64         {
65           bputc(b, 0xe0 | (u >> 12));
66           bputc(b, 0x80 | ((u >> 6) & 0x3f));
67         }
68       bputc(b, 0x80 | (u & 0x3f));
69     }
70 }