Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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	"gbk.h"
13
 
14
static void
15
gbkproc(int c, Rune **r, long input_loc)
16
{
17
	static enum { state0, state1 } state = state0;
18
	static int lastc;
19
	long ch, cold = c;
20
 
21
	switch(state)
22
	{
23
	case state0:	/* idle state */
24
		if(c < 0)
25
			return;
26
		if(c >= 0x80){
27
			lastc = c;
28
			state = state1;
29
			return;
30
		}
31
		emit(c);
32
		return;
33
 
34
	case state1:	/* seen a font spec */
35
		ch = -1;
36
		c = lastc<<8 | c;
37
		if(c >= GBKMIN && c < GBKMAX)
38
			ch = tabgbk[c - GBKMIN];
39
		if(ch < 0){
40
			nerrors++;
41
			if(squawk)
42
				EPR "%s: bad gbk glyph %d (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, (c & 0xFF), lastc, cold, input_loc, file);
43
			if(!clean)
44
				emit(BADMAP);
45
			state = state0;
46
			return;
47
		}
48
		emit(ch);
49
		state = state0;
50
	}
51
}
52
 
53
void
54
gbk_in(int fd, long *notused, struct convert *out)
55
{
56
	Rune ob[N];
57
	Rune *r, *re;
58
	uchar ibuf[N];
59
	int n, i;
60
	long nin;
61
 
62
	USED(notused);
63
	r = ob;
64
	re = ob+N-3;
65
	nin = 0;
66
	while((n = read(fd, ibuf, sizeof ibuf)) > 0){
67
		for(i = 0; i < n; i++){
68
			gbkproc(ibuf[i], &r, nin++);
69
			if(r >= re){
70
				OUT(out, ob, r-ob);
71
				r = ob;
72
			}
73
		}
74
		if(r > ob){
75
			OUT(out, ob, r-ob);
76
			r = ob;
77
		}
78
	}
79
	gbkproc(-1, &r, nin);
80
	if(r > ob)
81
		OUT(out, ob, r-ob);
82
	OUT(out, ob, 0);
83
}
84
 
85
 
86
void
87
gbk_out(Rune *base, int n, long *notused)
88
{
89
	char *p;
90
	int i;
91
	Rune r;
92
	static int first = 1;
93
 
94
	USED(notused);
95
	if(first){
96
		first = 0;
97
		for(i = 0; i < NRUNE; i++)
98
			tab[i] = -1;
99
		for(i = GBKMIN; i < GBKMAX; i++)
100
			tab[tabgbk[i-GBKMIN]] = i;
101
	}
102
	nrunes += n;
103
	p = obuf;
104
	for(i = 0; i < n; i++){
105
		r = base[i];
106
		if(r < 0x80)
107
			*p++ = r;
108
		else {
109
			if(tab[r] != -1){
110
				r = tab[r];
111
				*p++ = (r>>8) & 0xFF;
112
				*p++ = r & 0xFF;
113
				continue;
114
			}
115
			if(squawk)
116
				EPR "%s: rune 0x%x not in output cs\n", argv0, r);
117
			nerrors++;
118
			if(clean)
119
				continue;
120
			*p++ = BYTEBADMAP;
121
		}
122
	}
123
	noutput += p-obuf;
124
	if(p > obuf)
125
		write(1, obuf, p-obuf);
126
}