plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

conv_gb.c (2228B)


      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"
     13 
     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;
     23 
     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;
     36 
     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 }
     61 
     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;
     70 
     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 }
     93 
     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;
    101 
    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 }