Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7858 views
1
#ifndef MUPDF_FITZ_STREAM_H
2
#define MUPDF_FITZ_STREAM_H
3
4
#include "mupdf/fitz/system.h"
5
#include "mupdf/fitz/context.h"
6
#include "mupdf/fitz/buffer.h"
7
8
/*
9
fz_stream is a buffered reader capable of seeking in both
10
directions.
11
12
Streams are reference counted, so references must be dropped
13
by a call to fz_drop_stream.
14
15
Only the data between rp and wp is valid.
16
*/
17
typedef struct fz_stream_s fz_stream;
18
19
/*
20
fz_open_file: Open the named file and wrap it in a stream.
21
22
filename: Path to a file. On non-Windows machines the filename should
23
be exactly as it would be passed to open(2). On Windows machines, the
24
path should be UTF-8 encoded so that non-ASCII characters can be
25
represented. Other platforms do the encoding as standard anyway (and
26
in most cases, particularly for MacOS and Linux, the encoding they
27
use is UTF-8 anyway).
28
*/
29
fz_stream *fz_open_file(fz_context *ctx, const char *filename);
30
31
fz_stream *fz_open_fd_progressive(fz_context *ctx, int fd, int bps);
32
fz_stream *fz_open_file_progressive(fz_context *ctx, const char *filename, int bps);
33
34
/*
35
fz_open_file_w: Open the named file and wrap it in a stream.
36
37
This function is only available when compiling for Win32.
38
39
filename: Wide character path to the file as it would be given
40
to _wopen().
41
*/
42
fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename);
43
44
/*
45
fz_open_fd: Wrap an open file descriptor in a stream.
46
47
file: An open file descriptor supporting bidirectional
48
seeking. The stream will take ownership of the file
49
descriptor, so it may not be modified or closed after the call
50
to fz_open_fd. When the stream is closed it will also close
51
the file descriptor.
52
*/
53
fz_stream *fz_open_fd(fz_context *ctx, int file);
54
55
/*
56
fz_open_memory: Open a block of memory as a stream.
57
58
data: Pointer to start of data block. Ownership of the data block is
59
NOT passed in.
60
61
len: Number of bytes in data block.
62
63
Returns pointer to newly created stream. May throw exceptions on
64
failure to allocate.
65
*/
66
fz_stream *fz_open_memory(fz_context *ctx, unsigned char *data, int len);
67
68
/*
69
fz_open_buffer: Open a buffer as a stream.
70
71
buf: The buffer to open. Ownership of the buffer is NOT passed in
72
(this function takes it's own reference).
73
74
Returns pointer to newly created stream. May throw exceptions on
75
failure to allocate.
76
*/
77
fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
78
79
/*
80
fz_open_leecher: Attach a filter to a stream that will store any
81
characters read from the stream into the supplied buffer.
82
83
chain: The underlying stream to leech from.
84
85
buf: The buffer into which the read data should be appended.
86
The buffer will be resized as required.
87
88
Returns pointer to newly created stream. May throw exceptions on
89
failure to allocate.
90
*/
91
fz_stream *fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buf);
92
93
/*
94
fz_drop_stream: Close an open stream.
95
96
Drops a reference for the stream. Once no references remain
97
the stream will be closed, as will any file descriptor the
98
stream is using.
99
100
Does not throw exceptions.
101
*/
102
void fz_drop_stream(fz_context *ctx, fz_stream *stm);
103
104
/*
105
fz_tell: return the current reading position within a stream
106
*/
107
int fz_tell(fz_context *ctx, fz_stream *stm);
108
109
/*
110
fz_seek: Seek within a stream.
111
112
stm: The stream to seek within.
113
114
offset: The offset to seek to.
115
116
whence: From where the offset is measured (see fseek).
117
*/
118
void fz_seek(fz_context *ctx, fz_stream *stm, int offset, int whence);
119
120
/*
121
fz_read: Read from a stream into a given data block.
122
123
stm: The stream to read from.
124
125
data: The data block to read into.
126
127
len: The length of the data block (in bytes).
128
129
Returns the number of bytes read. May throw exceptions.
130
*/
131
int fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, int len);
132
133
/*
134
fz_read_all: Read all of a stream into a buffer.
135
136
stm: The stream to read from
137
138
initial: Suggested initial size for the buffer.
139
140
Returns a buffer created from reading from the stream. May throw
141
exceptions on failure to allocate.
142
*/
143
fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, int initial);
144
145
/*
146
fz_read_file: Read all the contents of a file into a buffer.
147
*/
148
fz_buffer *fz_read_file(fz_context *ctx, const char *filename);
149
150
enum
151
{
152
FZ_STREAM_META_PROGRESSIVE = 1,
153
FZ_STREAM_META_LENGTH = 2
154
};
155
156
int fz_stream_meta(fz_context *ctx, fz_stream *stm, int key, int size, void *ptr);
157
158
typedef int (fz_stream_next_fn)(fz_context *ctx, fz_stream *stm, int max);
159
typedef void (fz_stream_close_fn)(fz_context *ctx, void *state);
160
typedef void (fz_stream_seek_fn)(fz_context *ctx, fz_stream *stm, int offset, int whence);
161
typedef int (fz_stream_meta_fn)(fz_context *ctx, fz_stream *stm, int key, int size, void *ptr);
162
163
struct fz_stream_s
164
{
165
int refs;
166
int error;
167
int eof;
168
int pos;
169
int avail;
170
int bits;
171
unsigned char *rp, *wp;
172
void *state;
173
fz_stream_next_fn *next;
174
fz_stream_close_fn *close;
175
fz_stream_seek_fn *seek;
176
fz_stream_meta_fn *meta;
177
};
178
179
fz_stream *fz_new_stream(fz_context *ctx, void *state, fz_stream_next_fn *next, fz_stream_close_fn *close);
180
181
fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm);
182
183
/*
184
fz_read_best: Attempt to read a stream into a buffer. If truncated
185
is NULL behaves as fz_read_all, otherwise does not throw exceptions
186
in the case of failure, but instead sets a truncated flag.
187
188
stm: The stream to read from.
189
190
initial: Suggested initial size for the buffer.
191
192
truncated: Flag to store success/failure indication in.
193
194
Returns a buffer created from reading from the stream.
195
*/
196
fz_buffer *fz_read_best(fz_context *ctx, fz_stream *stm, int initial, int *truncated);
197
198
void fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, int max);
199
200
/*
201
fz_available: Ask how many bytes are available immediately from
202
a given stream.
203
204
stm: The stream to read from.
205
206
max: A hint for the underlying stream; the maximum number of
207
bytes that we are sure we will want to read. If you do not know
208
this number, give 1.
209
210
Returns the number of bytes immediately available between the
211
read and write pointers. This number is guaranteed only to be 0
212
if we have hit EOF. The number of bytes returned here need have
213
no relation to max (could be larger, could be smaller).
214
*/
215
static inline size_t fz_available(fz_context *ctx, fz_stream *stm, int max)
216
{
217
size_t len = stm->wp - stm->rp;
218
int c = EOF;
219
220
if (len)
221
return len;
222
fz_try(ctx)
223
{
224
c = stm->next(ctx, stm, max);
225
}
226
fz_catch(ctx)
227
{
228
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
229
fz_warn(ctx, "read error; treating as end of file");
230
stm->error = 1;
231
c = EOF;
232
}
233
if (c == EOF)
234
{
235
stm->eof = 1;
236
return 0;
237
}
238
stm->rp--;
239
return stm->wp - stm->rp;
240
}
241
242
static inline int fz_read_byte(fz_context *ctx, fz_stream *stm)
243
{
244
int c = EOF;
245
246
if (stm->rp != stm->wp)
247
return *stm->rp++;
248
fz_try(ctx)
249
{
250
c = stm->next(ctx, stm, 1);
251
}
252
fz_catch(ctx)
253
{
254
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
255
fz_warn(ctx, "read error; treating as end of file");
256
stm->error = 1;
257
c = EOF;
258
}
259
if (c == EOF)
260
stm->eof = 1;
261
return c;
262
}
263
264
static inline int fz_peek_byte(fz_context *ctx, fz_stream *stm)
265
{
266
int c;
267
268
if (stm->rp != stm->wp)
269
return *stm->rp;
270
271
c = stm->next(ctx, stm, 1);
272
if (c != EOF)
273
stm->rp--;
274
return c;
275
}
276
277
static inline void fz_unread_byte(fz_context *ctx, fz_stream *stm)
278
{
279
stm->rp--;
280
}
281
282
static inline int fz_is_eof(fz_context *ctx, fz_stream *stm)
283
{
284
if (stm->rp == stm->wp)
285
{
286
if (stm->eof)
287
return 1;
288
return fz_peek_byte(ctx, stm) == EOF;
289
}
290
return 0;
291
}
292
293
static inline unsigned int fz_read_bits(fz_context *ctx, fz_stream *stm, int n)
294
{
295
unsigned int x;
296
297
if (n <= stm->avail)
298
{
299
stm->avail -= n;
300
x = (stm->bits >> stm->avail) & ((1 << n) - 1);
301
}
302
else
303
{
304
x = stm->bits & ((1 << stm->avail) - 1);
305
n -= stm->avail;
306
stm->avail = 0;
307
308
while (n > 8)
309
{
310
x = (x << 8) | fz_read_byte(ctx, stm);
311
n -= 8;
312
}
313
314
if (n > 0)
315
{
316
stm->bits = fz_read_byte(ctx, stm);
317
stm->avail = 8 - n;
318
x = (x << n) | (stm->bits >> stm->avail);
319
}
320
}
321
322
return x;
323
}
324
325
static inline void fz_sync_bits(fz_context *ctx, fz_stream *stm)
326
{
327
stm->avail = 0;
328
}
329
330
static inline int fz_is_eof_bits(fz_context *ctx, fz_stream *stm)
331
{
332
return fz_is_eof(ctx, stm) && (stm->avail == 0 || stm->bits == EOF);
333
}
334
335
#endif
336
337