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