1 | #include "fitz-imp.h" |
2 | |
3 | #include <zlib.h> |
4 | |
5 | #include <string.h> |
6 | |
7 | typedef struct fz_leech_s fz_leech; |
8 | |
9 | struct fz_leech_s |
10 | { |
11 | fz_stream *chain; |
12 | fz_buffer *buffer; |
13 | }; |
14 | |
15 | static int |
16 | next_leech(fz_context *ctx, fz_stream *stm, size_t max) |
17 | { |
18 | fz_leech *state = stm->state; |
19 | fz_buffer *buffer = state->buffer; |
20 | size_t n = fz_available(ctx, state->chain, max); |
21 | |
22 | if (n > max) |
23 | n = max; |
24 | |
25 | while (buffer->cap < buffer->len + n) |
26 | { |
27 | fz_grow_buffer(ctx, state->buffer); |
28 | } |
29 | memcpy(buffer->data + buffer->len, state->chain->rp, n); |
30 | stm->rp = buffer->data + buffer->len; |
31 | stm->wp = buffer->data + buffer->len + n; |
32 | state->chain->rp += n; |
33 | buffer->len += n; |
34 | |
35 | if (n == 0) |
36 | return EOF; |
37 | return *stm->rp++; |
38 | } |
39 | |
40 | static void |
41 | close_leech(fz_context *ctx, void *state_) |
42 | { |
43 | fz_leech *state = (fz_leech *)state_; |
44 | fz_drop_stream(ctx, state->chain); |
45 | fz_drop_buffer(ctx, state->buffer); |
46 | fz_free(ctx, state); |
47 | } |
48 | |
49 | /* |
50 | Attach a filter to a stream that will store any |
51 | characters read from the stream into the supplied buffer. |
52 | |
53 | chain: The underlying stream to leech from. |
54 | |
55 | buf: The buffer into which the read data should be appended. |
56 | The buffer will be resized as required. |
57 | |
58 | Returns pointer to newly created stream. May throw exceptions on |
59 | failure to allocate. |
60 | */ |
61 | fz_stream * |
62 | fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buffer) |
63 | { |
64 | fz_leech *state = fz_malloc_struct(ctx, fz_leech); |
65 | state->chain = fz_keep_stream(ctx, chain); |
66 | state->buffer = fz_keep_buffer(ctx, buffer); |
67 | return fz_new_stream(ctx, state, next_leech, close_leech); |
68 | } |
69 | |