Blob
1 #ifdef PLAN92 #include <u.h>3 #include <libc.h>4 #include <bio.h>5 #else6 #include <stdio.h>7 #include <unistd.h>8 #include "plan9.h"9 #endif10 #include "hdr.h"11 #include "conv.h"12 #include "gb.h"14 /*15 a state machine for interpreting gb.16 */17 void18 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 } else57 emit(ch);58 state = state0;59 }60 }62 void63 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 void95 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;110 }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;123 }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;130 }131 }132 noutput += p-obuf;133 if(p > obuf)134 write(1, obuf, p-obuf);135 }