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"); } }
fz_error * fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out) { fz_pipeline *p = (fz_pipeline*)filter; fz_error *e; if (p->buffer->eof) goto tail; if (p->tailneedsin && p->head->produced) goto tail; head: e = fz_process(p->head, in, p->buffer); if (e == fz_ioneedin) return fz_ioneedin; else if (e == fz_ioneedout) { if (p->tailneedsin && !p->head->produced) { fz_error *be = nil; if (p->buffer->rp > p->buffer->bp) be = fz_rewindbuffer(p->buffer); else be = fz_growbuffer(p->buffer); if (be) return be; goto head; } goto tail; } else if (e == fz_iodone) goto tail; else return e; tail: e = fz_process(p->tail, p->buffer, out); if (e == fz_ioneedin) { if (p->buffer->eof) return fz_throw("ioerror: premature eof in pipeline"); p->tailneedsin = 1; goto head; } else if (e == fz_ioneedout) { p->tailneedsin = 0; return fz_ioneedout; } else if (e == fz_iodone) return fz_iodone; else return e; }