Beispiel #1
0
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;
}