summaryrefslogtreecommitdiff
path: root/source/fitz/stream-read.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-06-19 15:29:44 +0200
committerTor Andersson <tor.andersson@artifex.com>2013-06-20 16:45:35 +0200
commit0a927854a10e1e6b9770a81e2e1d9f3093631757 (patch)
tree3d65d820d9fdba2d0d394d99c36290c851b78ca0 /source/fitz/stream-read.c
parent1ae8f19179c5f0f8c6352b3c7855465325d5449a (diff)
downloadmupdf-0a927854a10e1e6b9770a81e2e1d9f3093631757.tar.xz
Rearrange source files.
Diffstat (limited to 'source/fitz/stream-read.c')
-rw-r--r--source/fitz/stream-read.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/source/fitz/stream-read.c b/source/fitz/stream-read.c
new file mode 100644
index 00000000..ee3d1cad
--- /dev/null
+++ b/source/fitz/stream-read.c
@@ -0,0 +1,219 @@
+#include "mupdf/fitz.h"
+
+#define MIN_BOMB (100 << 20)
+
+int
+fz_read(fz_stream *stm, unsigned char *buf, int len)
+{
+ int count, n;
+
+ count = fz_mini(len, stm->wp - stm->rp);
+ if (count)
+ {
+ memcpy(buf, stm->rp, count);
+ stm->rp += count;
+ }
+
+ if (count == len || stm->error || stm->eof)
+ return count;
+
+ assert(stm->rp == stm->wp);
+
+ if (len - count < stm->ep - stm->bp)
+ {
+ n = stm->read(stm, stm->bp, stm->ep - stm->bp);
+ if (n == 0)
+ {
+ stm->eof = 1;
+ }
+ else if (n > 0)
+ {
+ stm->rp = stm->bp;
+ stm->wp = stm->bp + n;
+ stm->pos += n;
+ }
+
+ n = fz_mini(len - count, stm->wp - stm->rp);
+ if (n)
+ {
+ memcpy(buf + count, stm->rp, n);
+ stm->rp += n;
+ count += n;
+ }
+ }
+ else
+ {
+ n = stm->read(stm, buf + count, len - count);
+ if (n == 0)
+ {
+ stm->eof = 1;
+ }
+ else if (n > 0)
+ {
+ stm->pos += n;
+ count += n;
+ }
+ }
+
+ return count;
+}
+
+void
+fz_fill_buffer(fz_stream *stm)
+{
+ int n;
+
+ assert(stm->rp == stm->wp);
+
+ if (stm->error || stm->eof)
+ return;
+
+ fz_try(stm->ctx)
+ {
+ n = stm->read(stm, stm->bp, stm->ep - stm->bp);
+ if (n == 0)
+ {
+ stm->eof = 1;
+ }
+ else if (n > 0)
+ {
+ stm->rp = stm->bp;
+ stm->wp = stm->bp + n;
+ stm->pos += n;
+ }
+ }
+ fz_catch(stm->ctx)
+ {
+ /* FIXME: TryLater */
+ fz_warn(stm->ctx, "read error; treating as end of file");
+ stm->error = 1;
+ }
+}
+
+fz_buffer *
+fz_read_all(fz_stream *stm, int initial)
+{
+ return fz_read_best(stm, initial, NULL);
+}
+
+fz_buffer *
+fz_read_best(fz_stream *stm, int initial, int *truncated)
+{
+ fz_buffer *buf = NULL;
+ int n;
+ fz_context *ctx = stm->ctx;
+
+ fz_var(buf);
+
+ if (truncated)
+ *truncated = 0;
+
+ fz_try(ctx)
+ {
+ if (initial < 1024)
+ initial = 1024;
+
+ buf = fz_new_buffer(ctx, initial+1);
+
+ while (1)
+ {
+ if (buf->len == buf->cap)
+ fz_grow_buffer(ctx, buf);
+
+ if (buf->len >= MIN_BOMB && buf->len / 200 > initial)
+ {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "compression bomb detected");
+ }
+
+ n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len);
+ if (n == 0)
+ break;
+
+ buf->len += n;
+ }
+ }
+ fz_catch(ctx)
+ {
+ /* FIXME: TryLater */
+ if (truncated)
+ {
+ *truncated = 1;
+ }
+ else
+ {
+ fz_drop_buffer(ctx, buf);
+ fz_rethrow(ctx);
+ }
+ }
+ fz_trim_buffer(ctx, buf);
+
+ return buf;
+}
+
+void
+fz_read_line(fz_stream *stm, char *mem, int n)
+{
+ char *s = mem;
+ int c = EOF;
+ while (n > 1)
+ {
+ c = fz_read_byte(stm);
+ if (c == EOF)
+ break;
+ if (c == '\r') {
+ c = fz_peek_byte(stm);
+ if (c == '\n')
+ fz_read_byte(stm);
+ break;
+ }
+ if (c == '\n')
+ break;
+ *s++ = c;
+ n--;
+ }
+ if (n)
+ *s = '\0';
+}
+
+int
+fz_tell(fz_stream *stm)
+{
+ return stm->pos - (stm->wp - stm->rp);
+}
+
+void
+fz_seek(fz_stream *stm, int offset, int whence)
+{
+ if (stm->seek)
+ {
+ if (whence == 1)
+ {
+ offset = fz_tell(stm) + offset;
+ whence = 0;
+ }
+ if (whence == 0)
+ {
+ int dist = stm->pos - offset;
+ if (dist >= 0 && dist <= stm->wp - stm->bp)
+ {
+ stm->rp = stm->wp - dist;
+ stm->eof = 0;
+ return;
+ }
+ }
+ stm->seek(stm, offset, whence);
+ stm->eof = 0;
+ }
+ else if (whence != 2)
+ {
+ if (whence == 0)
+ offset -= fz_tell(stm);
+ if (offset < 0)
+ fz_warn(stm->ctx, "cannot seek backwards");
+ /* dog slow, but rare enough */
+ while (offset-- > 0)
+ fz_read_byte(stm);
+ }
+ else
+ fz_warn(stm->ctx, "cannot seek");
+}