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 }93 void94 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;109 }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;122 }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;129 }130 }131 noutput += p-obuf;132 if(p > obuf)133 write(1, obuf, p-obuf);134 }