1 /* Copyright (C) 2001-2019 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.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Definitions common to stream clients and implementors */
18 
19 #ifndef scommon_INCLUDED
20 #  define scommon_INCLUDED
21 
22 #include "gsmemory.h"
23 #include "gstypes.h"		/* for gs_string */
24 #include "gsstype.h"		/* for extern_st */
25 #include "stdint_.h"         /* for int64_t */
26 
27 /*
28  * There are three major structures involved in the stream package.
29  *
30  * A stream is an "object" that owns a buffer, which it uses to implement
31  * byte-oriented sequential access in a standard way, and a set of
32  * procedures that handle things like buffer refilling.  See stream.h
33  * for more information about streams.
34  */
35 typedef struct stream_s stream;
36 
37 /* We really want our offset type to be 64 bit for large file support
38  * but this allows a particular port to specficy a prefered data type
39  */
40 #ifdef GS_OFFSET_T
41 typedef GS_OFFSET_T gs_offset_t;
42 #else
43 typedef int64_t gs_offset_t;
44 #endif
45 
46 /*
47  * A stream_state records the state specific to a given variety of stream.
48  * The buffer processing function of a stream maintains this state.
49  */
50 typedef struct stream_state_s stream_state;
51 
52 /*
53  * A stream_template provides the information needed to create a stream.
54  * The client must fill in any needed setup parameters in the appropriate
55  * variety of stream_state, and then call the initialization function
56  * provided by the template.  See strimpl.h for more information about
57  * stream_templates.
58  */
59 typedef struct stream_template_s stream_template;
60 
61 /*
62  * The stream package works with bytes, not chars.
63  * This is to ensure unsigned representation on all systems.
64  * A stream currently can only be read or written, not both.
65  * Note also that the read procedure returns an int, not a char or a byte;
66  * we use negative values to indicate exceptional conditions.
67  * (We cast these values to int explicitly, because some compilers
68  * don't do this if the other arm of a conditional is a byte.)
69  *
70  * Note that when a stream reaches an exceptional condition, that condition
71  * remains set until the client does something explicit to reset it.
72  * (There should be a 'sclearerr' procedure to do that, but there isn't.)
73  * In particular, if a read stream encounters an exceptional condition,
74  * it delivers the data it has in its buffer, and then all subsequent
75  * calls to read data (sgetc, sgets, etc.) will return the exceptional
76  * condition without reading any more actual data.
77  */
78 /* End of data */
79 #define EOFC ((int)(-1))
80 /* Error */
81 #define ERRC ((int)(-2))
82 /* Interrupt */
83 #define INTC ((int)(-3))
84 /****** INTC IS NOT USED YET ******/
85 /* Callout */
86 #define CALLC ((int)(-4))
87 #define max_stream_exception 4
88 /* The following hack is needed for initializing scan_char_array in iscan.c. */
89 #define stream_exception_repeat(x) x, x, x, x
90 
91 /*
92  * Define cursors for reading from or writing into a buffer.
93  * We lay them out this way so that we can alias
94  * the write pointer and the read limit.
95  */
96 typedef struct stream_cursor_read_s {
97     const byte *ptr;
98     const byte *limit;
99     byte *_skip;
100 } stream_cursor_read;
101 typedef struct stream_cursor_write_s {
102     const byte *_skip;
103     byte *ptr;
104     byte *limit;
105 } stream_cursor_write;
106 typedef union stream_cursor_s {
107     stream_cursor_read r;
108     stream_cursor_write w;
109 } stream_cursor;
110 
111 /*
112  * Define the prototype for the procedures known to both the generic
113  * stream code and the stream implementations.
114  */
115 
116 /* Initialize the stream state (after the client parameters are set). */
117 #define stream_proc_init(proc)\
118   int proc(stream_state *)
119 
120 /* Process a buffer.  See strimpl.h for details. */
121 #define stream_proc_process(proc)\
122   int proc(stream_state *, stream_cursor_read *,\
123     stream_cursor_write *, bool)
124 
125 /* Release the stream state when closing. */
126 #define stream_proc_release(proc)\
127   void proc(stream_state *)
128 
129 /* Initialize the client parameters to default values. */
130 #define stream_proc_set_defaults(proc)\
131   void proc(stream_state *)
132 
133 /* Reinitialize any internal stream state.  Note that this does not */
134 /* affect buffered data.  We declare this as returning an int so that */
135 /* it can be the same as the init procedure; however, reinit cannot fail. */
136 #define stream_proc_reinit(proc)\
137   int proc(stream_state *)
138 
139 /* Report an error.  Note that this procedure is stored in the state, */
140 /* not in the main stream structure. */
141 #define stream_proc_report_error(proc)\
142   int proc(stream_state *, const char *)
143 stream_proc_report_error(s_no_report_error);
144 
145 /*
146  * Some types of streams have the ability to read their parameters from
147  * a parameter list, and to write all (or only the non-default)
148  * parameters to a parameter list.  Since these are not virtual
149  * procedures for the stream (they operate on stream_state structures
150  * even if no actual stream has been created), we name them differently.
151  */
152 #define stream_state_proc_get_params(proc, state_type)\
153   int proc(gs_param_list *plist, const state_type *ss, bool all)
154 #define stream_state_proc_put_params(proc, state_type)\
155   int proc(gs_param_list *plist, state_type *ss)
156 
157 /*
158  * Define a generic stream state.  If a processing procedure has no
159  * state of its own, it can use stream_state; otherwise, it must
160  * create a "subclass".  There is a hack in stream.h to allow the stream
161  * itself to serve as the "state" of a couple of heavily used stream types.
162  *
163  * In order to simplify the structure descriptors for concrete streams,
164  * we require that the generic stream state not contain any pointers
165  * to garbage-collectable storage.
166  */
167 #define STREAM_MAX_ERROR_STRING 79
168 #define stream_state_common\
169         const stream_template *templat;\
170         gs_memory_t *memory;\
171         stream_proc_report_error((*report_error));\
172         int min_left; /* required bytes for lookahead */ \
173         char error_string[STREAM_MAX_ERROR_STRING + 1]
174 struct stream_state_s {
175     stream_state_common;
176 };
177 
178 extern_st(st_stream_state);
179 #define public_st_stream_state() /* in stream.c */\
180   gs_public_st_simple(st_stream_state, stream_state, "stream_state")
181 
182 #endif /* scommon_INCLUDED */
183