Esempio n. 1
0
/* <file> <string> .peekstring <substring> <filled_bool> */
static int
zpeekstring(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    stream *s;
    uint len, rlen;

    check_read_file(s, op - 1);
    check_write_type(*op, t_string);
    len = r_size(op);
    while ((rlen = sbufavailable(s)) < len) {
	int status = s->end_status;

	switch (status) {
	case EOFC:
	    break;
	case 0:
	    /*
	     * The following is a HACK.  It should reallocate the buffer to hold
	     * at least len bytes.  However, this raises messy problems about
	     * which allocator to use and how it should interact with restore.
	     */
	    if (len >= s->bsize)
		return_error(e_rangecheck);
	    s_process_read_buf(s);
	    continue;
	default:
	    return handle_read_status(i_ctx_p, status, op - 1, NULL,
				      zpeekstring);
	}
	break;
    }
    if (rlen > len)
	rlen = len;
    /* Don't remove the data from the buffer. */
    memcpy(op->value.bytes, sbufptr(s), rlen);
    r_set_size(op, rlen);
    op[-1] = *op;
    make_bool(op, (rlen == len ? 1 : 0));
    return 0;
}
Esempio n. 2
0
/* Continue processing data from an image with file data sources. */
static int
image_file_continue(i_ctx_t *i_ctx_p)
{
    gs_image_enum *penum = r_ptr(esp, gs_image_enum);
    int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;

    for (;;) {
	uint min_avail = max_int;
	gs_const_string plane_data[gs_image_max_planes];
	int code;
	int px;
	const ref *pp;
	bool at_eof = false;

	/*
	 * Do a first pass through the files to ensure that at least
	 * one has data available in its buffer.
	 */

	for (px = 0, pp = ETOP_SOURCE(esp, 0); px < num_sources;
	     ++px, pp -= 2
	    ) {
	    int num_aliases = pp[1].value.intval;
	    stream *s = pp->value.pfile;
	    int min_left;
	    uint avail;

	    if (num_aliases <= 0)
		num_aliases = ETOP_SOURCE(esp, -num_aliases)[1].value.intval;
	    while ((avail = sbufavailable(s)) <=
		   (min_left = sbuf_min_left(s)) + num_aliases - 1) {
		int next = s->end_status;

		switch (next) {
		case 0:
		    s_process_read_buf(s);
		    continue;
		case EOFC:
		    at_eof = true;
		    break;	/* with no data available */
		case INTC:
		case CALLC:
		    return
			s_handle_read_exception(i_ctx_p, next, pp,
						NULL, 0, image_file_continue);
		default:
		    /* case ERRC: */
		    return_error(e_ioerror);
		}
		break;		/* for EOFC */
	    }
	    /*
	     * Note that in the EOF case, we can get here with no data
	     * available.
	     */
	    if (avail >= min_left)
		avail = (avail - min_left) / num_aliases; /* may be 0 */
	    if (avail < min_avail)
		min_avail = avail;
	    plane_data[px].data = sbufptr(s);
	    plane_data[px].size = avail;
	}

	/*
	 * Now pass the available buffered data to the image processor.
	 * Even if there is no available data, we must call
	 * gs_image_next_planes one more time to finish processing any
	 * retained data.
	 */

	{
	    int pi;
	    uint used[gs_image_max_planes];

	    code = gs_image_next_planes(penum, plane_data, used);
	    /* Now that used has been set, update the streams. */
	    for (pi = 0, pp = ETOP_SOURCE(esp, 0); pi < num_sources;
		 ++pi, pp -= 2
		 )
		sbufskip(pp->value.pfile, used[pi]);
	    if (code == e_RemapColor)
		return code;
	}
	if (at_eof)
	    code = 1;
	if (code) {
	    int code1;

	    esp = zimage_pop_estack(esp);
	    code1 = image_cleanup(i_ctx_p);
	    return (code < 0 ? code : code1 < 0 ? code1 : o_pop_estack);
	}
    }
}