1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Definitions for Ghostscript stream package */
18 /* Requires stdio.h */
19 
20 #ifndef stream_INCLUDED
21 #  define stream_INCLUDED
22 
23 #include "scommon.h"
24 #include "gxiodev.h"
25 #include "srdline.h"
26 
27 /* See scommon.h for documentation on the design of streams. */
28 
29 /* ------ Stream structure definition ------ */
30 
31 /*
32  * We expose the stream structure definition to clients so that
33  * they can get reasonable performance out of the basic operations.
34  */
35 
36 /* Define the "virtual" stream procedures. */
37 
38 typedef struct {
39 
40     /* Store # available for reading. */
41     /* Return 0 if OK, ERRC if error or not implemented. */
42 #define stream_proc_available(proc)\
43   int proc(stream *, long *)
44     stream_proc_available((*available));
45 
46     /* Set position. */
47     /* Return 0 if OK, ERRC if error or not implemented. */
48 #define stream_proc_seek(proc)\
49   int proc(stream *, long)
50     stream_proc_seek((*seek));
51 
52     /* Clear buffer and, if relevant, unblock channel. */
53     /* Cannot cause an error. */
54 #define stream_proc_reset(proc)\
55   void proc(stream *)
56     stream_proc_reset((*reset));
57 
58     /* Flush buffered data to output, or drain input. */
59     /* Return 0 if OK, ERRC if error. */
60 #define stream_proc_flush(proc)\
61   int proc(stream *)
62     stream_proc_flush((*flush));
63 
64     /* Flush data (if writing) & close stream. */
65     /* Return 0 if OK, ERRC if error. */
66 #define stream_proc_close(proc)\
67   int proc(stream *)
68     stream_proc_close((*close));
69 
70     /* Process a buffer, updating the cursor pointers. */
71     /* See strimpl.h for details. */
72     stream_proc_process((*process));
73 
74     /* Switch the stream to read or write mode. */
75     /* false = read, true = write. */
76     /* If the procedure is 0, switching is not allowed. */
77 #define stream_proc_switch_mode(proc)\
78   int proc(stream *, bool)
79     stream_proc_switch_mode((*switch_mode));
80 
81 } stream_procs;
82 
83 /* ------ The actual stream structure ------ */
84 
85 struct stream_s {
86     /*
87      * To allow the stream itself to serve as the "state"
88      * of a couple of heavily used types, we start its
89      * definition with the common stream state.
90      */
91     stream_state_common;
92     /*
93      * The following invariants apply at all times for read streams:
94      *
95      *    s->cbuf - 1 <= s->srptr <= s->srlimit.
96      *
97      *    The amount of data in the buffer is s->srlimit + 1 - s->cbuf.
98      *
99      *    s->position represents the stream position as of the beginning
100      *      of the buffer, so the current position is s->position +
101      *      (s->srptr + 1 - s->cbuf).
102      *
103      * Analogous invariants apply for write streams:
104      *
105      *    s->cbuf - 1 <= s->swptr <= s->swlimit.
106      *
107      *    The amount of data in the buffer is s->swptr + 1 - s->cbuf.
108      *
109      *    s->position represents the stream position as of the beginning
110      *      of the buffer, so the current position is s->position +
111      *      (s->swptr + 1 - s->cbuf).
112      */
113     stream_cursor cursor;	/* cursor for reading/writing data */
114     byte *cbuf;			/* base of buffer */
115     uint bsize;			/* size of buffer, 0 if closed */
116     uint cbsize;		/* size of buffer */
117     /*
118      * end_status indicates what should happen when the client
119      * reaches the end of the buffer:
120      *      0 in the normal case;
121      *      EOFC if a read stream has reached EOD or a write
122      *        stream has written the EOD marker;
123      *      ERRC if an error terminated the last read or write
124      *        operation from or to the underlying data source
125      *        or sink;
126      *      INTC if the last transfer was interrupted (NOT
127      *        USED YET);
128      *      CALLC if a callout is required.
129      */
130     short end_status;		/* status at end of buffer (when */
131                                 /* reading) or now (when writing) */
132     byte foreign;		/* true if buffer is outside heap */
133     byte modes;			/* access modes allowed for this stream */
134 #define s_mode_read 1
135 #define s_mode_write 2
136 #define s_mode_seek 4
137 #define s_mode_append 8		/* (s_mode_write also set) */
138 #define s_is_valid(s) ((s)->modes != 0)
139 #define s_is_reading(s) (((s)->modes & s_mode_read) != 0)
140 #define s_is_writing(s) (((s)->modes & s_mode_write) != 0)
141 #define s_can_seek(s) (((s)->modes & s_mode_seek) != 0)
142     gs_string cbuf_string;	/* cbuf/cbsize if cbuf is a string, */
143                                 /* 0/? if not */
144     long position;		/* file position of beginning of */
145                                 /* buffer */
146     stream_procs procs;
147     stream *strm;		/* the underlying stream, non-zero */
148                                 /* iff this is a filter stream */
149     int is_temp;		/* if >0, this is a temporary */
150                                 /* stream and should be freed */
151                                 /* when its source/sink is closed; */
152                                 /* if >1, the buffer is also */
153                                 /* temporary */
154     int inline_temp;		/* temporary for inline access */
155                                 /* (see spgetc_inline below) */
156     stream_state *state;	/* state of process */
157     /*
158      * The following are for the use of the interpreter.
159      * See files.h for more information on read_id and write_id,
160      * zfile.c for more information on prev and next,
161      * zfilter.c for more information on close_strm.
162      */
163     ushort read_id;		/* "unique" serial # for detecting */
164                                 /* references to closed streams */
165                                 /* and for validating read access */
166     ushort write_id;		/* ditto to validate write access */
167     stream *prev, *next;	/* keep track of all files */
168     bool close_strm;		/* CloseSource/CloseTarget */
169     bool close_at_eod;		/*(default is true, only false if "reusable")*/
170     int (*save_close)(stream *);	/* save original close proc */
171     /*
172      * In order to avoid allocating a separate stream_state for
173      * file streams, which are the most heavily used stream type,
174      * we put their state here.
175      */
176     FILE *file;			/* file handle for C library */
177     gs_const_string file_name;	/* file name (optional) -- clients must */
178                                 /* access only through procedures */
179     uint file_modes;		/* access modes for the file, */
180                                 /* may be a superset of modes */
181     /* Clients must only set the following through sread_subfile. */
182     long file_offset;		/* starting point in file (reading) */
183     long file_limit;		/* ending point in file (reading) */
184 };
185 
186 /* The descriptor is only public for subclassing. */
187 extern_st(st_stream);
188 #define public_st_stream()	/* in stream.c */\
189   gs_public_st_composite_final(st_stream, stream, "stream",\
190     stream_enum_ptrs, stream_reloc_ptrs, stream_finalize)
191 #define STREAM_NUM_PTRS 6
192 
193 /* Initialize the checking IDs of a stream. */
194 #define s_init_ids(s) ((s)->read_id = (s)->write_id = 1)
195 #define s_init_read_id(s) ((s)->read_id = 1, (s)->write_id = 0)
196 #define s_init_write_id(s) ((s)->read_id = 0, (s)->write_id = 1)
197 #define s_init_no_id(s) ((s)->read_id = (s)->write_id = 0)
198 
199 /* ------ Stream functions ------ */
200 
201 #define srptr cursor.r.ptr
202 #define srlimit cursor.r.limit
203 #define swptr cursor.w.ptr
204 #define swlimit cursor.w.limit
205 
206 /* Some of these are macros -- beware. */
207 /* Note that unlike the C stream library, */
208 /* ALL stream procedures take the stream as the first argument. */
209 #define sendrp(s) ((s)->srptr >= (s)->srlimit)	/* NOT FOR CLIENTS */
210 #define sendwp(s) ((s)->swptr >= (s)->swlimit)	/* NOT FOR CLIENTS */
211 
212 /*
213  * Following are valid for all streams.
214  */
215 /* flush is NOT a no-op for read streams -- it discards data until EOF. */
216 /* close is NOT a no-op for non-file streams -- */
217 /* it actively disables them. */
218 /* The close routine must do a flush if needed. */
219 #define sseekable(s) s_can_seek(s)
220 int savailable(stream *, long *);
221 
222 #define sreset(s) (*(s)->procs.reset)(s)
223 #define sflush(s) (*(s)->procs.flush)(s)
224 int sclose(stream *);
225 int sswitch(stream *, bool);
226 
227 /*
228  * Following are only valid for read streams.
229  */
230 int spgetcc(stream *, bool);	/* bool indicates close at EOD */
231 #define spgetc(s) spgetcc(s, true)	/* a procedure equivalent of sgetc */
232 /*
233  * Note that sgetc must call spgetc one byte early, because filter must read
234  * ahead to detect EOD.
235  *
236  * In the definition of sgetc, the first alternative should read
237  *      (int)(*++((s)->srptr))
238  * but the Borland compiler generates truly atrocious code for this.
239  * The SCO ODT compiler requires the first, pointless cast to int.
240  */
241 #define sgetc(s)\
242   ((int)((s)->srlimit - (s)->srptr > 1 ? (++((s)->srptr), (int)*(s)->srptr) : spgetc(s)))
243 int sgets(stream *, byte *, uint, uint *);
244 int sungetc(stream *, byte);	/* ERRC on error, 0 if OK */
245 
246 #define sputback(s) ((s)->srptr--)	/* can only do this once! */
247 #define seofp(s) (sendrp(s) && (s)->end_status == EOFC)
248 #define serrorp(s) (sendrp(s) && (s)->end_status == ERRC)
249 int spskip(stream *, long, long *);
250 
251 #define sskip(s,nskip,pskipped) spskip(s, (long)(nskip), pskipped)
252 /*
253  * Attempt to refill the buffer of a read stream.
254  * Only call this if the end_status is not EOFC,
255  * and if the buffer is (nearly) empty.
256  */
257 int s_process_read_buf(stream *);
258 
259 /*
260  * Following are only valid for write streams.
261  */
262 int spputc(stream *, byte);	/* a procedure equivalent of sputc */
263 
264 /*
265  * The first alternative should read
266  *      ((int)(*++((s)->swptr)=(c)))
267  * but the Borland compiler generates truly atrocious code for this.
268  */
269 #define sputc(s,c)\
270   (!sendwp(s) ? (++((s)->swptr), *(s)->swptr=(c), 0) : spputc((s),(c)))
271 int sputs(stream *, const byte *, uint, uint *);
272 
273 /*
274  * Attempt to empty the buffer of a write stream.
275  * Only call this if the end_status is not EOFC.
276  */
277 int s_process_write_buf(stream *, bool);
278 
279 /* Following are only valid for positionable streams. */
280 long stell(stream *);
281 int spseek(stream *, long);
282 
283 #define sseek(s,pos) spseek(s, (long)(pos))
284 
285 /* Following are for high-performance reading clients. */
286 /* bufptr points to the next item. */
287 #define sbufptr(s) ((s)->srptr + 1)
288 #define sbufavailable(s) ((s)->srlimit - (s)->srptr)
289 #define sbufskip(s, n) ((s)->srptr += (n), 0)
290 /*
291  * Define the minimum amount of data that must be left in an input buffer
292  * after a read operation to handle filter read-ahead, either 0 or 1
293  * byte(s).
294  */
295 #define max_min_left 1
296 /*
297  * The stream.state min_left value is the minimum amount of data that must
298  * be left in an input buffer after a read operation to handle filter
299  * read-ahead. Once filters reach EOD, return 0 since read-ahead is
300  * no longer relevant.
301  */
302 #define sbuf_min_left(s) \
303       ((s->end_status == EOFC || s->end_status == ERRC ? 0 : s->state->min_left))
304 
305 /* The following are for very high-performance clients of read streams, */
306 /* who unpack the stream state into local variables. */
307 /* Note that any non-inline operations must do a s_end_inline before, */
308 /* and a s_begin_inline after. */
309 #define s_declare_inline(s, cp, ep)\
310   register const byte *cp;\
311   const byte *ep
312 #define s_begin_inline(s, cp, ep)\
313   cp = (s)->srptr, ep = (s)->srlimit
314 #define s_end_inline(s, cp, ep)\
315   (s)->srptr = cp
316 #define sbufavailable_inline(s, cp, ep)\
317   (ep - cp)
318 #define sendbufp_inline(s, cp, ep)\
319   (cp >= ep)
320 /* The (int) is needed to pacify the SCO ODT compiler. */
321 #define sgetc_inline(s, cp, ep)\
322   ((int)(sendbufp_inline(s, cp, ep) ? spgetc_inline(s, cp, ep) : *++cp))
323 #define spgetc_inline(s, cp, ep)\
324   (s_end_inline(s, cp, ep), (s)->inline_temp = spgetc(s),\
325    s_begin_inline(s, cp, ep), (s)->inline_temp)
326 #define sputback_inline(s, cp, ep)\
327   --cp
328 
329 /* Allocate a stream or a stream state. */
330 stream *s_alloc(gs_memory_t *, client_name_t);
331 stream_state *s_alloc_state(gs_memory_t *, gs_memory_type_ptr_t, client_name_t);
332 /*
333  * Initialize a separately allocated stream or stream state, as if allocated
334  * by s_alloc[_state].
335  */
336 void s_init(stream *, gs_memory_t *);
337 void s_init_state(stream_state *, const stream_template *, gs_memory_t *);
338 
339 /* create a stream for a file object */
340 int file_prepare_stream(const char *, uint, const char *,
341                  uint, stream **, char[4], gs_memory_t *);
342 
343 /* Set up a file stream on an OS file.  */
344 void file_init_stream(stream *, FILE *, const char *, byte *, uint);
345 
346 /* Open a file stream, optionally on an OS file. */
347 int file_open_stream(const char *, uint, const char *,
348                  uint, stream **, gx_io_device *,
349                  iodev_proc_fopen_t, gs_memory_t *);
350 
351 /* Allocate and return a file stream. */
352 stream * file_alloc_stream(gs_memory_t *, client_name_t);
353 
354 /*
355  * Macros for checking file validity.
356  * NOTE: in order to work around a bug in the Borland 5.0 compiler,
357  * you must use file_is_invalid rather than !file_is_valid.
358  */
359 #define file_is_valid(svar,op)\
360   (svar = fptr(op), (svar->read_id | svar->write_id) == r_size(op))
361 #define file_is_invalid(svar,op)\
362   (svar = fptr(op), (svar->read_id | svar->write_id) != r_size(op))
363 #define check_file(svar,op)\
364   BEGIN\
365     check_type(*(op), t_file);\
366     if ( file_is_invalid(svar, op) ) return_error(e_invalidaccess);\
367   END
368 
369 /* Close a file stream. */
370 int file_close_file(stream *);
371 
372 int file_close_finish(stream *);
373 
374 /* Disable further access on the stream by mangling the id's */
375 int file_close_disable(stream *);
376 
377 /* Create a stream on a string or a file. */
378 void sread_string(stream *, const byte *, uint),
379     sread_string_reusable(stream *, const byte *, uint),
380     swrite_string(stream *, byte *, uint);
381 void sread_file(stream *, FILE *, byte *, uint),
382     swrite_file(stream *, FILE *, byte *, uint),
383     sappend_file(stream *, FILE *, byte *, uint);
384 
385 /* Confine reading to a subfile.  This is primarily for reusable streams. */
386 int sread_subfile(stream *s, long start, long length);
387 
388 /* Set the file name of a stream, copying the name. */
389 /* Return <0 if the copy could not be allocated. */
390 int ssetfilename(stream *, const byte *, uint);
391 
392 /* Return the file name of a stream, if any. */
393 /* There is a guaranteed 0 byte after the string. */
394 int sfilename(stream *, gs_const_string *);
395 
396 /* Create a stream that tracks the position, */
397 /* for calculating how much space to allocate when actually writing. */
398 void swrite_position_only(stream *);
399 
400 /* Standard stream initialization */
401 void s_std_init(stream *, byte *, uint, const stream_procs *, int /*mode */ );
402 
403 /* Standard stream finalization */
404 void s_disable(stream *);
405 
406 /* Generic stream procedures exported for templates */
407 int s_std_null(stream *);
408 void s_std_read_reset(stream *), s_std_write_reset(stream *);
409 int s_std_read_flush(stream *), s_std_write_flush(stream *), s_std_noavailable(stream *, long *),
410      s_std_noseek(stream *, long), s_std_close(stream *), s_std_switch_mode(stream *, bool);
411 
412 /* Generic procedures for filters. */
413 int s_filter_write_flush(stream *), s_filter_close(stream *);
414 
415 /* Generic procedure structures for filters. */
416 extern const stream_procs s_filter_read_procs, s_filter_write_procs;
417 
418 /*
419  * Add a filter to an output pipeline.  The client must have allocated the
420  * stream state, if any, using the given allocator.  For s_init_filter, the
421  * client must have called s_init and s_init_state.
422  *
423  * Note that if additional buffering is needed, s_add_filter may add
424  * an additional filter to provide it.
425  */
426 int s_init_filter(stream *fs, stream_state *fss, byte *buf, uint bsize,
427                   stream *target);
428 stream *s_add_filter(stream **ps, const stream_template *template,
429                      stream_state *ss, gs_memory_t *mem);
430 
431 /*
432  * Close the filters in a pipeline, up to a given target stream, freeing
433  * their buffers and state structures.
434  */
435 int s_close_filters(stream **ps, stream *target);
436 
437 /* Define templates for the NullEncode/Decode filters. */
438 /* They have no state. */
439 extern const stream_template s_NullE_template;
440 extern const stream_template s_NullD_template;
441 
442         /* for ziodev.c */
443 int file_close_finish(stream *);
444 int file_close_disable(stream *);
445 
446 #endif /* stream_INCLUDED */
447