Commit | Line | Data |
---|---|---|
2f372869 WJ |
1 | /* Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. |
2 | Distributed by Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of Ghostscript. | |
5 | ||
6 | Ghostscript is distributed in the hope that it will be useful, but | |
7 | WITHOUT ANY WARRANTY. No author or distributor accepts responsibility | |
8 | to anyone for the consequences of using it or for whether it serves any | |
9 | particular purpose or works at all, unless he says so in writing. Refer | |
10 | to the Ghostscript General Public License for full details. | |
11 | ||
12 | Everyone is granted permission to copy, modify and redistribute | |
13 | Ghostscript, but only under the conditions described in the Ghostscript | |
14 | General Public License. A copy of this license is supposed to have been | |
15 | given to you along with Ghostscript so you can know your rights and | |
16 | responsibilities. It should be in a file named COPYING. Among other | |
17 | things, the copyright notice and this notice must be preserved on all | |
18 | copies. */ | |
19 | ||
20 | /* sfilter.c */ | |
21 | /* Stream functions for filters */ | |
22 | #include <stdio.h> | |
23 | #include "std.h" | |
24 | #include "scanchar.h" | |
25 | #include "stream.h" | |
26 | #include "gxfixed.h" /* for gstype1.h */ | |
27 | #include "gstype1.h" | |
28 | ||
29 | /* ------ Generic functions ------ */ | |
30 | ||
31 | /* Implement flushing for all encoding filters. */ | |
32 | int | |
33 | s_filter_flush(register stream *s) | |
34 | { (*s->procs.write_buf)(s); | |
35 | return sflush(s->strm); | |
36 | } | |
37 | ||
38 | /* Close a filter. If this is an encoding filter, flush it first. */ | |
39 | int | |
40 | s_filter_close(register stream *s) | |
41 | { if ( s->mode == s_mode_write ) | |
42 | { int code = sflush(s); | |
43 | if ( code < 0 ) return code; | |
44 | } | |
45 | return s_std_close(s); | |
46 | } | |
47 | ||
48 | /* ------ ASCIIHexEncode ------ */ | |
49 | ||
50 | /* Flush the buffer */ | |
51 | private int | |
52 | s_AXE_write_buf(register stream *s) | |
53 | { static char *hex_digits = "0123456789abcdef"; | |
54 | register stream *strm = s->strm; | |
55 | register byte *p = s->cbuf; | |
56 | register int count = s->cptr + 1 - p; | |
57 | while ( --count >= 0 ) | |
58 | { byte ch = *p++; | |
59 | sputc(strm, hex_digits[ch >> 4]); | |
60 | sputc(strm, hex_digits[ch & 0xf]); | |
61 | if ( !(count & 15) ) | |
62 | sputc(strm, '\n'); | |
63 | } | |
64 | s->cptr = s->cbuf - 1; | |
65 | return 0; | |
66 | } | |
67 | ||
68 | /* Close the stream */ | |
69 | private int | |
70 | s_AXE_close(register stream *s) | |
71 | { (*s->procs.write_buf)(s); | |
72 | sputc(s->strm, '>'); | |
73 | return s_std_close(s); | |
74 | } | |
75 | ||
76 | /* Stream procedures */ | |
77 | stream_procs s_AXE_procs = | |
78 | { s_std_noavailable, NULL, s_filter_flush, s_AXE_close, | |
79 | NULL, s_AXE_write_buf | |
80 | }; | |
81 | ||
82 | /* ------ ASCIIHexDecode ------ */ | |
83 | ||
84 | /* Initialize the stream */ | |
85 | void | |
86 | s_AXD_init(register stream *s) | |
87 | { s->odd = -1; | |
88 | } | |
89 | ||
90 | /* Refill the buffer */ | |
91 | private int | |
92 | s_AXD_read_buf(register stream *s) | |
93 | { stream *strm = s->strm; | |
94 | uint count; | |
95 | int code = sreadhex(strm, s->cbuf, s->bsize, &count, &s->odd, 0); | |
96 | s->cptr = s->cbuf - 1; | |
97 | s->endptr = s->cptr + count; | |
98 | if ( code != ERRC ) | |
99 | { s->end_status = strm->end_status; | |
100 | return 0; | |
101 | } | |
102 | /* Check for EOD */ | |
103 | if ( sgetc(strm) == '>' ) /* EOD */ | |
104 | s->end_status = EOFC; | |
105 | else /* syntax error */ | |
106 | { s->end_status = ERRC; | |
107 | sputback(strm); | |
108 | } | |
109 | return 0; | |
110 | } | |
111 | ||
112 | /* Stream procedures */ | |
113 | stream_procs s_AXD_procs = | |
114 | { s_std_noavailable, NULL, s_std_null, s_filter_close, | |
115 | s_AXD_read_buf, NULL | |
116 | }; | |
117 | ||
118 | /* ------ eexecDecode ------ */ | |
119 | ||
120 | /* Initialize a stream for reading and decrypting another stream. */ | |
121 | /* Decrypting streams are not positionable. */ | |
122 | void | |
123 | s_exD_init(register stream *s, ushort /*crypt_state*/ state) | |
124 | { s->cstate = state; | |
125 | s->odd = -1; | |
126 | s->binary = -1; /* unknown */ | |
127 | } | |
128 | ||
129 | /* Refill the buffer of a decrypting stream. */ | |
130 | private int | |
131 | s_exD_read_buf(register stream *s) | |
132 | { byte *buf = s->cbuf; | |
133 | uint nread; | |
134 | int skip = (s->binary < 0 ? 4 : 0); | |
135 | s->cptr = s->endptr = buf - 1; | |
136 | top: nread = sgets(s->strm, buf, s->bsize); | |
137 | if ( nread == 0 ) /* end of stream */ | |
138 | { s->end_status = EOFC; | |
139 | return 0; | |
140 | } | |
141 | if ( s->binary < 0 ) | |
142 | { /* This is the very first time we're filling the buffer. */ | |
143 | /* Determine whether this is ASCII or hex encoding. */ | |
144 | register byte _ds *decoder = scan_char_decoder; | |
145 | if ( nread < 4 ) return EOFC; | |
146 | if ( decoder[buf[0]] == ctype_space || | |
147 | (decoder[buf[0]] | decoder[buf[1]] | decoder[buf[2]] | | |
148 | decoder[buf[3]]) <= 0xf ) | |
149 | { /* Would be invalid if binary, hence must be hex. */ | |
150 | s->binary = 0; | |
151 | } | |
152 | else s->binary = 1; | |
153 | ||
154 | } | |
155 | if ( !s->binary ) | |
156 | { /* Convert the buffer from binary to hex in place. */ | |
157 | stream sst; | |
158 | sread_string(&sst, buf, nread); | |
159 | sreadhex(&sst, buf, nread, &nread, &s->odd, 0); | |
160 | if ( nread == 0 ) goto top; /* try again */ | |
161 | } | |
162 | /* Now decrypt the buffer. */ | |
163 | gs_type1_decrypt(buf, buf, nread, (crypt_state *)&s->cstate); | |
164 | if ( skip ) | |
165 | { /* Very first buffer-load, strip off leading bytes. */ | |
166 | if ( nread < skip ) return EOFC; | |
167 | s->cptr += skip; | |
168 | nread -= skip; | |
169 | } | |
170 | s->endptr = s->cptr + nread; | |
171 | return 0; | |
172 | } | |
173 | ||
174 | /* Estimate the number of remaining bytes in a decrypting stream. */ | |
175 | private int | |
176 | s_exD_available(stream *s, long *pl) | |
177 | { if ( savailable(s->strm, pl) < 0 ) return ERRC; | |
178 | if ( *pl >= 0 ) *pl /= 2; | |
179 | return 0; | |
180 | } | |
181 | ||
182 | /* Stream procedures */ | |
183 | stream_procs s_exD_procs = | |
184 | { s_exD_available, NULL, s_std_null, s_filter_close, | |
185 | s_exD_read_buf, NULL | |
186 | }; | |
187 | ||
188 | /* ------ PFBDecode ------ */ | |
189 | ||
190 | /* Initialize the stream */ | |
191 | void | |
192 | s_PFBD_init(register stream *s) | |
193 | { s->record_type = -1; | |
194 | } | |
195 | ||
196 | /* Refill the buffer */ | |
197 | private int | |
198 | s_PFBD_read_buf(register stream *s) | |
199 | { stream *strm = s->strm; | |
200 | register byte *ptr = s->cbuf; | |
201 | uint count; | |
202 | int c; | |
203 | s->cptr = s->endptr = s->cbuf - 1; | |
204 | top: count = s->bsize; | |
205 | switch ( s->record_type ) | |
206 | { | |
207 | case -1: /* new record */ | |
208 | c = sgetc(strm); | |
209 | if ( c != 0x80 ) goto err; | |
210 | c = sgetc(strm); | |
211 | switch ( c ) | |
212 | { | |
213 | case 1: case 2: | |
214 | s->record_type = c; | |
215 | break; | |
216 | case 3: | |
217 | case EOFC: | |
218 | s->end_status = EOFC; | |
219 | return 0; | |
220 | default: | |
221 | goto err; | |
222 | } | |
223 | s->record_left = sgetc(strm); | |
224 | s->record_left += (ulong)sgetc(strm) << 8; | |
225 | s->record_left += (ulong)sgetc(strm) << 16; | |
226 | s->record_left += (ulong)sgetc(strm) << 24; | |
227 | goto top; | |
228 | case 1: /* translate \r to \n */ | |
229 | if ( count > s->record_left ) count = s->record_left; | |
230 | { uint n; | |
231 | for ( n = count; n != 0 && (c = sgetc(strm)) != EOFC; n-- ) | |
232 | { *ptr++ = (c == '\r' ? '\n' : c); | |
233 | } | |
234 | } break; | |
235 | case 2: /* translate binary to hex */ | |
236 | { static char *hex_digits = "0123456789abcdef"; | |
237 | uint n; | |
238 | count >>= 1; /* 2 chars per input byte */ | |
239 | if ( count > s->record_left ) count = s->record_left; | |
240 | for ( n = count; n != 0 && (c = sgetc(strm)) >= 0; n-- ) | |
241 | { *ptr++ = hex_digits[c >> 4]; | |
242 | *ptr++ = hex_digits[c & 0xf]; | |
243 | } | |
244 | } break; | |
245 | } | |
246 | if ( count == 0 ) | |
247 | { s->record_type = -1; | |
248 | goto top; | |
249 | } | |
250 | s->record_left -= count; | |
251 | s->endptr = ptr - 1; | |
252 | return 0; | |
253 | err: s->end_status = ERRC; | |
254 | s->endptr = ptr - 1; | |
255 | return 0; | |
256 | } | |
257 | ||
258 | /* Stream procedures */ | |
259 | stream_procs s_PFBD_procs = | |
260 | { s_std_noavailable, NULL, s_std_null, s_filter_close, | |
261 | s_PFBD_read_buf, NULL | |
262 | }; |