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 }
93 void
94 gb_out(Rune *base, int n, long *notused)
95 {
96 char *p;
97 int i;
98 Rune r;
99 static int first = 1;
101 USED(notused);
102 if(first){
103 first = 0;
104 for(i = 0; i < NRUNE; i++)
105 tab[i] = -1;
106 for(i = 0; i < GBMAX; i++)
107 if(tabgb[i] != -1)
108 tab[tabgb[i]] = i;
110 nrunes += n;
111 p = obuf;
112 for(i = 0; i < n; i++){
113 r = base[i];
114 if(r < 128)
115 *p++ = r;
116 else {
117 if(tab[r] != -1){
118 r = tab[r];
119 *p++ = 0xA0 + (r/100);
120 *p++ = 0xA0 + (r%100);
121 continue;
123 if(squawk)
124 EPR "%s: rune 0x%x not in output cs\n", argv0, r);
125 nerrors++;
126 if(clean)
127 continue;
128 *p++ = BYTEBADMAP;
131 noutput += p-obuf;
132 if(p > obuf)
133 write(1, obuf, p-obuf);