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