Ejemplo n.º 1
0
/* convenience of reusing procedures that take 1 state parameter */
static int
zreadhexstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start, int odd)
{
    stream *s;
    uint len, nread;
    byte *str;
    int odd_byte = odd;
    stream_cursor_write cw;
    int status;

    check_read_file(s, op - 1);
    /*check_write_type(*op, t_string); *//* done by caller */
    str = op->value.bytes;
    len = r_size(op);
    cw.ptr = str + start - 1;
    cw.limit = str + len - 1;
    for (;;) {
	status = s_hex_process(&s->cursor.r, &cw, &odd_byte,
			       hex_ignore_garbage);
	if (status == 1) {	/* filled the string */
	    ref_assign_inline(op - 1, op);
	    make_true(op);
	    return 0;
	} else if (status != 0)	/* error or EOF */
	    break;
	/* Didn't fill, keep going. */
	status = spgetc(s);
	if (status < 0)
	    break;
	sputback(s);
    }
    nread = cw.ptr + 1 - str;
    if (status != EOFC) {	/* Error */
	nread |= odd_byte << 24;
        return handle_read_status(i_ctx_p, status, op - 1, &nread,
				  zreadhexstring_continue);
    }
    /* Reached end-of-file before filling the string. */
    /* Return an appropriate substring. */
    ref_assign_inline(op - 1, op);
    r_set_size(op - 1, nread);
    make_false(op);
    return 0;
}
Ejemplo n.º 2
0
/* Return a double result. */
static int
double_result(i_ctx_t *i_ctx_p, int count, double result)
{
    os_ptr op = osp;
    os_ptr op1 = op - count;

    ref_assign_inline(op1, op);
    memcpy(op1->value.bytes, &result, sizeof(double));
    pop(count);
    return 0;
}
Ejemplo n.º 3
0
/* Continuation operator for positive integers. */
static int
for_pos_int_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    register es_ptr ep = esp;
    int var = ep[-3].value.intval;

    if (var > ep[-1].value.intval) {
        esp -= 5;		/* pop everything */
        return o_pop_estack;
    }
    push(1);
    make_int(op, var);
    ep[-3].value.intval = var + ep[-2].value.intval;
    ref_assign_inline(ep + 2, ep);	/* saved proc */
    esp = ep + 2;
    return o_push_estack;
}
Ejemplo n.º 4
0
/* Continuation procedure */
static int
for_samples_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    es_ptr ep = esp;
    int var = ep[-4].value.intval;
    float a = ep[-3].value.realval;
    int n = ep[-2].value.intval;
    float b = ep[-1].value.realval;

    if (var > n) {
        esp -= 6;		/* pop everything */
        return o_pop_estack;
    }
    push(1);
    make_real(op, ((n - var) * a + var * b) / n);
    ep[-4].value.intval = var + 1;
    ref_assign_inline(ep + 2, ep);	/* saved proc */
    esp = ep + 2;
    return o_push_estack;
}
Ejemplo n.º 5
0
/* Remove the marks at the same time. */
static void
refs_compact(const gs_memory_t *mem, obj_header_t * pre, obj_header_t * dpre, uint size)
{
    ref_packed *dest;
    ref_packed *src;
    ref_packed *end;
    uint new_size;

   /* The next switch controls an optimization 
      for the loop termination condition.
      It was useful during the development,
      when some assumptions were temporary wrong.
      We keep it for records. */

    src = (ref_packed *) (pre + 1);
    end = (ref_packed *) ((byte *) src + size);
    /*
     * We know that a block of refs always ends with a
     * full-size ref, so we only need to check for reaching the end
     * of the block when we see one of those.
     */
    if (dpre == pre)		/* Loop while we don't need to copy. */
	for (;;) {
	    if (r_is_packed(src)) {
		if (!r_has_pmark(src))
		    break;
		if_debug1('8', "  [8]packed ref 0x%lx \"copied\"\n",
			  (ulong) src);
		*src &= ~lp_mark;
		src++;
	    } else {		/* full-size ref */
		ref *const pref = (ref *)src;

		if (!r_has_attr(pref, l_mark))
		    break;
		if_debug1('8', "  [8]ref 0x%lx \"copied\"\n", (ulong) src);
		r_clear_attrs(pref, l_mark);
		src += packed_per_ref;
	    }
    } else
	*dpre = *pre;
    dest = (ref_packed *) ((char *)dpre + ((char *)src - (char *)pre));
    for (;;) {
	if (r_is_packed(src)) {
	    if (r_has_pmark(src)) {
		if_debug2('8', "  [8]packed ref 0x%lx copied to 0x%lx\n",
			  (ulong) src, (ulong) dest);
		*dest++ = *src & ~lp_mark;
	    }
	    src++;
	} else {		/* full-size ref */
	    if (r_has_attr((ref *) src, l_mark)) {
		ref rtemp;

		if_debug2('8', "  [8]ref 0x%lx copied to 0x%lx\n",
			  (ulong) src, (ulong) dest);
		/* We can't just use ref_assign_inline, */
		/* because the source and destination */
		/* might overlap! */
		ref_assign_inline(&rtemp, (ref *) src);
		r_clear_attrs(&rtemp, l_mark);
		ref_assign_inline((ref *) dest, &rtemp);
		src += packed_per_ref;
		dest += packed_per_ref;
	    } else {		/* check for end of block */
		src += packed_per_ref;
		if (src >= end)
		    break;
	    }
	}
    }
    new_size = (byte *) dest - (byte *) (dpre + 1) + sizeof(ref);
#ifdef DEBUG
    /* Check that the relocation came out OK. */
    /* NOTE: this check only works within a single chunk. */
    if ((byte *) src - (byte *) dest != r_size((ref *) src - 1) + sizeof(ref)) {
	lprintf3("Reloc error for refs 0x%lx: reloc = %lu, stored = %u\n",
		 (ulong) dpre, (ulong) ((byte *) src - (byte *) dest),
		 (uint) r_size((ref *) src - 1));
	gs_abort(mem);
    }
#endif
    /* Pad to a multiple of sizeof(ref). */
    while (new_size & (sizeof(ref) - 1))
	*dest++ = pt_tag(pt_integer),
	    new_size += sizeof(ref_packed);
    /* We want to make the newly freed space into a free block, */
    /* but we can only do this if we have enough room. */
    if (size - new_size < sizeof(obj_header_t)) {	/* Not enough room.  Pad to original size. */
	while (new_size < size)
	    *dest++ = pt_tag(pt_integer),
		new_size += sizeof(ref_packed);
    } else {
	obj_header_t *pfree = (obj_header_t *) ((ref *) dest + 1);

	pfree->o_alone = 0;
	pfree->o_size = size - new_size - sizeof(obj_header_t);
	pfree->o_type = &st_bytes;
    }
    /* Re-create the final ref. */
    r_set_type((ref *) dest, t_integer);
    dpre->o_size = new_size;
}