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