Blob


1 #ifdef PLAN9
2 #include <u.h>
3 #include <libc.h>
4 #include <bio.h>
5 #else
6 #include <stdio.h>
7 #include <unistd.h>
8 #include "plan9.h"
9 #endif
10 #include "hdr.h"
11 #include "conv.h"
12 #include "gb.h"
14 /*
15 a state machine for interpreting gb.
16 */
17 void
18 gbproc(int c, Rune **r, long input_loc)
19 {
20 static enum { state0, state1 } state = state0;
21 static int lastc;
22 long n, ch, cold = c;
24 switch(state)
25 {
26 case state0: /* idle state */
27 if(c < 0)
28 return;
29 if(c >= 0xA1){
30 lastc = c;
31 state = state1;
32 return;
33 }
34 emit(c);
35 return;
37 case state1: /* seen a font spec */
38 if(c >= 0xA1)
39 n = (lastc-0xA0)*100 + (c-0xA0);
40 else {
41 nerrors++;
42 if(squawk)
43 EPR "%s: bad gb glyph %d (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, c-0xA0, lastc, cold, input_loc, file);
44 if(!clean)
45 emit(BADMAP);
46 state = state0;
47 return;
48 }
49 ch = tabgb[n];
50 if(ch < 0){
51 nerrors++;
52 if(squawk)
53 EPR "%s: unknown gb %ld (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, n, lastc, cold, input_loc, file);
54 if(!clean)
55 emit(BADMAP);
56 } else
57 emit(ch);
58 state = state0;
59 }
60 }
62 void
63 gb_in(int fd, long *notused, struct convert *out)
64 {
65 Rune ob[N];
66 Rune *r, *re;
67 uchar ibuf[N];
68 int n, i;
69 long nin;
71 USED(notused);
72 r = ob;
73 re = ob+N-3;
74 nin = 0;
75 while((n = read(fd, ibuf, sizeof ibuf)) > 0){
76 for(i = 0; i < n; i++){
77 gbproc(ibuf[i], &r, nin++);
78 if(r >= re){
79 OUT(out, ob, r-ob);
80 r = ob;
81 }
82 }
83 if(r > ob){
84 OUT(out, ob, r-ob);
85 r = ob;
86 }
87 }
88 gbproc(-1, &r, nin);
89 if(r > ob)
90 OUT(out, ob, r-ob);
91 OUT(out, ob, 0);
92 }
94 void
95 gb_out(Rune *base, int n, long *notused)
96 {
97 char *p;
98 int i;
99 Rune r;
100 static int first = 1;
102 USED(notused);
103 if(first){
104 first = 0;
105 for(i = 0; i < NRUNE; i++)
106 tab[i] = -1;
107 for(i = 0; i < GBMAX; i++)
108 if(tabgb[i] != -1)
109 tab[tabgb[i]] = i;
111 nrunes += n;
112 p = obuf;
113 for(i = 0; i < n; i++){
114 r = base[i];
115 if(r < 128)
116 *p++ = r;
117 else {
118 if(tab[r] != -1){
119 r = tab[r];
120 *p++ = 0xA0 + (r/100);
121 *p++ = 0xA0 + (r%100);
122 continue;
124 if(squawk)
125 EPR "%s: rune 0x%x not in output cs\n", argv0, r);
126 nerrors++;
127 if(clean)
128 continue;
129 *p++ = BYTEBADMAP;
132 noutput += p-obuf;
133 if(p > obuf)
134 write(1, obuf, p-obuf);