xref: /plan9/sys/src/cmd/gs/src/strimpl.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1993, 1995, 1997, 1999 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: strimpl.h,v 1.6 2002/06/16 05:00:54 lpd Exp $ */
18 /* Definitions for stream implementors */
19 /* Requires stdio.h */
20 
21 #ifndef strimpl_INCLUDED
22 #  define strimpl_INCLUDED
23 
24 #include "scommon.h"
25 #include "gstypes.h"		/* for gsstruct.h */
26 #include "gsstruct.h"
27 
28 /*
29  * The 'process' procedure does the real work of the stream.
30  * It must process as much input information (from pr->ptr + 1 through
31  * pr->limit) as it can, subject to space available for output
32  * (pw->ptr + 1 through pw->limit), updating pr->ptr and pw->ptr.
33  *
34  * The procedure return value must be one of:
35  *      EOFC - an end-of-data pattern was detected in the input,
36  *        or no more input can be processed for some other reason (e.g.,
37  *        the stream was told only to read a certain amount of data).
38  *      ERRC - a syntactic error was detected in the input.
39  *      0 - more input data is needed.
40  *      1 - more output space is needed.
41  * If the procedure returns EOFC, it can assume it will never be called
42  * again for that stream.
43  *
44  * If the procedure is called with last = 1, this is an indication that
45  * no more input will ever be supplied (after the input in the current
46  * buffer defined by *pr); the procedure should produce as much output
47  * as possible, including an end-of-data marker if applicable.  In this
48  * case:
49  *      - If the procedure returns 1, it may be called again (also with
50  *        last = 1).
51  *      - If the procedure returns any other value other than 1, the
52  *        procedure will never be called again for that stream.
53  *      - If the procedure returns 0, this is taken as equivalent to
54  *        returning EOFC.
55  *      - If the procedure returns EOFC (or 0), the stream's end_status
56  *        is set to EOFC, meaning no more writing is allowed.
57  *
58  * Note that these specifications do not distinguish input from output
59  * streams.  This is deliberate: The processing procedures should work
60  * regardless of which way they are oriented in a stream pipeline.
61  * (The PostScript language does take a position as whether any given
62  * filter may be used for input or output, but this occurs at a higher level.)
63  *
64  * The value returned by the process procedure of a stream whose data source
65  * or sink is external (i.e., not another stream) is interpreted slightly
66  * differently.  For an external data source, a return value of 0 means
67  * "no more input data are available now, but more might become available
68  * later."  For an external data sink, a return value of 1 means "there is
69  * no more room for output data now, but there might be room later."
70  *
71  * It appears that the Adobe specifications, read correctly, require that when
72  * the process procedure of a decoding filter has filled up the output
73  * buffer, it must still peek ahead in the input to determine whether or not
74  * the next thing in the input stream is EOD.  If the next thing is an EOD (or
75  * end-of-data, indicated by running out of input data with last = true), the
76  * process procedure must return EOFC; if the next thing is definitely not
77  * an EOD, the process procedure must return 1 (output full) (without, of
78  * course, consuming the non-EOD datum); if the procedure cannot determine
79  * whether or not the next thing is an EOD, it must return 0 (need more input).
80  * Decoding filters that don't have EOD (for example, NullDecode) can use
81  * a simpler algorithm: if the output buffer is full, then if there is more
82  * input, return 1, otherwise return 0 (which is taken as EOFC if last
83  * is true).  All this may seem a little awkward, but it is needed in order
84  * to have consistent behavior regardless of where buffer boundaries fall --
85  * in particular, if a buffer boundary falls just before an EOD.  It is
86  * actually quite easy to implement if the main loop of the process
87  * procedure tests for running out of input rather than for filling the
88  * output: with this structure, exhausting the input always returns 0,
89  * and discovering that the output buffer is full when attempting to store
90  * more output always returns 1.
91  *
92  * Even this algorithm for handling end-of-buffer is not sufficient if an
93  * EOD falls just after a buffer boundary, but the generic stream code
94  * handles this case: the process procedures need only do what was just
95  * described.
96  */
97 
98 /*
99  * The set_defaults procedure in the template has a dual purpose: it sets
100  * default values for all parameters that the client can set before calling
101  * the init procedure, and it also must initialize all pointers in the
102  * stream state to a value that will be valid for the garbage collector
103  * (normally 0).  The latter implies that:
104  *
105  *	Any stream whose state includes additional pointers (beyond those
106  *	in stream_state_common) must have a set_defaults procedure.
107  */
108 
109 /*
110  * Note that all decoding filters that require an explicit EOD in the
111  * source data must have an init procedure that sets min_left = 1.
112  * This effectively provides a 1-byte lookahead in the source data,
113  * which is required so that the stream can close itself "after reading
114  * the last byte of data" (per Adobe specification), as noted above.
115  */
116 
117 /*
118  * Define a template for creating a stream.
119  *
120  * The meaning of min_in_size and min_out_size is the following:
121  * If the amount of input information is at least min_in_size,
122  * and the available output space is at least min_out_size,
123  * the process procedure guarantees that it will make some progress.
124  * (It may make progress even if this condition is not met, but this is
125  * not guaranteed.)
126  */
127 struct stream_template_s {
128 
129     /* Define the structure type for the stream state. */
130     gs_memory_type_ptr_t stype;
131 
132     /* Define an optional initialization procedure. */
133     stream_proc_init((*init));
134 
135     /* Define the processing procedure. */
136     /* (The init procedure can reset other procs if it wants.) */
137     stream_proc_process((*process));
138 
139     /* Define the minimum buffer sizes. */
140     uint min_in_size;		/* minimum size for process input */
141     uint min_out_size;		/* minimum size for process output */
142 
143     /* Define an optional releasing procedure. */
144     stream_proc_release((*release));
145 
146     /* Define an optional parameter defaulting and pointer initialization */
147     /* procedure. */
148     stream_proc_set_defaults((*set_defaults));
149 
150     /* Define an optional reinitialization procedure. */
151     stream_proc_reinit((*reinit));
152 
153 };
154 
155 /* Utility procedures */
156 int stream_move(stream_cursor_read *, stream_cursor_write *);	/* in stream.c */
157 
158 /* Hex decoding utility procedure */
159 typedef enum {
160     hex_ignore_garbage = 0,
161     hex_ignore_whitespace = 1,
162     hex_ignore_leading_whitespace = 2
163 } hex_syntax;
164 int s_hex_process(stream_cursor_read *, stream_cursor_write *, int *, hex_syntax);	/* in sstring.c */
165 
166 #endif /* strimpl_INCLUDED */
167