jas_stream.h (14872B)
1 /* 2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of 3 * British Columbia. 4 * Copyright (c) 2001-2003 Michael David Adams. 5 * All rights reserved. 6 */ 7 8 /* __START_OF_JASPER_LICENSE__ 9 * 10 * JasPer License Version 2.0 11 * 12 * Copyright (c) 1999-2000 Image Power, Inc. 13 * Copyright (c) 1999-2000 The University of British Columbia 14 * Copyright (c) 2001-2003 Michael David Adams 15 * 16 * All rights reserved. 17 * 18 * Permission is hereby granted, free of charge, to any person (the 19 * "User") obtaining a copy of this software and associated documentation 20 * files (the "Software"), to deal in the Software without restriction, 21 * including without limitation the rights to use, copy, modify, merge, 22 * publish, distribute, and/or sell copies of the Software, and to permit 23 * persons to whom the Software is furnished to do so, subject to the 24 * following conditions: 25 * 26 * 1. The above copyright notices and this permission notice (which 27 * includes the disclaimer below) shall be included in all copies or 28 * substantial portions of the Software. 29 * 30 * 2. The name of a copyright holder shall not be used to endorse or 31 * promote products derived from the Software without specific prior 32 * written permission. 33 * 34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS 35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER 36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO 40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE 45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE 46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. 47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS 48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL 49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS 50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE 51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE 52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL 53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, 54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL 55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH 56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, 57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH 58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY 59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. 60 * 61 * __END_OF_JASPER_LICENSE__ 62 */ 63 64 /* 65 * I/O Stream Class 66 * 67 * $Id: jas_stream.h 1918 2005-07-24 14:12:08Z baford $ 68 */ 69 70 #ifndef JAS_STREAM_H 71 #define JAS_STREAM_H 72 73 /******************************************************************************\ 74 * Includes. 75 \******************************************************************************/ 76 77 #include <jasper/jas_config.h> 78 79 #include <stdio.h> 80 #if defined(HAVE_FCNTL_H) 81 #include <fcntl.h> 82 #endif 83 #include <string.h> 84 #if defined(HAVE_UNISTD_H) 85 #include <unistd.h> 86 #endif 87 #include <jasper/jas_types.h> 88 89 #ifdef __cplusplus 90 extern "C" { 91 #endif 92 93 /******************************************************************************\ 94 * Constants. 95 \******************************************************************************/ 96 97 /* On most UNIX systems, we probably need to define O_BINARY ourselves. */ 98 #ifndef O_BINARY 99 #define O_BINARY 0 100 #endif 101 102 /* 103 * Stream open flags. 104 */ 105 106 /* The stream was opened for reading. */ 107 #define JAS_STREAM_READ 0x0001 108 /* The stream was opened for writing. */ 109 #define JAS_STREAM_WRITE 0x0002 110 /* The stream was opened for appending. */ 111 #define JAS_STREAM_APPEND 0x0004 112 /* The stream was opened in binary mode. */ 113 #define JAS_STREAM_BINARY 0x0008 114 /* The stream should be created/truncated. */ 115 #define JAS_STREAM_CREATE 0x0010 116 117 118 /* 119 * Stream buffering flags. 120 */ 121 122 /* The stream is unbuffered. */ 123 #define JAS_STREAM_UNBUF 0x0000 124 /* The stream is line buffered. */ 125 #define JAS_STREAM_LINEBUF 0x0001 126 /* The stream is fully buffered. */ 127 #define JAS_STREAM_FULLBUF 0x0002 128 /* The buffering mode mask. */ 129 #define JAS_STREAM_BUFMODEMASK 0x000f 130 131 /* The memory associated with the buffer needs to be deallocated when the 132 stream is destroyed. */ 133 #define JAS_STREAM_FREEBUF 0x0008 134 /* The buffer is currently being used for reading. */ 135 #define JAS_STREAM_RDBUF 0x0010 136 /* The buffer is currently being used for writing. */ 137 #define JAS_STREAM_WRBUF 0x0020 138 139 /* 140 * Stream error flags. 141 */ 142 143 /* The end-of-file has been encountered (on reading). */ 144 #define JAS_STREAM_EOF 0x0001 145 /* An I/O error has been encountered on the stream. */ 146 #define JAS_STREAM_ERR 0x0002 147 /* The read/write limit has been exceeded. */ 148 #define JAS_STREAM_RWLIMIT 0x0004 149 /* The error mask. */ 150 #define JAS_STREAM_ERRMASK \ 151 (JAS_STREAM_EOF | JAS_STREAM_ERR | JAS_STREAM_RWLIMIT) 152 153 /* 154 * Other miscellaneous constants. 155 */ 156 157 /* The default buffer size (for fully-buffered operation). */ 158 #define JAS_STREAM_BUFSIZE 8192 159 /* The default permission mask for file creation. */ 160 #define JAS_STREAM_PERMS 0666 161 162 /* The maximum number of characters that can always be put back on a stream. */ 163 #define JAS_STREAM_MAXPUTBACK 16 164 165 /******************************************************************************\ 166 * Types. 167 \******************************************************************************/ 168 169 /* 170 * Generic file object. 171 */ 172 173 typedef void jas_stream_obj_t; 174 175 /* 176 * Generic file object operations. 177 */ 178 179 typedef struct { 180 181 /* Read characters from a file object. */ 182 int (*read_)(jas_stream_obj_t *obj, char *buf, int cnt); 183 184 /* Write characters to a file object. */ 185 int (*write_)(jas_stream_obj_t *obj, char *buf, int cnt); 186 187 /* Set the position for a file object. */ 188 long (*seek_)(jas_stream_obj_t *obj, long offset, int origin); 189 190 /* Close a file object. */ 191 int (*close_)(jas_stream_obj_t *obj); 192 193 } jas_stream_ops_t; 194 195 /* 196 * Stream object. 197 */ 198 199 typedef struct { 200 201 /* The mode in which the stream was opened. */ 202 int openmode_; 203 204 /* The buffering mode. */ 205 int bufmode_; 206 207 /* The stream status. */ 208 int flags_; 209 210 /* The start of the buffer area to use for reading/writing. */ 211 uchar *bufbase_; 212 213 /* The start of the buffer area excluding the extra initial space for 214 character putback. */ 215 uchar *bufstart_; 216 217 /* The buffer size. */ 218 int bufsize_; 219 220 /* The current position in the buffer. */ 221 uchar *ptr_; 222 223 /* The number of characters that must be read/written before 224 the buffer needs to be filled/flushed. */ 225 int cnt_; 226 227 /* A trivial buffer to be used for unbuffered operation. */ 228 uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1]; 229 230 /* The operations for the underlying stream file object. */ 231 jas_stream_ops_t *ops_; 232 233 /* The underlying stream file object. */ 234 jas_stream_obj_t *obj_; 235 236 /* The number of characters read/written. */ 237 long rwcnt_; 238 239 /* The maximum number of characters that may be read/written. */ 240 long rwlimit_; 241 242 } jas_stream_t; 243 244 /* 245 * Regular file object. 246 */ 247 248 /* 249 * File descriptor file object. 250 */ 251 typedef struct { 252 int fd; 253 int flags; 254 char pathname[L_tmpnam + 1]; 255 } jas_stream_fileobj_t; 256 257 #define JAS_STREAM_FILEOBJ_DELONCLOSE 0x01 258 #define JAS_STREAM_FILEOBJ_NOCLOSE 0x02 259 260 /* 261 * Memory file object. 262 */ 263 264 typedef struct { 265 266 /* The data associated with this file. */ 267 uchar *buf_; 268 269 /* The allocated size of the buffer for holding file data. */ 270 int bufsize_; 271 272 /* The length of the file. */ 273 int_fast32_t len_; 274 275 /* The seek position. */ 276 int_fast32_t pos_; 277 278 /* Is the buffer growable? */ 279 int growable_; 280 281 /* Was the buffer allocated internally? */ 282 int myalloc_; 283 284 } jas_stream_memobj_t; 285 286 /******************************************************************************\ 287 * Macros/functions for opening and closing streams. 288 \******************************************************************************/ 289 290 /* Open a file as a stream. */ 291 jas_stream_t *jas_stream_fopen(const char *filename, const char *mode); 292 293 /* Open a memory buffer as a stream. */ 294 jas_stream_t *jas_stream_memopen(char *buf, int bufsize); 295 296 /* Open a file descriptor as a stream. */ 297 jas_stream_t *jas_stream_fdopen(int fd, const char *mode); 298 299 /* Open a stdio stream as a stream. */ 300 jas_stream_t *jas_stream_reopen(const char *path, const char *mode, FILE *fp); 301 302 /* Open a temporary file as a stream. */ 303 jas_stream_t *jas_stream_tmpfile(void); 304 305 /* Close a stream. */ 306 int jas_stream_close(jas_stream_t *stream); 307 308 /******************************************************************************\ 309 * Macros/functions for getting/setting the stream state. 310 \******************************************************************************/ 311 312 /* Get the EOF indicator for a stream. */ 313 #define jas_stream_eof(stream) \ 314 (((stream)->flags_ & JAS_STREAM_EOF) != 0) 315 316 /* Get the error indicator for a stream. */ 317 #define jas_stream_error(stream) \ 318 (((stream)->flags_ & JAS_STREAM_ERR) != 0) 319 320 /* Clear the error indicator for a stream. */ 321 #define jas_stream_clearerr(stream) \ 322 ((stream)->flags_ &= ~(JAS_STREAM_ERR | JAS_STREAM_EOF)) 323 324 /* Get the read/write limit for a stream. */ 325 #define jas_stream_getrwlimit(stream) \ 326 (((const jas_stream_t *)(stream))->rwlimit_) 327 328 /* Set the read/write limit for a stream. */ 329 int jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit); 330 331 /* Get the read/write count for a stream. */ 332 #define jas_stream_getrwcount(stream) \ 333 (((const jas_stream_t *)(stream))->rwcnt_) 334 335 /* Set the read/write count for a stream. */ 336 long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt); 337 338 /******************************************************************************\ 339 * Macros/functions for I/O. 340 \******************************************************************************/ 341 342 /* Read a character from a stream. */ 343 #if defined(DEBUG) 344 #define jas_stream_getc(stream) jas_stream_getc_func(stream) 345 #else 346 #define jas_stream_getc(stream) jas_stream_getc_macro(stream) 347 #endif 348 349 /* Write a character to a stream. */ 350 #if defined(DEBUG) 351 #define jas_stream_putc(stream, c) jas_stream_putc_func(stream, c) 352 #else 353 #define jas_stream_putc(stream, c) jas_stream_putc_macro(stream, c) 354 #endif 355 356 /* Read characters from a stream into a buffer. */ 357 int jas_stream_read(jas_stream_t *stream, void *buf, int cnt); 358 359 /* Write characters from a buffer to a stream. */ 360 int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt); 361 362 /* Write formatted output to a stream. */ 363 int jas_stream_printf(jas_stream_t *stream, const char *fmt, ...); 364 365 /* Write a string to a stream. */ 366 int jas_stream_puts(jas_stream_t *stream, const char *s); 367 368 /* Read a line of input from a stream. */ 369 char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize); 370 371 /* Look at the next character to be read from a stream without actually 372 removing it from the stream. */ 373 #define jas_stream_peekc(stream) \ 374 (((stream)->cnt_ <= 0) ? jas_stream_fillbuf(stream, 0) : \ 375 ((int)(*(stream)->ptr_))) 376 377 /* Put a character back on a stream. */ 378 int jas_stream_ungetc(jas_stream_t *stream, int c); 379 380 /******************************************************************************\ 381 * Macros/functions for getting/setting the stream position. 382 \******************************************************************************/ 383 384 /* Is it possible to seek on this stream? */ 385 int jas_stream_isseekable(jas_stream_t *stream); 386 387 /* Set the current position within the stream. */ 388 long jas_stream_seek(jas_stream_t *stream, long offset, int origin); 389 390 /* Get the current position within the stream. */ 391 long jas_stream_tell(jas_stream_t *stream); 392 393 /* Seek to the beginning of a stream. */ 394 int jas_stream_rewind(jas_stream_t *stream); 395 396 /******************************************************************************\ 397 * Macros/functions for flushing. 398 \******************************************************************************/ 399 400 /* Flush any pending output to a stream. */ 401 int jas_stream_flush(jas_stream_t *stream); 402 403 /******************************************************************************\ 404 * Miscellaneous macros/functions. 405 \******************************************************************************/ 406 407 /* Copy data from one stream to another. */ 408 int jas_stream_copy(jas_stream_t *dst, jas_stream_t *src, int n); 409 410 /* Display stream contents (for debugging purposes). */ 411 int jas_stream_display(jas_stream_t *stream, FILE *fp, int n); 412 413 /* Consume (i.e., discard) characters from stream. */ 414 int jas_stream_gobble(jas_stream_t *stream, int n); 415 416 /* Write a character multiple times to a stream. */ 417 int jas_stream_pad(jas_stream_t *stream, int n, int c); 418 419 /* Get the size of the file associated with the specified stream. 420 The specified stream must be seekable. */ 421 long jas_stream_length(jas_stream_t *stream); 422 423 /******************************************************************************\ 424 * Internal functions. 425 \******************************************************************************/ 426 427 /* The following functions are for internal use only! If you call them 428 directly, you will die a horrible, miserable, and painful death! */ 429 430 /* Read a character from a stream. */ 431 #define jas_stream_getc_macro(stream) \ 432 ((!((stream)->flags_ & (JAS_STREAM_ERR | JAS_STREAM_EOF | \ 433 JAS_STREAM_RWLIMIT))) ? \ 434 (((stream)->rwlimit_ >= 0 && (stream)->rwcnt_ >= (stream)->rwlimit_) ? \ 435 (stream->flags_ |= JAS_STREAM_RWLIMIT, EOF) : \ 436 jas_stream_getc2(stream)) : EOF) 437 #define jas_stream_getc2(stream) \ 438 ((--(stream)->cnt_ < 0) ? jas_stream_fillbuf(stream, 1) : \ 439 (++(stream)->rwcnt_, (int)(*(stream)->ptr_++))) 440 441 /* Write a character to a stream. */ 442 #define jas_stream_putc_macro(stream, c) \ 443 ((!((stream)->flags_ & (JAS_STREAM_ERR | JAS_STREAM_EOF | \ 444 JAS_STREAM_RWLIMIT))) ? \ 445 (((stream)->rwlimit_ >= 0 && (stream)->rwcnt_ >= (stream)->rwlimit_) ? \ 446 (stream->flags_ |= JAS_STREAM_RWLIMIT, EOF) : \ 447 jas_stream_putc2(stream, c)) : EOF) 448 #define jas_stream_putc2(stream, c) \ 449 (((stream)->bufmode_ |= JAS_STREAM_WRBUF, --(stream)->cnt_ < 0) ? \ 450 jas_stream_flushbuf((stream), (uchar)(c)) : \ 451 (++(stream)->rwcnt_, (int)(*(stream)->ptr_++ = (c)))) 452 453 /* These prototypes need to be here for the sake of the stream_getc and 454 stream_putc macros. */ 455 int jas_stream_fillbuf(jas_stream_t *stream, int getflag); 456 int jas_stream_flushbuf(jas_stream_t *stream, int c); 457 int jas_stream_getc_func(jas_stream_t *stream); 458 int jas_stream_putc_func(jas_stream_t *stream, int c); 459 460 #ifdef __cplusplus 461 } 462 #endif 463 464 #endif