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