Ejemplo n.º 1
0
/* Procedures for reading from a file */
static int
s_fileno_available(register stream * s, long *pl)
{
    long max_avail = s->file_limit - stell(s);
    long buf_avail = sbufavailable(s);
    int fd = sfileno(s);

    *pl = min(max_avail, buf_avail);
    if (sseekable(s)) {
        long pos, end;

        pos = ltell(fd);
        if (pos < 0)
            return ERRC;
        end = lseek(fd, 0L, SEEK_END);
        if (lseek(fd, pos, SEEK_SET) < 0 || end < 0)
            return ERRC;
        buf_avail += end - pos;
        *pl = min(max_avail, buf_avail);
        if (*pl == 0)
            *pl = -1;		/* EOF */
    } else {
        if (*pl == 0)
            *pl = -1;		/* EOF */
    }
    return 0;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
static int
zreusablestream(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr source_op = op - 1;
    long length = max_long;
    bool close_source;
    int code;

    check_type(*op, t_boolean);
    close_source = op->value.boolval;
    if (r_has_type(source_op, t_string)) {
        uint size = r_size(source_op);

        check_read(*source_op);
        code = make_rss(i_ctx_p, source_op, source_op->value.const_bytes,
                        size, r_space(source_op), 0L, size, false);
    } else if (r_has_type(source_op, t_astruct)) {
        uint size = gs_object_size(imemory, source_op->value.pstruct);

        if (gs_object_type(imemory, source_op->value.pstruct) != &st_bytes)
            return_error(e_rangecheck);
        check_read(*source_op);
        code = make_rss(i_ctx_p, source_op,
                        (const byte *)source_op->value.pstruct, size,
                        r_space(source_op), 0L, size, true);
    } else if (r_has_type(source_op, t_array)) {  /* no packedarrays */
        int i, blk_cnt, blk_sz;
        ref *blk_ref;
        ulong filelen = 0;

        check_read(*source_op);
        blk_cnt = r_size(source_op);
        blk_ref = source_op->value.refs;
        if (blk_cnt > 0) {
            blk_sz = r_size(blk_ref);
            for (i = 0; i < blk_cnt; i++) {
                int len;

                check_read_type(blk_ref[i], t_string);
                len = r_size(&blk_ref[i]);
                if (len > blk_sz || (len < blk_sz && i < blk_cnt - 1))
                   return_error(e_rangecheck); /* last block can be smaller */
                filelen += len;
            }
        }
        if (filelen == 0) {
           code = make_rss(i_ctx_p, source_op, (unsigned char *)"", 0,
               r_space(source_op), 0, 0, false);
        } else {
           code = make_aos(i_ctx_p, source_op, blk_sz, r_size(&blk_ref[blk_cnt - 1]), filelen);
        }
    } else {
        long offset = 0;
        stream *source;
        stream *s;

        check_read_file(i_ctx_p, source, source_op);
        s = source;
rs:
        if (s->cbuf_string.data != 0) {	/* string stream */
            long pos = stell(s);
            long avail = sbufavailable(s) + pos;

            offset += pos;
            code = make_rss(i_ctx_p, source_op, s->cbuf_string.data,
                            s->cbuf_string.size,
                            imemory_space((const gs_ref_memory_t *)s->memory),
                            offset, min(avail, length), false);
        } else if (s->file != 0) { /* file stream */
            if (~s->modes & (s_mode_read | s_mode_seek))
                return_error(e_ioerror);
            code = make_rfs(i_ctx_p, source_op, s, offset + stell(s), length);
        } else if (s->state->templat == &s_SFD_template) {
            /* SubFileDecode filter */
            const stream_SFD_state *const sfd_state =
                (const stream_SFD_state *)s->state;

            if (sfd_state->eod.size != 0)
                return_error(e_rangecheck);
            offset += sfd_state->skip_count - sbufavailable(s);
            if (sfd_state->count != 0) {
                long left = max(sfd_state->count, 0) + sbufavailable(s);

                if (left < length)
                    length = left;
            }
            s = s->strm;
            goto rs;
        }
        else			/* some other kind of stream */
            return_error(e_rangecheck);
        if (close_source) {
            stream *rs = fptr(source_op);

            rs->strm = source;	/* only for close_source */
            rs->close_strm = true;
        }
    }
    if (code >= 0)
        pop(1);
    return code;
}
Ejemplo n.º 4
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);
	}
    }
}
Ejemplo n.º 5
0
/* <source> <dict> eexecDecode/filter <file> */
static int
zexD(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    stream_exD_state state;
    int code;

    (*s_exD_template.set_defaults)((stream_state *)&state);
    if (r_has_type(op, t_dictionary)) {
        uint cstate;
        bool is_eexec;

        check_dict_read(*op);
        if ((code = dict_uint_param(op, "seed", 0, 0xffff, 0x10000,
                                    &cstate)) < 0 ||
            (code = dict_int_param(op, "lenIV", 0, max_int, 4,
                                   &state.lenIV)) < 0 ||
            (code = dict_bool_param(op, "eexec", false,
                                   &is_eexec)) < 0 ||
            (code = dict_bool_param(op, "keep_spaces", false,
                                   &state.keep_spaces)) < 0
            )
            return code;
        state.cstate = cstate;
        state.binary = (is_eexec ? -1 : 1);
        code = 1;
    } else {
        state.binary = 1;
        code = eexec_param(op, &state.cstate);
    }
    if (code < 0)
        return code;
    /*
     * If we're reading a .PFB file, let the filter know about it,
     * so it can read recklessly to the end of the binary section.
     */
    if (r_has_type(op - 1, t_file)) {
        stream *s = (op - 1)->value.pfile;

        if (s->state != 0 && s->state->templat == &s_PFBD_template) {
            stream_PFBD_state *pss = (stream_PFBD_state *)s->state;

            state.pfb_state = pss;
            /*
             * If we're reading the binary section of a PFB stream,
             * avoid the conversion from binary to hex and back again.
             */
            if (pss->record_type == 2) {
                /*
                 * The PFB decoder may have converted some data to hex
                 * already.  Convert it back if necessary.
                 */
                if (pss->binary_to_hex && sbufavailable(s) > 0) {
                    state.binary = 0;	/* start as hex */
                    state.hex_left = sbufavailable(s);
                } else {
                    state.binary = 1;
                }
                pss->binary_to_hex = 0;
            }
        }
    }
    return filter_read(i_ctx_p, code, &s_exD_template, (stream_state *)&state, 0);
}