Coverage Report

Created: 2025-07-23 08:18

/work/include/jasper/jas_stream.h
Line
Count
Source (jump to first uncovered line)
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) 2001-2006 Michael David Adams
13
 * Copyright (c) 1999-2000 Image Power, Inc.
14
 * Copyright (c) 1999-2000 The University of British Columbia
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
 * @file jas_stream.h
66
 * @brief I/O Stream Class
67
 */
68
69
#ifndef JAS_STREAM_H
70
#define JAS_STREAM_H
71
72
/******************************************************************************\
73
* Includes.
74
\******************************************************************************/
75
76
/* The configuration header file should be included first. */
77
#include <jasper/jas_config.h> /* IWYU pragma: export */
78
79
#include <stdio.h>
80
#if defined(JAS_HAVE_FCNTL_H)
81
#include <fcntl.h>
82
#endif
83
#include <jasper/jas_types.h>
84
85
#ifdef __cplusplus
86
extern "C" {
87
#endif
88
89
/*!
90
 * @addtogroup module_iostreams
91
 * @{
92
 */
93
94
/******************************************************************************\
95
* Constants.
96
\******************************************************************************/
97
98
/* On most UNIX systems, we probably need to define O_BINARY ourselves. */
99
#ifndef O_BINARY
100
#define O_BINARY  0
101
#endif
102
103
/*
104
 * Stream open flags.
105
 */
106
107
/* The stream was opened for reading. */
108
24.2k
#define JAS_STREAM_READ 0x0001
109
/* The stream was opened for writing. */
110
24.2k
#define JAS_STREAM_WRITE  0x0002
111
/* The stream was opened for appending. */
112
#define JAS_STREAM_APPEND 0x0004
113
/* The stream was opened in binary mode. */
114
24.2k
#define JAS_STREAM_BINARY 0x0008
115
/* The stream should be created/truncated. */
116
#define JAS_STREAM_CREATE 0x0010
117
118
/*
119
 * Stream buffering flags.
120
 */
121
122
/* The stream is unbuffered. */
123
24.2k
#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
24.2k
#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
24.2k
#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
  ssize_t (*read_)(jas_stream_obj_t *obj, char *buf, size_t cnt);
183
184
  /* Write characters to a file object. */
185
  ssize_t (*write_)(jas_stream_obj_t *obj, const char *buf, size_t 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
@brief
197
I/O stream object.
198
199
@warning
200
Library users should never directly access any of the members of this
201
class.
202
The functions/macros provided by the JasPer library API should always
203
be used.
204
 */
205
206
typedef struct {
207
208
  /* The mode in which the stream was opened. */
209
  int openmode_;
210
211
  /* The buffering mode. */
212
  int bufmode_;
213
214
  /* The stream status. */
215
  int flags_;
216
217
  /* The start of the buffer area to use for reading/writing. */
218
  jas_uchar *bufbase_;
219
220
  /* The start of the buffer area excluding the extra initial space for
221
    character putback. */
222
  jas_uchar *bufstart_;
223
224
  /* The buffer size. */
225
  int bufsize_;
226
227
  /* The current position in the buffer. */
228
  jas_uchar *ptr_;
229
230
  /* The number of characters that must be read/written before
231
  the buffer needs to be filled/flushed. */
232
  int cnt_;
233
234
  /* A trivial buffer to be used for unbuffered operation. */
235
  jas_uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
236
237
  /* The operations for the underlying stream file object. */
238
  const jas_stream_ops_t *ops_;
239
240
  /* The underlying stream file object. */
241
  jas_stream_obj_t *obj_;
242
243
  /* The number of characters read/written. */
244
  long rwcnt_;
245
246
  /* The maximum number of characters that may be read/written. */
247
  long rwlimit_;
248
249
} jas_stream_t;
250
251
/*
252
 * Regular file object.
253
 */
254
255
/*
256
 * File descriptor file object.
257
 */
258
typedef struct {
259
  int fd;
260
  int flags;
261
#if defined(JAS_WASI_LIBC)
262
#define L_tmpnam 4096
263
#endif
264
  char pathname[L_tmpnam + 1];
265
} jas_stream_fileobj_t;
266
267
/* Delete underlying file object upon stream close. */
268
#define JAS_STREAM_FILEOBJ_DELONCLOSE 0x01
269
/* Do not close underlying file object upon stream close. */
270
#define JAS_STREAM_FILEOBJ_NOCLOSE  0x02
271
272
/*
273
 * Memory file object.
274
 */
275
276
typedef struct {
277
278
  /* The data associated with this file. */
279
  jas_uchar *buf_;
280
281
  /* The allocated size of the buffer for holding file data. */
282
  size_t bufsize_;
283
284
  /* The length of the file. */
285
  size_t len_;
286
287
  /* The seek position. */
288
  size_t pos_;
289
290
  /* Is the buffer growable? */
291
  int growable_;
292
293
  /* Was the buffer allocated internally? */
294
  int myalloc_;
295
296
} jas_stream_memobj_t;
297
298
/******************************************************************************\
299
* Macros/functions for opening and closing streams.
300
\******************************************************************************/
301
302
/*!
303
@brief Open a file as a stream.
304
305
@param filename
306
A pointer to the pathname of the file to be opened.
307
@param mode
308
A pointer to the string specifying the open mode.
309
The open mode is similar to that used by the fopen function in the
310
C standard library.
311
312
@return
313
Upon success, a pointer to the opened stream is returned.
314
Otherwise, a null pointer is returned.
315
*/
316
JAS_EXPORT
317
jas_stream_t *jas_stream_fopen(const char *filename, const char *mode);
318
319
/*!
320
@brief Open a memory buffer as a stream.
321
322
@param buffer
323
A pointer to the buffer to be used to store stream data.
324
@param buffer_size
325
The size of the buffer.
326
327
@details
328
<ul>
329
<li>
330
If buffer is 0 and buffer_size > 0:
331
a buffer is dynamically allocated with size buffer_size and this buffer is
332
not growable.
333
<li>
334
If buffer is 0 and buffer_size is 0:
335
a buffer is dynamically allocated whose size will automatically grow to
336
accommodate the amount of data written.
337
<li>
338
If buffer is not 0:
339
buffer_size (which, in this case, is not currently allowed to be zero) is
340
the size of the (nongrowable) buffer pointed to by buffer.
341
</ul>
342
*/
343
JAS_EXPORT
344
jas_stream_t *jas_stream_memopen(char *buffer, size_t buffer_size);
345
346
/*!
347
@brief
348
Do not use.
349
@deprecated
350
Do not use this function.
351
This function is deprecated.
352
Use jas_stream_memopen instead.
353
*/
354
JAS_DEPRECATED
355
JAS_EXPORT
356
jas_stream_t *jas_stream_memopen2(char *buffer, size_t buffer_size);
357
358
/*!
359
@brief Open a file descriptor as a stream.
360
361
@param fd
362
The file descriptor of the file to open as a stream.
363
@param mode
364
A pointer to a string specifying the open mode.
365
The format of this string is similar to that of the fdopen function
366
in the C standard library.
367
368
@return
369
Upon success, a pointer to the opened stream is returned.
370
Otherwise, a null pointer is returned.
371
*/
372
JAS_EXPORT
373
jas_stream_t *jas_stream_fdopen(int fd, const char *mode);
374
375
/*!
376
@brief Open a stdio (i.e., C standard library) stream as a stream.
377
378
@param path
379
A pointer to a null-terminated string containing the pathname of the file
380
to be reopened.
381
@param mode
382
A pointer to a null-terminated string containing the mode to be used for
383
reopening the file.
384
This string is similar to that used by the fdopen function in the
385
C standard library.
386
@param fp
387
A pointer to the `FILE` (i.e., stdio stream) to be reopened.
388
389
@details
390
It is unspecified whether the open mode specified by mode can be
391
changed from the open mode used for opening the stdio stream.
392
393
@return
394
Upon success, a pointer to the opened stream is returned.
395
Otherwise, a null pointer is returned.
396
*/
397
JAS_EXPORT
398
jas_stream_t *jas_stream_freopen(const char *path, const char *mode, FILE *fp);
399
400
/*!
401
@brief Open a temporary file as a stream.
402
403
@details
404
A temporary file is created and opened as a stream.
405
The temporary file is deleted when closed via jas_stream_close().
406
Some operating systems provide a mechanism for ensuring that a file
407
is removed when closed.
408
Such functionality may be used by the implementation when available.
409
410
@return
411
Upon success, a pointer to the opened stream is returned.
412
Otherwise, a null pointer is returned.
413
*/
414
JAS_EXPORT
415
jas_stream_t *jas_stream_tmpfile(void);
416
417
/*!
418
@brief Close a stream.
419
420
@param stream
421
A (nonnull) pointer to the stream to be closed.
422
423
@details
424
The close operation will implicitly flush any pending output
425
to the stream before closing.
426
If such a flush operation fails, this will be reflected in
427
the return value of this function.
428
For many systems, it is likely that the main reason that this function
429
can fail is due to an I/O error when flushing buffered output.
430
431
@return
432
If no errors are encountered when closing the stream, 0 is returned.
433
Otherwise, a nonzero value is returned.
434
*/
435
JAS_EXPORT
436
int jas_stream_close(jas_stream_t *stream);
437
438
/******************************************************************************\
439
* Macros/functions for getting/setting the stream state.
440
\******************************************************************************/
441
442
/*!
443
@brief Get the EOF indicator for a stream.
444
445
@param stream
446
The stream whose EOF indicator is to be queried.
447
448
@return
449
The value of the EOF indicator is returned.
450
A nonzero value indicates that the stream has encountered EOF.
451
*/
452
#define jas_stream_eof(stream) \
453
  (((stream)->flags_ & JAS_STREAM_EOF) != 0)
454
455
/*!
456
@brief Get the error indicator for a stream.
457
458
@param stream
459
The stream whose error indicator is to be queried.
460
@return
461
The value of the error indicator is returned.
462
A nonzero value indicates that the stream has encountered an error
463
of some type (such as an I/O error).
464
Note that EOF is not an error.
465
*/
466
#define jas_stream_error(stream) \
467
  (((stream)->flags_ & JAS_STREAM_ERR) != 0)
468
469
/*!
470
@brief Clear the error indicator for a stream.
471
472
@param stream
473
The stream whose error indicator is to be cleared.
474
475
@todo
476
TODO/FIXME: Should this macro evaluate to void?
477
*/
478
#define jas_stream_clearerr(stream) \
479
  ((stream)->flags_ &= ~(JAS_STREAM_ERR | JAS_STREAM_EOF))
480
481
/*!
482
@brief Get the read/write limit for a stream.
483
@param stream
484
A pointer to the stream whose read/write limit is to be queried.
485
@return
486
The read/write limit for the stream is returned.
487
This operation cannot fail.
488
A negative read/write limit indicates no limit (i.e., an limit that is
489
effectively infinite).
490
*/
491
#define jas_stream_getrwlimit(stream) \
492
  (((const jas_stream_t *)(stream))->rwlimit_)
493
494
/*!
495
@brief Set the read/write limit for a stream.
496
497
@param stream
498
A pointer to the stream whose read/write limit is to be set.
499
@param rwlimit
500
The new value for the read/write limit.
501
502
@details
503
A negative read/write limit is treated as if it were infinity
504
(i.e., there is no read/write limit).
505
506
@return
507
The old read/write limit is returned.
508
*/
509
JAS_EXPORT long jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit);
510
511
/*!
512
@brief Get the read/write count for a stream.
513
514
@param stream
515
A pointer to the stream whose read/write count is to be queried.
516
517
@return
518
The read/write count is returned.
519
This operation cannot fail.
520
*/
521
#define jas_stream_getrwcount(stream) \
522
  (((const jas_stream_t *)(stream))->rwcnt_)
523
524
/*!
525
@brief Set the read/write count for a stream.
526
527
@param stream
528
A pointer to the stream whose read/write count is to be set.
529
@param rw_count
530
The new value for the read/write count.
531
@return
532
The old value of the read/write count is returned.
533
This operation cannot fail.
534
@todo
535
TODO/FIXME: Should this macro evaluate to void?
536
*/
537
JAS_EXPORT
538
long jas_stream_setrwcount(jas_stream_t *stream, long rw_count);
539
540
/******************************************************************************\
541
* Macros/functions for I/O.
542
\******************************************************************************/
543
544
/* Read a character from a stream. */
545
#ifndef NDEBUG
546
/*!
547
@brief jas_stream_getc
548
Read a character from a stream.
549
550
@param stream
551
A pointer to the stream from which to read a character.
552
553
@returns
554
If a character is succesfully read, the character is returned.
555
Otherwise, EOF is returned.
556
*/
557
#define jas_stream_getc(stream) jas_stream_getc_func(stream)
558
#else
559
#define jas_stream_getc(stream) jas_stream_getc_macro(stream)
560
#endif
561
562
/* Write a character to a stream. */
563
#ifndef NDEBUG
564
/*!
565
@brief jas_stream_putc
566
Write a character to a stream.
567
568
@param stream
569
A pointer to the stream to which to write the character.
570
@param c
571
The character to be written.
572
573
@returns
574
If the character is successfully output, the value of the character is
575
returned.
576
Otherwise, EOF is returned.
577
*/
578
#define jas_stream_putc(stream, c)  jas_stream_putc_func(stream, c)
579
#else
580
#define jas_stream_putc(stream, c)  jas_stream_putc_macro(stream, c)
581
#endif
582
583
/*!
584
@brief Read characters from a stream into a buffer.
585
586
@param stream
587
A pointer to the stream from which to read data.
588
@param buffer
589
A pointer to the start of the buffer.
590
@param count
591
A count of the number of characters to read (nominally).
592
593
@details
594
If @c count is zero, the function has no effect (and therefore cannot fail).
595
Otherwise, the function attempts to read @c count characters from the
596
stream @c stream into the buffer starting at @c buffer.
597
The number of characters read can be less than @c count, due to
598
end-of-file (EOF) or an I/O error.
599
600
(This function is analogous to fread with the two read-count
601
parameters combined into a single size.)
602
603
@return
604
The number of characters read is returned.
605
In the case that the number of characters read is less than @c count,
606
jas_stream_eof() and/or jas_stream_error() must be used
607
to distinguish between:
608
<ol>
609
<li>a failure due to an I/O error
610
<li>a failure due to the read/write limit being exceeded
611
<li>EOF.
612
</ol>
613
(The functions jas_stream_getrwcount() and jas_stream_getrwlimit()
614
can be used to distinguish between failure due to an I/O error
615
and failure due to the read/write limit being exceeed.)
616
617
@todo
618
TODO: should jas_stream_error be true if RWLIMIT exceeded?
619
or maybe introduce a jas_stream_rwlimit predicate?
620
*/
621
JAS_EXPORT
622
size_t jas_stream_read(jas_stream_t *stream, void *buffer, size_t count);
623
624
/*!
625
@brief Attempt to retrieve one or more pending characters of input
626
from a stream into a buffer
627
without actually removing the characters from the stream.
628
629
@param stream
630
A pointer to the stream from which to retrieve pending input.
631
@param buffer
632
A pointer to the start of the buffer.
633
@param count
634
A count of how many characters to retrieve.
635
636
@details
637
The extent to which one can peek into the stream is limited.
638
Therefore, this function can fail if count is sufficiently large.
639
640
@return
641
Returns the number of bytes copied to the given buffer, or 0 on error
642
or EOF.
643
644
@warning
645
TODO/FIXME: peeking at EOF should be distinguishable from an I/O error;
646
also should return type be changed to size_t?
647
648
*/
649
JAS_EXPORT
650
unsigned jas_stream_peek(jas_stream_t *stream, void *buffer, size_t count);
651
652
/*!
653
@brief Write characters from a buffer to a stream.
654
@param stream
655
A pointer to the stream to which to write data.
656
@param buffer
657
A pointer to the start of the buffer.
658
@param count
659
A count of the number of characters to write.
660
661
@details
662
If @c count is zero, the function has no effect (and therefore cannot fail).
663
Otherwise, the function will attempt to write @c count characters
664
from the buffer starting at @c buffer to the stream @c stream.
665
The number of characters written can be less than @c count due to
666
an I/O error or the read/write limit being exceeded.
667
668
(This function is analogous to fwrite with the two write-count
669
parameters combined into a single size.)
670
671
@return
672
Upon success, the number of characters successfully written is returned.
673
If an error occurs, the value returned will be less than @c count.
674
The jas_stream_error() and jas_stream_rwlimit() function (TODO/CHECK: the latter
675
of which does not currently exist?) can be used to distinguish between:
676
<ol>
677
<li>failure due to an I/O error
678
<li>failure due to the read/write limit being exceeded
679
</ol>
680
*/
681
JAS_EXPORT
682
size_t jas_stream_write(jas_stream_t *stream, const void *buffer,
683
  size_t count);
684
685
/*!
686
@brief Write formatted output to a stream.
687
688
@param stream
689
A pointer to the stream to which to write output.
690
@param format
691
A pointer to a format string similar to the printf function in the C standard
692
library.
693
694
@details
695
The function prints the information associated with the format string
696
to the specified stream.
697
698
@return
699
Upon success, the number of characters output to the stream is returned.
700
If an error is encountered, a negative value is returned.
701
702
@todo
703
I think that the return type of int is okay here.
704
It is consistent with printf and friends.
705
*/
706
JAS_EXPORT
707
int jas_stream_printf(jas_stream_t *stream, const char *format, ...);
708
709
/*!
710
@brief Write a string to a stream.
711
712
@param stream
713
A pointer to the stream to which the string should be written.
714
@param s
715
A pointer to a null-terminated string for output.
716
717
@details
718
The null character is not output.
719
720
(This function is analogous to fputs for C standard library streams.)
721
722
@return
723
Upon success, a nonnegative value is returned.
724
Upon failure, a negative value is returned.
725
*/
726
JAS_EXPORT
727
int jas_stream_puts(jas_stream_t *stream, const char *s);
728
729
/*!
730
@brief Read a line of input from a stream.
731
732
@param stream
733
A pointer to the stream from which to read input.
734
@param buffer
735
A pointer to the start of the buffer to hold to input to be read.
736
@param buffer_size
737
The size of the buffer in characters.
738
739
@details
740
The function reads a line of input from a stream into a buffer.
741
If a newline character is read, it is placed in the buffer.
742
Since the buffer may be too small to hold the input,
743
this operation can fail due to attempted buffer overrun.
744
745
(This function is analogous to fgets for C standard library streams.)
746
747
@return
748
If the operation fails (e.g., due to an I/O error or attempted buffer overrun),
749
a null pointer is returned.
750
Otherwise, buffer is returned.
751
*/
752
JAS_EXPORT
753
char *jas_stream_gets(jas_stream_t *stream, char *buffer, int buffer_size);
754
755
/*!
756
@brief Look at the next character to be read from a stream without actually
757
removing the character from the stream.
758
759
@param stream
760
A pointer to the stream to be examined.
761
762
@details
763
This function examines the next character that would be read from the
764
stream and returns this character without actually removing it from the
765
stream.
766
767
@return
768
If the peek operation fails (e.g., due to EOF or I/O error),
769
EOF is returned.
770
Otherwise, the character that would be next read from the stream
771
is returned.
772
*/
773
#define jas_stream_peekc(stream) \
774
  (((stream)->cnt_ <= 0) ? jas_stream_fillbuf(stream, 0) : \
775
    ((int)(*(stream)->ptr_)))
776
777
/*!
778
@brief Put a character back on a stream.
779
780
@param stream
781
A pointer to the stream to which the character should be put back.
782
@param c
783
The character to put back.
784
785
@details
786
The character @c c (which was presumably read previously from the stream
787
@c stream) is put back on the stream (as if it had not yet been read).
788
In other words, this function undoes the effect of jas_stream_getc().
789
It is unspecified what happens if the character put back was not the
790
one originally read.
791
The number of characters that can be pushed back onto the stream
792
for subsequent reading is limited.
793
Trying to push back too many characters on a stream will result in an error.
794
The approximate limit is given by the value of JAS_STREAM_MAXPUTBACK.
795
796
@return
797
Upon success, zero is returned.
798
If the specified character cannot be pushed back, a negative value is returned.
799
*/
800
JAS_EXPORT
801
int jas_stream_ungetc(jas_stream_t *stream, int c);
802
803
/******************************************************************************\
804
* Macros/functions for getting/setting the stream position.
805
\******************************************************************************/
806
807
/*!
808
@brief Determine if stream supports seeking.
809
810
@param stream
811
A pointer to the stream to query.
812
813
@details
814
The function is a predicate that tests if the underlying file object
815
supports seek operations.
816
817
@return
818
If the underlying file object supports seek operations, a (strictly)
819
positive value is returned.
820
Otherwise, 0 is returned.
821
*/
822
JAS_EXPORT
823
JAS_ATTRIBUTE_PURE
824
int jas_stream_isseekable(jas_stream_t *stream);
825
826
/*!
827
@brief Set the current position within the stream.
828
829
@param stream
830
A pointer to the stream for which to set the current position.
831
@param offset
832
The new position for the stream.
833
@param origin
834
The origin to which this new position is relative.
835
836
@details
837
The origin can be SEEK_CUR, SEEK_SET, or SEEK_END
838
in a similar fashion as the fseek function in the C standard library
839
(and the lseek function in POSIX).
840
841
@return
842
Upon success, the new stream position is returned.
843
Upon failure, a negative value is returned.
844
*/
845
JAS_EXPORT
846
long jas_stream_seek(jas_stream_t *stream, long offset, int origin);
847
848
/*!
849
@brief Get the current position within the stream.
850
851
@param stream
852
A pointer to the stream whose current position is to be queried.
853
854
@details
855
The current position of the stream is returned.
856
857
(This function is analogous to ftell for C standard library streams.)
858
859
@return
860
Upon success, the current stream position is returned.
861
If an error is encountered, a negative value is returned.
862
*/
863
JAS_EXPORT
864
long jas_stream_tell(jas_stream_t *stream);
865
866
/*!
867
@brief Seek to the beginning of a stream.
868
869
@param stream
870
A pointer to the stream whose position is to be set.
871
872
@details
873
The stream position is set to the start of the stream.
874
This function is equivalent to returning the value
875
of jas_stream_seek(stream, 0, SEEK_SET).
876
877
(This function is analogous to frewind for C standard library streams.)
878
879
@return
880
Upon success, the new stream position is returned.
881
Otherwise, a negative value is returned.
882
*/
883
JAS_EXPORT
884
int jas_stream_rewind(jas_stream_t *stream);
885
886
/******************************************************************************\
887
* Macros/functions for flushing.
888
\******************************************************************************/
889
890
/*!
891
@brief Flush any pending output to a stream.
892
893
@param stream
894
A pointer to the stream for which output should be flushed.
895
896
@details
897
The function flushes any buffered output to the underlying file object.
898
899
(This function is analogous to fflush for C standard library streams.)
900
901
@return
902
Upon success, zero is returned.
903
Otherwise, a negative value is returned.
904
*/
905
JAS_EXPORT
906
int jas_stream_flush(jas_stream_t *stream);
907
908
/******************************************************************************\
909
* Miscellaneous macros/functions.
910
\******************************************************************************/
911
912
/*!
913
@brief Copy data from one stream to another.
914
915
@param destination
916
A pointer to the stream that is the destination for the copy.
917
@param source
918
A pointer to the stream that is the source for the copy.
919
@param count
920
The number of characters to copy.
921
922
@details
923
The function copies the specified number of characters from the
924
source stream to the destination stream.
925
In particular, if @c count is nonnegative, @c count characters are
926
copied from the source stream @c source to the destination stream
927
@c destination.
928
Otherwise (i.e., if @c count is negative), the entire source
929
stream @c source (i.e., until EOF is reached) is copied to the
930
destination stream @c destination.
931
932
@return
933
Upon success, 0 is returned; otherwise, -1 is returned.
934
935
@todo
936
TODO/FIXME: should return type be ssize_t and the return value be
937
the count of the characters copied?
938
Perhaps, it might be safer to introduce a new function with differing
939
semantics and deprecate this one?
940
*/
941
JAS_EXPORT
942
int jas_stream_copy(jas_stream_t *destination, jas_stream_t *source,
943
  ssize_t count);
944
945
/*!
946
@brief Print a hex dump of data read from a stream.
947
948
@param stream
949
A pointer to the stream from which to read data.
950
@param fp
951
A pointer to a stdio stream (i.e., FILE) to which to print the hex dump.
952
@param count
953
The number of characters to include in the hex dump.
954
955
@details
956
This function prints a hex dump of data read from a stream to a
957
stdio stream.
958
This function is most likely to be useful for debugging.
959
960
@return
961
Upon success, 0 is returned.
962
Otherwise, a negative value is returned.
963
964
@todo
965
TODO/FIXME: should count be unsigned int or size_t instead of int?
966
*/
967
JAS_EXPORT
968
int jas_stream_display(jas_stream_t *stream, FILE *fp, int count);
969
970
/*!
971
@brief Consume (i.e., discard) characters from stream.
972
973
@param stream
974
A pointer to the stream from which to discard data.
975
@param count
976
The number of characters to discard.
977
978
@details
979
This function reads and discards  the specified number of characters from the
980
given stream.
981
982
@return
983
This function returns the number of characters read and discarded.
984
If an error or EOF is encountered, the number of characters read
985
will be less than count.
986
To distinguish EOF from an I/O error, jas_stream_eof() and jas_stream_error()
987
can be used.
988
*/
989
JAS_EXPORT
990
ssize_t jas_stream_gobble(jas_stream_t *stream, size_t count);
991
992
/*!
993
@brief Write a fill character multiple times to a stream.
994
995
@param stream
996
A pointer to the stream to which to write.
997
@param count
998
The number of times to write the fill character to the stream.
999
@param value
1000
The fill character.
1001
1002
@details
1003
This function writes the given fill character to a stream a
1004
specified number of times.
1005
If a count of zero is specified, the function should have no effect.
1006
1007
@return
1008
The number of times the fill character was written to the stream is
1009
returned.
1010
If this value is less than the specified count, an error must have
1011
occurred.
1012
*/
1013
JAS_EXPORT
1014
ssize_t jas_stream_pad(jas_stream_t *stream, size_t count, int value);
1015
1016
/*!
1017
@brief Get the size of the file associated with the specified stream.
1018
1019
@param stream
1020
A pointer to the stream.
1021
1022
@details
1023
This function queries the size (i.e., length) of the underlying file object
1024
associated with the specified stream.
1025
The specified stream must be seekable.
1026
1027
@return
1028
Upon success, the size of the stream is returned.
1029
If an error occurs, a negative value is returned.
1030
1031
@todo
1032
Should the return type be long or ssize_t?  long is consistent with the
1033
type used for seek offsets.
1034
*/
1035
JAS_EXPORT
1036
long jas_stream_length(jas_stream_t *stream);
1037
1038
/******************************************************************************\
1039
* Internal functions.
1040
\******************************************************************************/
1041
1042
/* The following functions are for internal use only!  If you call them
1043
directly, you will die a horrible, miserable, and painful death! */
1044
1045
/* These prototypes need to be here for the sake of the stream_getc and
1046
stream_putc macros. */
1047
/* Library users must not invoke these functions directly. */
1048
JAS_EXPORT int jas_stream_fillbuf(jas_stream_t *stream, int getflag);
1049
JAS_EXPORT int jas_stream_flushbuf(jas_stream_t *stream, int c);
1050
JAS_EXPORT int jas_stream_getc_func(jas_stream_t *stream);
1051
JAS_EXPORT int jas_stream_putc_func(jas_stream_t *stream, int c);
1052
1053
/* Read a character from a stream. */
1054
static inline int jas_stream_getc2(jas_stream_t *stream)
1055
0
{
1056
0
  if (--stream->cnt_ < 0)
1057
0
    return jas_stream_fillbuf(stream, 1);
1058
0
1059
0
  ++stream->rwcnt_;
1060
0
  return (int)(*stream->ptr_++);
1061
0
}
1062
1063
static inline int jas_stream_getc_macro(jas_stream_t *stream)
1064
0
{
1065
0
  if (stream->flags_ & (JAS_STREAM_ERR | JAS_STREAM_EOF | JAS_STREAM_RWLIMIT))
1066
0
    return EOF;
1067
0
1068
0
  if (stream->rwlimit_ >= 0 && stream->rwcnt_ >= stream->rwlimit_) {
1069
0
    stream->flags_ |= JAS_STREAM_RWLIMIT;
1070
0
    return EOF;
1071
0
  }
1072
0
1073
0
  return jas_stream_getc2(stream);
1074
0
}
1075
1076
/* Write a character to a stream. */
1077
static inline int jas_stream_putc2(jas_stream_t *stream, jas_uchar c)
1078
0
{
1079
0
  stream->bufmode_ |= JAS_STREAM_WRBUF;
1080
0
1081
0
  if (--stream->cnt_ < 0)
1082
0
    return jas_stream_flushbuf(stream, c);
1083
0
  else {
1084
0
    ++stream->rwcnt_;
1085
0
    return (int)(*stream->ptr_++ = c);
1086
0
  }
1087
0
}
1088
1089
static inline int jas_stream_putc_macro(jas_stream_t *stream, jas_uchar c)
1090
0
{
1091
0
  if (stream->flags_ & (JAS_STREAM_ERR | JAS_STREAM_EOF | JAS_STREAM_RWLIMIT))
1092
0
      return EOF;
1093
0
1094
0
  if (stream->rwlimit_ >= 0 && stream->rwcnt_ >= stream->rwlimit_) {
1095
0
    stream->flags_ |= JAS_STREAM_RWLIMIT;
1096
0
    return EOF;
1097
0
  }
1098
0
1099
0
  return jas_stream_putc2(stream, c);
1100
0
}
1101
1102
/*!
1103
 * @}
1104
 */
1105
1106
#ifdef __cplusplus
1107
}
1108
#endif
1109
1110
#endif