summaryrefslogtreecommitdiff
path: root/fitz/stm_read.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-29 23:17:46 +0000
committerTor Andersson <tor@ghostscript.com>2010-07-29 23:17:46 +0000
commitd797d4707564bd9c0e1536d1d6355945aa1be740 (patch)
treeb6aef992de0ce2aa306c4dd330512852c1a63ede /fitz/stm_read.c
parent0b954421d7908c8b835d96b4a945418c2ae08de7 (diff)
downloadmupdf-d797d4707564bd9c0e1536d1d6355945aa1be740.tar.xz
Use chained reader like interface for filters instead of process interface.
Diffstat (limited to 'fitz/stm_read.c')
-rw-r--r--fitz/stm_read.c354
1 files changed, 67 insertions, 287 deletions
diff --git a/fitz/stm_read.c b/fitz/stm_read.c
index d4d27f66..3bdddade 100644
--- a/fitz/stm_read.c
+++ b/fitz/stm_read.c
@@ -1,283 +1,91 @@
#include "fitz.h"
-fz_error
-fz_readimp(fz_stream *stm)
-{
- fz_buffer *buf = stm->buffer;
- fz_error error;
- fz_error reason;
- int produced;
- int n;
-
- if (stm->dead)
- return fz_throw("assert: read from dead stream");
-
- if (buf->eof)
- return fz_okay;
-
- fz_rewindbuffer(buf);
- if (buf->ep - buf->wp == 0)
- fz_growbuffer(buf);
-
- switch (stm->kind)
- {
-
- case FZ_SFILE:
- n = read(stm->file, buf->wp, buf->ep - buf->wp);
- if (n == -1)
- {
- stm->dead = 1;
- return fz_throw("syserr: read: %s", strerror(errno));
- }
-
- if (n == 0)
- buf->eof = 1;
- buf->wp += n;
-
- return fz_okay;
-
- case FZ_SFILTER:
- produced = 0;
-
- while (1)
- {
- reason = fz_process(stm->filter, stm->chain->buffer, buf);
-
- if (stm->filter->produced)
- produced = 1;
-
- if (reason == fz_ioneedin)
- {
- error = fz_readimp(stm->chain);
- if (error)
- {
- stm->dead = 1;
- return fz_rethrow(error, "cannot read from input stream");
- }
- }
-
- else if (reason == fz_ioneedout)
- {
- if (produced)
- return 0;
-
- if (buf->rp > buf->bp)
- fz_rewindbuffer(buf);
- else
- fz_growbuffer(buf);
- }
-
- else if (reason == fz_iodone)
- {
- return fz_okay;
- }
-
- else
- {
- stm->dead = 1;
- return fz_rethrow(reason, "cannot process filter");
- }
- }
-
- case FZ_SBUFFER:
- return fz_okay;
-
- default:
- return fz_throw("assert: unknown stream type");
- }
-}
-
int
-fz_tell(fz_stream *stm)
+fz_read(fz_stream *stm, unsigned char *buf, int len)
{
- fz_buffer *buf = stm->buffer;
- int t;
-
- if (stm->dead)
- return EOF;
+ int avail, count;
- switch (stm->kind)
+ avail = stm->wp - stm->rp;
+ if (avail)
{
- case FZ_SFILE:
- t = lseek(stm->file, 0, 1);
- if (t < 0)
- {
- fz_warn("syserr: lseek: %s", strerror(errno));
- stm->dead = 1;
- return EOF;
- }
- return t - (buf->wp - buf->rp);
-
- case FZ_SFILTER:
- return stm->filter->count - (buf->wp - buf->rp);
-
- case FZ_SBUFFER:
- return buf->rp - buf->bp;
-
- default:
- return EOF;
+ count = MIN(len, avail);
+ memcpy(buf, stm->rp, count);
+ stm->rp += count;
}
-}
-
-fz_error
-fz_seek(fz_stream *stm, int offset, int whence)
-{
- fz_error error;
- fz_buffer *buf = stm->buffer;
- int t, c;
-
- if (stm->dead)
- return fz_throw("assert: seek in dead stream");
-
- if (whence == 1)
+ else
{
- int cur = fz_tell(stm);
- if (cur < 0)
- return fz_throw("cannot tell current position");
- offset = cur + offset;
- whence = 0;
+ count = 0;
}
- buf->eof = 0;
+ if (stm->dead)
+ return count;
- switch (stm->kind)
+ while (len > count)
{
- case FZ_SFILE:
- t = lseek(stm->file, offset, whence);
- if (t < 0)
+ int n = stm->read(stm, buf + count, len - count);
+ if (n < 0)
{
stm->dead = 1;
- return fz_throw("syserr: lseek: %s", strerror(errno));
- }
-
- buf->rp = buf->bp;
- buf->wp = buf->bp;
-
- return fz_okay;
-
- case FZ_SFILTER:
- if (whence == 0)
- {
- if (offset < fz_tell(stm))
- {
- stm->dead = 1;
- return fz_throw("assert: seek backwards in filter");
- }
- while (fz_tell(stm) < offset)
- {
- c = fz_readbyte(stm);
- if (c == EOF)
- {
- error = fz_readerror(stm);
- if (error)
- return fz_rethrow(error, "cannot seek forward in filter");
- break;
- }
- }
- return fz_okay;
+ return fz_rethrow(n, "read error");
}
-
- stm->dead = 1;
- return fz_throw("assert: relative seek in filter");
-
- case FZ_SBUFFER:
- if (whence == 0)
- buf->rp = CLAMP(buf->bp + offset, buf->bp, buf->ep);
- else
- buf->rp = CLAMP(buf->ep + offset, buf->bp, buf->ep);
- return fz_okay;
-
- default:
- return fz_throw("unknown stream type");
+ if (n == 0)
+ break;
+ stm->pos += n;
+ count += n;
}
+
+ return count;
}
-fz_error
-fz_read(int *np, fz_stream *stm, unsigned char *mem, int n)
+void
+fz_fillbuffer(fz_stream *stm)
{
- fz_error error;
- fz_buffer *buf = stm->buffer;
- int i = 0;
-
- while (i < n)
- {
- while (buf->rp < buf->wp && i < n)
- mem[i++] = *buf->rp++;
+ int n;
- if (buf->rp == buf->wp)
- {
- if (buf->eof)
- {
- *np = i;
- return fz_okay;
- }
+ assert(stm->rp == stm->wp);
- error = fz_readimp(stm);
- if (error)
- return fz_rethrow(error, "cannot produce data");
- }
+ n = fz_read(stm, stm->bp, stm->ep - stm->bp);
+ if (n < 0)
+ fz_catch(n, "read error; treating as end of file");
+ else
+ {
+ stm->rp = stm->bp;
+ stm->wp = stm->bp + n;
}
-
- *np = i;
- return fz_okay;
}
fz_error
-fz_readerror(fz_stream *stm)
+fz_readall(fz_buffer **bufp, fz_stream *stm)
{
- fz_error error;
- if (stm->error)
- {
- error = stm->error;
- stm->error = fz_okay;
- return fz_rethrow(error, "delayed read error");
- }
- return fz_okay;
-}
+ fz_buffer *buf;
+ int n;
-int
-fz_readbytex(fz_stream *stm)
-{
- fz_buffer *buf = stm->buffer;
+ buf = fz_newbuffer(16 * 1024);
- if (buf->rp == buf->wp)
+ while (1)
{
- if (!buf->eof && !stm->error)
- {
- fz_error error = fz_readimp(stm);
- if (error)
- stm->error = fz_rethrow(error, "cannot read data");
- }
- }
-
- return buf->rp < buf->wp ? *buf->rp++ : EOF ;
-}
-
-int
-fz_peekbytex(fz_stream *stm)
-{
- fz_buffer *buf = stm->buffer;
+ if (buf->len == buf->cap)
+ fz_growbuffer(buf);
- if (buf->rp == buf->wp)
- {
- if (!buf->eof && !stm->error)
+ n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len);
+ if (n < 0)
{
- fz_error error = fz_readimp(stm);
- if (error)
- stm->error = fz_rethrow(error, "cannot read data");
+ fz_dropbuffer(buf);
+ return fz_rethrow(n, "read error");
}
+ if (n == 0)
+ break;
+
+ buf->len += n;
}
- return buf->rp < buf->wp ? *buf->rp : EOF ;
+ *bufp = buf;
+ return fz_okay;
}
-/* Read a line terminated by LF or CR or CRLF. */
-
-fz_error
+void
fz_readline(fz_stream *stm, char *mem, int n)
{
- fz_error error;
-
char *s = mem;
int c = EOF;
while (n > 1)
@@ -298,57 +106,29 @@ fz_readline(fz_stream *stm, char *mem, int n)
}
if (n)
*s = '\0';
-
- error = fz_readerror(stm);
- if (error)
- return fz_rethrow(error, "cannot read line");
- return fz_okay;
}
-static inline int
-fz_fillbuf(fz_stream *stm, fz_buffer *buf)
+int
+fz_tell(fz_stream *stm)
{
- int remaining = buf->ep - buf->wp;
- int available = stm->buffer->wp - stm->buffer->rp;
-
- if (available == 0 && remaining > 0)
- {
- int c = fz_readbytex(stm);
- if (c == EOF)
- return EOF;
-
- *buf->wp++ = c;
-
- remaining = buf->ep - buf->wp;
- available = stm->buffer->wp - stm->buffer->rp;
- }
-
- memmove(buf->wp, stm->buffer->rp, MIN(remaining, available));
- buf->wp += MIN(remaining, available);
- stm->buffer->rp += MIN(remaining, available);
-
- if (stm->buffer->rp == stm->buffer->wp && stm->buffer->eof)
- return EOF;
- return 0;
+ return stm->pos - (stm->wp - stm->rp);
}
-/* Read the contents of an input stream into a new buffer. */
-
-fz_buffer *
-fz_readall(fz_stream *stm, int sizehint)
+void
+fz_seek(fz_stream *stm, int offset, int whence)
{
- fz_buffer *buf;
-
- if (sizehint == 0)
- sizehint = 4 * 1024;
-
- buf = fz_newbuffer(sizehint);
-
- while (fz_fillbuf(stm, buf) != EOF)
+ if (stm->seek)
+ stm->seek(stm, offset, whence);
+ else if (whence != 2)
{
- if (buf->wp == buf->ep)
- fz_growbuffer(buf);
+ if (whence == 0)
+ offset -= fz_tell(stm);
+ if (offset < 0)
+ fz_warn("cannot seek backwards");
+ /* dog slow, but rare enough */
+ while (offset-- > 0)
+ fz_readbyte(stm);
}
-
- return buf;
+ else
+ fz_warn("cannot seek");
}