Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1993, 2000 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: sbcp.c,v 1.5 2002/02/21 22:24:53 giles Exp $ */
18
/* BCP and TBCP filters */
19
#include "stdio_.h"
20
#include "strimpl.h"
21
#include "sbcp.h"
22
 
23
#define CtrlA 0x01
24
#define CtrlC 0x03
25
#define CtrlD 0x04
26
#define CtrlE 0x05
27
#define CtrlQ 0x11
28
#define CtrlS 0x13
29
#define CtrlT 0x14
30
#define ESC 0x1b
31
#define CtrlBksl 0x1c
32
 
33
/* The following is not used yet. */
34
/*private const char *TBCP_end_protocol_string = "\033%-12345X"; */
35
 
36
/* ------ BCPEncode and TBCPEncode ------ */
37
 
38
/* Process a buffer */
39
private int
40
s_xBCPE_process(stream_state * st, stream_cursor_read * pr,
41
		stream_cursor_write * pw, bool last, const byte * escaped)
42
{
43
    const byte *p = pr->ptr;
44
    const byte *rlimit = pr->limit;
45
    uint rcount = rlimit - p;
46
    byte *q = pw->ptr;
47
    uint wcount = pw->limit - q;
48
    const byte *end = p + min(rcount, wcount);
49
 
50
    while (p < end) {
51
	byte ch = *++p;
52
 
53
	if (ch <= 31 && escaped[ch]) {
54
	    if (p == rlimit) {
55
		p--;
56
		break;
57
	    }
58
	    *++q = CtrlA;
59
	    ch ^= 0x40;
60
	    if (--wcount < rcount)
61
		end--;
62
	}
63
	*++q = ch;
64
    }
65
    pr->ptr = p;
66
    pw->ptr = q;
67
    return (p == rlimit ? 0 : 1);
68
}
69
 
70
/* Actual process procedures */
71
private int
72
s_BCPE_process(stream_state * st, stream_cursor_read * pr,
73
	       stream_cursor_write * pw, bool last)
74
{
75
    static const byte escaped[32] =
76
    {
77
	0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78
	0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
79
    };
80
 
81
    return s_xBCPE_process(st, pr, pw, last, escaped);
82
}
83
private int
84
s_TBCPE_process(stream_state * st, stream_cursor_read * pr,
85
		stream_cursor_write * pw, bool last)
86
{
87
    static const byte escaped[32] =
88
    {
89
	0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90
	0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0
91
    };
92
 
93
    return s_xBCPE_process(st, pr, pw, last, escaped);
94
}
95
 
96
/* Stream templates */
97
const stream_template s_BCPE_template =
98
{&st_stream_state, NULL, s_BCPE_process, 1, 2
99
};
100
const stream_template s_TBCPE_template =
101
{&st_stream_state, NULL, s_TBCPE_process, 1, 2
102
};
103
 
104
/* ------ BCPDecode and TBCPDecode ------ */
105
 
106
private_st_BCPD_state();
107
 
108
/* Initialize the state */
109
private int
110
s_BCPD_init(stream_state * st)
111
{
112
    stream_BCPD_state *const ss = (stream_BCPD_state *) st;
113
 
114
    ss->escaped = 0;
115
    ss->matched = ss->copy_count = 0;
116
    return 0;
117
}
118
 
119
/* Process a buffer */
120
private int
121
s_xBCPD_process(stream_state * st, stream_cursor_read * pr,
122
		stream_cursor_write * pw, bool last, bool tagged)
123
{
124
    stream_BCPD_state *const ss = (stream_BCPD_state *) st;
125
    const byte *p = pr->ptr;
126
    const byte *rlimit = pr->limit;
127
    byte *q = pw->ptr;
128
    byte *wlimit = pw->limit;
129
    int copy_count = ss->copy_count;
130
    int status;
131
    bool escaped = ss->escaped;
132
 
133
    for (;;) {
134
	byte ch;
135
 
136
	if (copy_count) {
137
	    if (q == wlimit) {
138
		status = (p < rlimit ? 1 : 0);
139
		break;
140
	    }
141
	    *++q = *++(ss->copy_ptr);
142
	    copy_count--;
143
	    continue;
144
	}
145
	if (p == rlimit) {
146
	    status = 0;
147
	    break;
148
	}
149
	ch = *++p;
150
	if (ch <= 31)
151
	    switch (ch) {
152
		case CtrlA:
153
		    if (escaped) {
154
			status = ERRC;
155
			goto out;
156
		    }
157
		    escaped = true;
158
		    continue;
159
		case CtrlC:
160
		    status = (*ss->signal_interrupt) (st);
161
		    if (status < 0)
162
			goto out;
163
		    continue;
164
		case CtrlD:
165
		    if (escaped) {
166
			status = ERRC;
167
			goto out;
168
		    }
169
		    status = EOFC;
170
		    goto out;
171
		case CtrlE:
172
		    continue;
173
		case CtrlQ:
174
		    continue;
175
		case CtrlS:
176
		    continue;
177
		case CtrlT:
178
		    status = (*ss->request_status) (st);
179
		    if (status < 0)
180
			goto out;
181
		    continue;
182
		case CtrlBksl:
183
		    continue;
184
	    }
185
	if (q == wlimit) {
186
	    p--;
187
	    status = 1;
188
	    break;
189
	}
190
	if (escaped) {
191
	    escaped = false;
192
	    switch (ch) {
193
		case '[':
194
		    if (!tagged) {
195
			status = ERRC;
196
			goto out;
197
		    }
198
		    /* falls through */
199
		case 'A':
200
		case 'C':
201
		case 'D':
202
		case 'E':
203
		case 'Q':
204
		case 'S':
205
		case 'T':
206
		case '\\':
207
		    ch ^= 0x40;
208
		    break;
209
		case 'M':
210
		    if (!tagged) {
211
			status = ERRC;
212
			goto out;
213
		    }
214
		    continue;
215
		default:
216
		    status = ERRC;
217
		    goto out;
218
	    }
219
	}
220
	*++q = ch;
221
    }
222
  out:ss->copy_count = copy_count;
223
    ss->escaped = escaped;
224
    pr->ptr = p;
225
    pw->ptr = q;
226
    return status;
227
}
228
 
229
/* Actual process procedures */
230
private int
231
s_BCPD_process(stream_state * st, stream_cursor_read * pr,
232
	       stream_cursor_write * pw, bool last)
233
{
234
    return s_xBCPD_process(st, pr, pw, last, false);
235
}
236
private int
237
s_TBCPD_process(stream_state * st, stream_cursor_read * pr,
238
		stream_cursor_write * pw, bool last)
239
{
240
    return s_xBCPD_process(st, pr, pw, last, true);
241
}
242
 
243
/* Stream templates */
244
const stream_template s_BCPD_template =
245
{&st_BCPD_state, s_BCPD_init, s_BCPD_process, 1, 1,
246
 NULL, NULL, s_BCPD_init
247
};
248
const stream_template s_TBCPD_template =
249
{&st_BCPD_state, s_BCPD_init, s_TBCPD_process, 1, 1,
250
 NULL, NULL, s_BCPD_init
251
};