]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/tcs/conv_gbk.c
ip/ipconfig: use ewrite() to enable routing command for sendra
[plan9front.git] / sys / src / cmd / tcs / conv_gbk.c
1 #include        <u.h>
2 #include        <libc.h>
3 #include        <bio.h>
4 #include        "hdr.h"
5 #include        "conv.h"
6 #include        "gbk.h"
7
8 static void
9 gbkproc(int c, Rune **r, long input_loc)
10 {
11         static enum { state0, state1 } state = state0;
12         static int lastc;
13         long ch, cold = c;
14
15         switch(state)
16         {
17         case state0:    /* idle state */
18                 if(c < 0)
19                         return;
20                 if(c >= 0x80){
21                         lastc = c;
22                         state = state1;
23                         return;
24                 }
25                 emit(c);
26                 return;
27
28         case state1:    /* seen a font spec */
29                 ch = -1;
30                 c = lastc<<8 | c;
31                 if(c >= GBKMIN && c < GBKMAX)
32                         ch = tabgbk[c - GBKMIN];
33                 if(ch < 0){
34                         nerrors++;
35                         if(squawk)
36                                 warn("bad gbk glyph %d (from 0x%x,0x%lx) near byte %ld in %s", (c & 0xFF), lastc, cold, input_loc, file);
37                         if(!clean)
38                                 emit(BADMAP);
39                         state = state0;
40                         return;
41                 }
42                 emit(ch);
43                 state = state0;
44         }
45 }
46
47 void
48 gbk_in(int fd, long *, struct convert *out)
49 {
50         Rune ob[N];
51         Rune *r, *re;
52         uchar ibuf[N];
53         int n, i;
54         long nin;
55
56         r = ob;
57         re = ob+N-3;
58         nin = 0;
59         while((n = read(fd, ibuf, sizeof ibuf)) > 0){
60                 for(i = 0; i < n; i++){
61                         gbkproc(ibuf[i], &r, nin++);
62                         if(r >= re){
63                                 OUT(out, ob, r-ob);
64                                 r = ob;
65                         }
66                 }
67                 if(r > ob){
68                         OUT(out, ob, r-ob);
69                         r = ob;
70                 }
71         }
72         gbkproc(-1, &r, nin);
73         if(r > ob)
74                 OUT(out, ob, r-ob);
75         OUT(out, ob, 0);
76 }
77
78
79 void
80 gbk_out(Rune *base, int n, long *)
81 {
82         char *p;
83         int i;
84         Rune r;
85         static int first = 1;
86
87         if(first){
88                 first = 0;
89                 for(i = 0; i < NRUNE; i++)
90                         tab[i] = -1;
91                 for(i = GBKMIN; i < GBKMAX; i++)
92                         tab[tabgbk[i-GBKMIN]] = i;
93         }
94         nrunes += n;
95         p = obuf;
96         for(i = 0; i < n; i++){
97                 r = base[i];
98                 if(r < 0x80)
99                         *p++ = r;
100                 else {
101                         if(r < NRUNE && tab[r] != -1){
102                                 r = tab[r];
103                                 *p++ = (r>>8) & 0xFF;
104                                 *p++ = r & 0xFF;
105                                 continue;
106                         }
107                         if(squawk)
108                                 warn("rune 0x%x not in output cs", r);
109                         nerrors++;
110                         if(clean)
111                                 continue;
112                         *p++ = BYTEBADMAP;
113                 }
114         }
115         noutput += p-obuf;
116         if(p > obuf)
117                 write(1, obuf, p-obuf);
118 }