コード例 #1
0
ファイル: zstring.c プロジェクト: LambdaCalculus379/SLS-1.02
/* search */
int
zsearch(register os_ptr op)
{	os_ptr op1 = op - 1;
	uint size = r_size(op);
	uint count;
	byte *ptr;
	check_read_type(*op1, t_string);
	check_read_type(*op, t_string);
	if ( size > r_size(op1) )		/* can't match */
	   {	make_bool(op, 0);
		return 0;
	   }
	count = r_size(op1) - size;
	ptr = op1->value.bytes;
	do
	   {	if ( !memcmp(ptr, op->value.bytes, size) )
		   {	op->tas.type_attrs = op1->tas.type_attrs;
			op->value.bytes = ptr;
			r_set_size(op, size);
			push(1);
			*op = *op1;
			r_set_size(op, ptr - op->value.bytes);
			op1->value.bytes = ptr + size;
			r_set_size(op1, count);
			push(1);
			make_bool(op, 1);
			return 0;
		   }
		ptr++;
	   }
	while ( count-- );
	/* No match */
	make_bool(op, 0);
	return 0;
}
コード例 #2
0
static int
push_execstack(i_ctx_t *i_ctx_p, os_ptr op1, bool include_marks,
               op_proc_t cont)
{
    uint size;
    /*
     * We can't do this directly, because the interpreter
     * might have cached some state.  To force the interpreter
     * to update the stored state, we push a continuation on
     * the exec stack; the continuation is executed immediately,
     * and does the actual transfer.
     */
    uint depth;

    if (!r_is_array(op1))
        return_op_typecheck(op1);
    /* Check the length before the write access per CET 28-03 */
    size = r_size(op1);
    depth = count_exec_stack(i_ctx_p, include_marks);
    if (depth > size)
        return_error(e_rangecheck);
    check_write(*op1);
    {
        int code = ref_stack_store_check(&e_stack, op1, size, 0);

        if (code < 0)
            return code;
    }
    check_estack(1);
    r_set_size(op1, depth);
    push_op_estack(cont);
    return o_push_estack;
}
コード例 #3
0
static int
zreadstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start)
{
    stream *s;
    uint len, rlen;
    int status;

    check_write_type(*op, t_string);
    check_read_file(s, op - 1);
    len = r_size(op);
    status = sgets(s, op->value.bytes + start, len - start, &rlen);
    rlen += start;
    switch (status) {
	case EOFC:
	case 0:
	    break;
	default:
	    return handle_read_status(i_ctx_p, status, op - 1, &rlen,
				      zreadstring_continue);
    }
    /*
     * The most recent Adobe specification says that readstring
     * must signal a rangecheck if the string length is zero.
     * I can't imagine the motivation for this, but we emulate it.
     * It's safe to check it here, rather than earlier, because if
     * len is zero, sgets will return 0 immediately with rlen = 0.
     */
    if (len == 0)
	return_error(e_rangecheck);
    r_set_size(op, rlen);
    op[-1] = *op;
    make_bool(op, (rlen == len ? 1 : 0));
    return 0;
}
コード例 #4
0
ファイル: zmisc1.c プロジェクト: BorodaZizitopa/ghostscript
static int
type1crypt(i_ctx_t *i_ctx_p,
           int (*proc)(byte *, const byte *, uint, ushort *))
{
    os_ptr op = osp;
    crypt_state state;
    uint ssize;

    check_type(op[-2], t_integer);
    state = op[-2].value.intval;
    if (op[-2].value.intval != state)
        return_error(e_rangecheck);	/* state value was truncated */
    check_read_type(op[-1], t_string);
    check_write_type(*op, t_string);
    ssize = r_size(op - 1);
    if (r_size(op) < ssize)
        return_error(e_rangecheck);
    discard((*proc)(op->value.bytes, op[-1].value.const_bytes, ssize,
                    &state));	/* can't fail */
    op[-2].value.intval = state;
    op[-1] = *op;
    r_set_size(op - 1, ssize);
    pop(1);
    return 0;
}
コード例 #5
0
ファイル: zfile.c プロジェクト: MasterPlexus/vendor_goldenve
/* Continuation operator for enumerating files */
static int
file_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    es_ptr pscratch = esp - 2;
    file_enum *pfen = r_ptr(esp - 1, file_enum);
    long devlen = esp[-3].value.intval;
    gx_io_device *iodev = r_ptr(esp - 4, gx_io_device);
    uint len = r_size(pscratch);
    uint code;

    if (len < devlen)
	return_error(e_rangecheck);	/* not even room for device len */
    memcpy((char *)pscratch->value.bytes, iodev->dname, devlen);
    code = iodev->procs.enumerate_next(pfen, (char *)pscratch->value.bytes + devlen,
    		len - devlen);
    if (code == ~(uint) 0) {	/* all done */
	esp -= 5;		/* pop proc, pfen, devlen, iodev , mark */
	return o_pop_estack;
    } else if (code > len)	/* overran string */
	return_error(e_rangecheck);
    else {
	push(1);
	ref_assign(op, pscratch);
	r_set_size(op, code + devlen);
	push_op_estack(file_continue);	/* come again */
	*++esp = pscratch[2];	/* proc */
	return o_push_estack;
    }
}
コード例 #6
0
/* <string> <pattern> search <string> -false- */
static int
zsearch(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    uint size = r_size(op);
    uint count;
    byte *pat;
    byte *ptr;
    byte ch;

    check_read_type(*op1, t_string);
    check_read_type(*op, t_string);
    if (size > r_size(op1)) {	/* can't match */
        make_false(op);
        return 0;
    }
    count = r_size(op1) - size;
    ptr = op1->value.bytes;
    if (size == 0)
        goto found;
    pat = op->value.bytes;
    ch = pat[0];
    do {
        if (*ptr == ch && (size == 1 || !memcmp(ptr, pat, size)))
            goto found;
        ptr++;
    }
    while (count--);
    /* No match */
    make_false(op);
    return 0;
found:
    op->tas.type_attrs = op1->tas.type_attrs;
    op->value.bytes = ptr;
    r_set_size(op, size);
    push(2);
    op[-1] = *op1;
    r_set_size(op - 1, ptr - op[-1].value.bytes);
    op1->value.bytes = ptr + size;
    r_set_size(op1, count);
    make_true(op);
    return 0;
}
コード例 #7
0
static int
zwritecvp_at(i_ctx_t *i_ctx_p, os_ptr op, uint start, bool first)
{
    stream *s;
    byte str[100];		/* arbitrary */
    ref rstr;
    const byte *data = str;
    uint len;
    int code, status;

    check_write_file(s, op - 2);
    check_type(*op, t_integer);
    code = obj_cvp(op - 1, str, sizeof(str), &len, (int)op->value.intval,
		   start, imemory, true);
    if (code == e_rangecheck) {
        code = obj_string_data(imemory, op - 1, &data, &len);
	if (len < start)
	    return_error(e_rangecheck);
	data += start;
	len -= start;
    }
    if (code < 0)
	return code;
    r_set_size(&rstr, len);
    rstr.value.const_bytes = data;
    status = write_string(&rstr, s);
    switch (status) {
	default:
	    return_error(e_ioerror);
	case 0:
	    break;
	case INTC:
	case CALLC:
	    len = start + len - r_size(&rstr);
	    if (!first)
		--osp;		/* pop(1) without affecting op */
	    return handle_write_status(i_ctx_p, status, op - 2, &len,
				       zwritecvp_continue);
    }
    if (code == 1) {
	if (first)
	    check_ostack(1);
	push_op_estack(zwritecvp_continue);
	if (first)
	    push(1);
	make_int(osp, start + len);
	return o_push_estack;
    }
    if (first)			/* zwritecvp */
	pop(3);
    else			/* zwritecvp_continue */
	pop(4);
    return 0;
}
コード例 #8
0
static int
zwritehexstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint odd)
{
    register stream *s;
    register byte ch;
    register const byte *p;
    register const char *const hex_digits = "0123456789abcdef";
    register uint len;
    int status;

#define MAX_HEX 128
    byte buf[MAX_HEX];

    check_write_file(s, op - 1);
    check_read_type(*op, t_string);
    p = op->value.bytes;
    len = r_size(op);
    while (len) {
	uint len1 = min(len, MAX_HEX / 2);
	register byte *q = buf;
	uint count = len1;
	ref rbuf;

	do {
	    ch = *p++;
	    *q++ = hex_digits[ch >> 4];
	    *q++ = hex_digits[ch & 0xf];
	}
	while (--count);
	r_set_size(&rbuf, (len1 << 1) - odd);
	rbuf.value.bytes = buf + odd;
	status = write_string(&rbuf, s);
	switch (status) {
	    default:
		return_error(e_ioerror);
	    case 0:
		len -= len1;
		odd = 0;
		continue;
	    case INTC:
	    case CALLC:
		count = rbuf.value.bytes - buf;
		op->value.bytes += count >> 1;
		r_set_size(op, len - (count >> 1));
		count &= 1;
		return handle_write_status(i_ctx_p, status, op - 1, &count,
					   zwritehexstring_continue);
	}
    }
    pop(2);
    return 0;
#undef MAX_HEX
}
コード例 #9
0
/* <string1> <string2> copy <substring2> */
static int
zcopy_interval(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    int code = copy_interval(i_ctx_p, op, 0, op1, "copy");

    if (code < 0)
	return code;
    r_set_size(op, r_size(op1));
    *op1 = *op;
    pop(1);
    return 0;
}
コード例 #10
0
/*
 * We could handle readline the same way as readstring,
 * except for the anomalous situation where we get interrupted
 * between the CR and the LF of an end-of-line marker.
 * We hack around this in the following way: if we get interrupted
 * before we've read any characters, we just restart the readline;
 * if we get interrupted at any other time, we use readline_continue;
 * we use start=0 (which we have just ruled out as a possible start value
 * for readline_continue) to indicate interruption after the CR.
 */
static int
zreadline_at(i_ctx_t *i_ctx_p, os_ptr op, uint count, bool in_eol)
{
    stream *s;
    int status;
    gs_string str;

    check_write_type(*op, t_string);
    check_read_file(s, op - 1);
    str.data = op->value.bytes;
    str.size = r_size(op);
    status = zreadline_from(s, &str, NULL, &count, &in_eol);
    switch (status) {
	case 0:
	case EOFC:
	    break;
	case 1:
	    return_error(e_rangecheck);
	default:
	    if (count == 0 && !in_eol)
		return handle_read_status(i_ctx_p, status, op - 1, NULL,
					  zreadline);
	    else {
		if (in_eol) {
		    r_set_size(op, count);
		    count = 0;
		}
		return handle_read_status(i_ctx_p, status, op - 1, &count,
					  zreadline_continue);
	    }
    }
    r_set_size(op, count);
    op[-1] = *op;
    make_bool(op, status == 0);
    return 0;
}
コード例 #11
0
/* Convert a file name to a C string by adding a null terminator. */
int
terminate_file_name(parsed_file_name *pfn, client_name_t cname)
{   uint len = pfn->len;
    ref fnref;
    const char *fname;
    if ( pfn->iodev == NULL )	 /* no device */
        pfn->iodev = iodev_default;
    fnref.value.const_bytes = (const byte *)pfn->fname;
    r_set_size(&fnref, len);
    fname = ref_to_string(&fnref, imemory, cname);
    if ( fname == 0 )
        return_error(e_VMerror);
    pfn->fname = fname;
    pfn->len = len + 1;	/* null terminator */
    return 0;
}
コード例 #12
0
/* <dnum> <string> .dcvs <substring> */
static int
zdcvs(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double num;
    int code = double_params(op - 1, 1, &num);
    char dot, str[MAX_CHARS + 1];
    int len;

    if (code < 0)
	return code;
    check_write_type(*op, t_string);
    sprintf(str, "%f", 1.5);
    dot = str[1]; /* locale-dependent */
    /*
     * To get fully accurate output results for IEEE double-
     * precision floats (53 bits of mantissa), the ANSI
     * %g default of 6 digits is not enough; 16 are needed.
     * Unfortunately, using %.16g produces unfortunate artifacts such as
     * 1.2 printing as 1.200000000000005.  Therefore, we print using %g,
     * and if the result isn't accurate enough, print again
     * using %.16g.
     */
    {
	double scanned;

	sprintf(str, "%g", num);
	sscanf(str, "%lf", &scanned);
	if (scanned != num)
	    sprintf(str, "%.16g", num);
    }
    len = strlen(str);
    if (len > r_size(op))
	return_error(e_rangecheck);
    /* Juggling locales isn't thread-safe. Posix me harder. */
    if (dot != '.') {
        char *pdot = strchr(str, dot); 
        if (pdot)
            *pdot = '.';
    }
    memcpy(op->value.bytes, str, len);
    op[-1] = *op;
    r_set_size(op - 1, len);
    pop(1);
    return 0;
}
コード例 #13
0
/* <seq:array|packedarray|string> <index> <count> getinterval <subseq> */
static int
zgetinterval(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    os_ptr op2 = op1 - 1;
    uint index;
    uint count;

    switch (r_type(op2)) {
	default:
	    return_op_typecheck(op2);
	case t_array:
	case t_string:
	case t_mixedarray:
	case t_shortarray:;
    }
    check_read(*op2);
    check_int_leu(*op1, r_size(op2));
    index = op1->value.intval;
    check_int_leu(*op, r_size(op2) - index);
    count = op->value.intval;
    switch (r_type(op2)) {
	case t_array:
	    op2->value.refs += index;
	    break;
	case t_string:
	    op2->value.bytes += index;
	    break;
	case t_mixedarray: {
	    const ref_packed *packed = op2->value.packed;

	    for (; index--;)
		packed = packed_next(packed);
	    op2->value.packed = packed;
	    break;
	}
	case t_shortarray:
	    op2->value.packed += index;
	    break;
    }
    r_set_size(op2, count);
    pop(2);
    return 0;
}
コード例 #14
0
ファイル: zstring.c プロジェクト: LambdaCalculus379/SLS-1.02
/* anchorsearch */
int
zanchorsearch(register os_ptr op)
{	os_ptr op1 = op - 1;
	uint size = r_size(op);
	check_read_type(*op1, t_string);
	check_read_type(*op, t_string);
	if ( size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size) )
	   {	*op = *op1;
		r_set_size(op, size);
		op1->value.bytes += size;
		r_inc_size(op1, -size);
		push(1);
		make_bool(op, 1);
	   }
	else
		make_bool(op, 0);
	return 0;
}
コード例 #15
0
/* If the status is INTC or CALLC, updates the string on the o-stack. */
static int
write_string(ref * op, stream * s)
{
    const byte *data = op->value.const_bytes;
    uint len = r_size(op);
    uint wlen;
    int status = sputs(s, data, len, &wlen);

    switch (status) {
	case INTC:
	case CALLC:
	    op->value.const_bytes = data + wlen;
	    r_set_size(op, len - wlen);
	    /* falls through */
	default:		/* 0, EOFC, ERRC */
	    return status;
    }
}
コード例 #16
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;
}
コード例 #17
0
ファイル: zbseq.c プロジェクト: computersforpeace/ghostpdl
static int
zbosobject(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;

    check_type(op[-3], t_integer);
    check_type(op[-2], t_integer);
    check_write_type(*op, t_string);
    if (r_size(op) < 8)
        return_error(gs_error_rangecheck);
    code = encode_binary_token(i_ctx_p, op - 1, &op[-3].value.intval,
                               &op[-2].value.intval, op->value.bytes);
    if (code < 0)
        return code;
    op[-1] = *op;
    r_set_size(op - 1, 8);
    pop(1);
    return 0;
}
コード例 #18
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;
}
コード例 #19
0
ファイル: igcref.c プロジェクト: MasterPlexus/vendor_goldenve
/* Clear the relocation for a ref object. */
static void
refs_clear_reloc(obj_header_t *hdr, uint size)
{
    ref_packed *rp = (ref_packed *) (hdr + 1);
    ref_packed *end = (ref_packed *) ((byte *) rp + size);

    while (rp < end) {
	if (r_is_packed(rp))
	    rp++;
	else {
	    /* Full-size ref.  Store the relocation here if possible. */
	    ref *const pref = (ref *)rp;

	    if (!ref_type_uses_size_or_null(r_type(pref))) {
		if_debug1('8', "  [8]clearing reloc at 0x%lx\n", (ulong) rp);
		r_set_size(pref, 0);
	    }
	    rp += packed_per_ref;
	}
    }
}
コード例 #20
0
/* <string> <pattern> anchorsearch <string> -false- */
static int
zanchorsearch(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    uint size = r_size(op);

    check_read_type(*op, t_string);
    check_read_type(*op1, t_string);
    if (size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size)) {
        os_ptr op0 = op;

        push(1);
        *op0 = *op1;
        r_set_size(op0, size);
        op1->value.bytes += size;
        r_dec_size(op1, size);
        make_true(op);
    } else
        make_false(op);
    return 0;
}
コード例 #21
0
/* cvrs can use it when the radix is 10. */
static int
convert_to_string(const gs_memory_t *mem, os_ptr op1, os_ptr op)
{
    uint len;
    const byte *pstr = 0;
    int code = obj_cvs(mem, op1, op->value.bytes, r_size(op), &len, &pstr);

    if (code < 0) {
	/*
	 * Some common downloaded error handlers assume that
	 * operator names don't exceed a certain fixed size.
	 * To work around this bit of bad design, we implement
	 * a special hack here: if we got a rangecheck, and
	 * the object is an operator whose name begins with
	 * %, ., or @, we just truncate the name.
	 */
	if (code == e_rangecheck)
	    switch (r_btype(op1)) {
		case t_oparray:
		case t_operator:
		    if (pstr != 0)
			switch (*pstr) {
			    case '%':
			    case '.':
			    case '@':
				len = r_size(op);
				memcpy(op->value.bytes, pstr, len);
				goto ok;
			}
	    }
	return code;
    }
ok:
    *op1 = *op;
    r_set_size(op1, len);
    return 0;
}
コード例 #22
0
/*   .getbitsrect <height> <substring> */
static int
zgetbitsrect(i_ctx_t *i_ctx_p)
{	/*
	 * alpha? is 0 for no alpha, -1 for alpha first, 1 for alpha last.
	 * std_depth is null for native pixels, depth/component for
	 * standard color space.
	 */
    os_ptr op = osp;
    gx_device *dev;
    gs_int_rect rect;
    gs_get_bits_params_t params;
    int w, h;
    gs_get_bits_options_t options =
	GB_ALIGN_ANY | GB_RETURN_COPY | GB_OFFSET_0 | GB_RASTER_STANDARD |
	GB_PACKING_CHUNKY;
    int depth;
    uint raster;
    int num_rows;
    int code;

    check_read_type(op[-7], t_device);
    dev = op[-7].value.pdevice;
    check_int_leu(op[-6], dev->width);
    rect.p.x = op[-6].value.intval;
    check_int_leu(op[-5], dev->height);
    rect.p.y = op[-5].value.intval;
    check_int_leu(op[-4], dev->width);
    w = op[-4].value.intval;
    check_int_leu(op[-3], dev->height);
    h = op[-3].value.intval;
    check_type(op[-2], t_integer);
    /*
     * We use if/else rather than switch because the value is long,
     * which is not supported as a switch value in pre-ANSI C.
     */
    if (op[-2].value.intval == -1)
	options |= GB_ALPHA_FIRST;
    else if (op[-2].value.intval == 0)
	options |= GB_ALPHA_NONE;
    else if (op[-2].value.intval == 1)
	options |= GB_ALPHA_LAST;
    else
	return_error(e_rangecheck);
    if (r_has_type(op - 1, t_null)) {
	options |= GB_COLORS_NATIVE;
	depth = dev->color_info.depth;
    } else {
	static const gs_get_bits_options_t depths[17] = {
	    0, GB_DEPTH_1, GB_DEPTH_2, 0, GB_DEPTH_4, 0, 0, 0, GB_DEPTH_8,
	    0, 0, 0, GB_DEPTH_12, 0, 0, 0, GB_DEPTH_16
	};
	gs_get_bits_options_t depth_option;
	int std_depth;

	check_int_leu(op[-1], 16);
	std_depth = (int)op[-1].value.intval;
	depth_option = depths[std_depth];
	if (depth_option == 0)
	    return_error(e_rangecheck);
	options |= depth_option | GB_COLORS_NATIVE;
	depth = (dev->color_info.num_components +
		 (options & GB_ALPHA_NONE ? 0 : 1)) * std_depth;
    }
    if (w == 0)
	return_error(e_rangecheck);
    raster = (w * depth + 7) >> 3;
    check_write_type(*op, t_string);
    num_rows = r_size(op) / raster;
    h = min(h, num_rows);
    if (h == 0)
	return_error(e_rangecheck);
    rect.q.x = rect.p.x + w;
    rect.q.y = rect.p.y + h;
    params.options = options;
    params.data[0] = op->value.bytes;
    code = (*dev_proc(dev, get_bits_rectangle))(dev, &rect, &params, NULL);
    if (code < 0)
	return code;
    make_int(op - 7, h);
    op[-6] = *op;
    r_set_size(op - 6, h * raster);
    pop(6);
    return 0;
}
コード例 #23
0
ファイル: zchar32.c プロジェクト: computersforpeace/ghostpdl
/*   <bitmap> <cid> <type32font> <str22> .makeglyph32 <<same with substr>> */
static int
zmakeglyph32(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    bool long_form;
    uint msize;
    double metrics[10];
    int wx, llx, lly, urx, ury;
    int width, height, raster;
    gs_font *pfont;
    int code;
    byte *str;

    check_array(op[-4]);
    msize = r_size(op - 4);
    switch (msize) {
        case 10:
            long_form = true;
            break;
        case 6:
            long_form = false;
            break;
        default:
            return_error(gs_error_rangecheck);
    }
    code = num_params(op[-4].value.refs + msize - 1, msize, metrics);
    if (code < 0)
        return code;
    if (~code & 0x3c)		/* check llx .. ury for integers */
        return_error(gs_error_typecheck);
    check_read_type(op[-3], t_string);
    llx = (int)metrics[2];
    lly = (int)metrics[3];
    urx = (int)metrics[4];
    ury = (int)metrics[5];
    width = urx - llx;
    height = ury - lly;
    raster = (width + 7) >> 3;
    if (width < 0 || height < 0 || r_size(op - 3) != raster * height)
        return_error(gs_error_rangecheck);
    check_int_leu(op[-2], 65535);
    code = font_param(op - 1, &pfont);
    if (code < 0)
        return code;
    if (pfont->FontType != ft_CID_bitmap)
        return_error(gs_error_invalidfont);
    check_write_type(*op, t_string);
    if (r_size(op) < 22)
        return_error(gs_error_rangecheck);
    str = op->value.bytes;
    if (long_form || metrics[0] != (wx = (int)metrics[0]) ||
        metrics[1] != 0 || height == 0 ||
        ((wx | width | height | (llx + 128) | (lly + 128)) & ~255) != 0
        ) {
        /* Use the long form. */
        int i, n = (long_form ? 10 : 6);

        str[0] = 0;
        str[1] = long_form;
        for (i = 0; i < n; ++i) {
            int v = (int)metrics[i];  /* no floating point widths yet */

            str[2 + 2 * i] = (byte)(v >> 8);
            str[2 + 2 * i + 1] = (byte)v;
        }
        r_set_size(op, 2 + n * 2);
    } else {
コード例 #24
0
ファイル: igcref.c プロジェクト: MasterPlexus/vendor_goldenve
/* Set the relocation for a ref object. */
static bool
refs_set_reloc(obj_header_t * hdr, uint reloc, uint size)
{
    ref_packed *rp = (ref_packed *) (hdr + 1);
    ref_packed *end = (ref_packed *) ((byte *) rp + size);
    uint freed = 0;

    /*
     * We have to be careful to keep refs aligned properly.
     * For the moment, we do this by either keeping or discarding
     * an entire (aligned) block of align_packed_per_ref packed elements
     * as a unit.  We know that align_packed_per_ref <= packed_per_ref,
     * and we also know that packed refs are always allocated in blocks
     * of align_packed_per_ref, so this makes things relatively easy.
     */
    while (rp < end) {
	if (r_is_packed(rp)) {
#if align_packed_per_ref == 1
	    if (r_has_pmark(rp)) {
		if_debug1('8',
			  "  [8]packed ref 0x%lx is marked\n",
			  (ulong) rp);
		rp++;
	    } else {
#else
	    int i;

	    /*
	     * Note: align_packed_per_ref is typically
	     * 2 or 4 for 32-bit processors.
	     */
#define all_marked (align_packed_per_ref * lp_mark)
# if align_packed_per_ref == 2
#  if arch_sizeof_int == arch_sizeof_short * 2
#    undef all_marked
#    define all_marked ( (lp_mark << (sizeof(short) * 8)) + lp_mark )
#    define marked (*(int *)rp & all_marked)
#  else
#    define marked ((*rp & lp_mark) + (rp[1] & lp_mark))
#  endif
# else
#  if align_packed_per_ref == 4
#    define marked ((*rp & lp_mark) + (rp[1] & lp_mark) +\
		    (rp[2] & lp_mark) + (rp[3] & lp_mark))
#  else
	    /*
	     * The value of marked is logically a uint, not an int:
	     * we declare it as int only to avoid a compiler warning
	     * message about using a non-int value in a switch statement.
	     */
	    int marked = *rp & lp_mark;

	    for (i = 1; i < align_packed_per_ref; i++)
		marked += rp[i] & lp_mark;
#  endif
# endif
	    /*
	     * Now marked is lp_mark * the number of marked
	     * packed refs in the aligned block, except for
	     * a couple of special cases above.
	     */
	    switch (marked) {
		case all_marked:
		    if_debug2('8',
			      "  [8]packed refs 0x%lx..0x%lx are marked\n",
			      (ulong) rp,
			      (ulong) (rp + (align_packed_per_ref - 1)));
		    rp += align_packed_per_ref;
		    break;
		default:
		    /* At least one packed ref in the block */
		    /* is marked: Keep the whole block. */
		    for (i = align_packed_per_ref; i--; rp++) {
			r_set_pmark(rp);
			if_debug1('8',
				  "  [8]packed ref 0x%lx is marked\n",
				  (ulong) rp);
		    }
		    break;
		case 0:
#endif
		    if_debug2('8', "  [8]%d packed ref(s) at 0x%lx are unmarked\n",
			      align_packed_per_ref, (ulong) rp);
		    {
			uint rel = reloc + freed;

			/* Change this to an integer so we can */
			/* store the relocation here. */
			*rp = pt_tag(pt_integer) +
			    min(rel, packed_max_value);
		    }
		    rp += align_packed_per_ref;
		    freed += sizeof(ref_packed) * align_packed_per_ref;
	    }
	} else {		/* full-size ref */
	    uint rel = reloc + freed;

	    /* The following assignment is logically */
	    /* unnecessary; we do it only for convenience */
	    /* in debugging. */
	    ref *pref = (ref *) rp;

	    if (!r_has_attr(pref, l_mark)) {
		if_debug1('8', "  [8]ref 0x%lx is unmarked\n",
			  (ulong) pref);
		/* Change this to a mark so we can */
		/* store the relocation. */
		r_set_type(pref, t_mark);
		r_set_size(pref, rel);
		freed += sizeof(ref);
	    } else {
		if_debug1('8', "  [8]ref 0x%lx is marked\n",
			  (ulong) pref);
		/* Store the relocation here if possible. */
		if (!ref_type_uses_size_or_null(r_type(pref))) {
		    if_debug2('8', "  [8]storing reloc %u at 0x%lx\n",
			      rel, (ulong) pref);
		    r_set_size(pref, rel);
		}
	    }
	    rp += packed_per_ref;
	}
    }
    if_debug3('7', " [7]at end of refs 0x%lx, size = %u, freed = %u\n",
	      (ulong) (hdr + 1), size, freed);
    if (freed == size)
	return false;
#if arch_sizeof_int > arch_sizeof_short
    /*
     * If the final relocation can't fit in the r_size field
     * (which can't happen if the object shares a chunk with
     * any other objects, so we know reloc = 0 in this case),
     * we have to keep the entire object unless there are no
     * references to any ref in it.
     */
    if (freed <= max_ushort)
	return true;
    /*
     * We have to mark all surviving refs, but we also must
     * overwrite any non-surviving refs with something that
     * doesn't contain any pointers.
     */
    rp = (ref_packed *) (hdr + 1);
    while (rp < end) {
	if (r_is_packed(rp)) {
	    if (!r_has_pmark(rp))
		*rp = pt_tag(pt_integer) | lp_mark;
	    ++rp;
	} else {		/* The following assignment is logically */
	    /* unnecessary; we do it only for convenience */
	    /* in debugging. */
	    ref *pref = (ref *) rp;

	    if (!r_has_attr(pref, l_mark)) {
		r_set_type_attrs(pref, t_mark, l_mark);
		r_set_size(pref, reloc);
	    } else {
		if (!ref_type_uses_size_or_null(r_type(pref)))
		    r_set_size(pref, reloc);
	    }
	    rp += packed_per_ref;
	}
    }
    /* The last ref has to remain unmarked. */
    r_clear_attrs((ref *) rp - 1, l_mark);
#endif
    return true;
}
コード例 #25
0
ファイル: zfont.c プロジェクト: jonathan-mui/ruby-ghostscript
int
zdefault_make_font(gs_font_dir * pdir, const gs_font * oldfont,
                   const gs_matrix * pmat, gs_font ** ppfont)
{
    gs_font *newfont = *ppfont;
    gs_memory_t *mem = newfont->memory;
    /* HACK: we know this font was allocated by the interpreter. */
    gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
    ref *fp = pfont_dict(oldfont);
    font_data *pdata;
    ref newdict, newmat, scalemat;
    uint dlen = dict_maxlength(fp);
    uint mlen = dict_length(fp) + 3;	/* FontID, OrigFont, ScaleMatrix */
    int code;

    if (dlen < mlen)
        dlen = mlen;
    if ((pdata = gs_alloc_struct(mem, font_data, &st_font_data,
                                 "make_font(font_data)")) == 0
        )
        return_error(e_VMerror);
    /*
     * This dictionary is newly created: it's safe to pass NULL as the
     * dstack pointer to dict_copy and dict_put_string.
     */
    if ((code = dict_alloc(imem, dlen, &newdict)) < 0 ||
        (code = dict_copy(fp, &newdict, NULL)) < 0 ||
        (code = gs_alloc_ref_array(imem, &newmat, a_all, 12,
                                   "make_font(matrices)")) < 0
        )
        return code;
    refset_null_new(newmat.value.refs, 12, imemory_new_mask(imem));
    ref_assign(&scalemat, &newmat);
    r_set_size(&scalemat, 6);
    scalemat.value.refs += 6;
    /*
     * Create the scaling matrix.  We could do this several different
     * ways: by "dividing" the new FontMatrix by the base FontMatrix, by
     * multiplying the current scaling matrix by a ScaleMatrix kept in
     * the gs_font, or by multiplying the current scaling matrix by the
     * ScaleMatrix from the font dictionary.  We opt for the last of
     * these.
     */
    {
        gs_matrix scale, prev_scale;
        ref *ppsm;

        if (!(dict_find_string(fp, "ScaleMatrix", &ppsm) > 0 &&
              read_matrix(mem, ppsm, &prev_scale) >= 0 &&
              gs_matrix_multiply(pmat, &prev_scale, &scale) >= 0)
            )
            scale = *pmat;
        write_matrix_new(&scalemat, &scale, imem);
    }
    r_clear_attrs(&scalemat, a_write);
    r_set_size(&newmat, 6);
    write_matrix_new(&newmat, &newfont->FontMatrix, imem);
    r_clear_attrs(&newmat, a_write);
    if ((code = dict_put_string(&newdict, "FontMatrix", &newmat, NULL)) < 0 ||
        (code = dict_put_string(&newdict, "OrigFont", pfont_dict(oldfont->base), NULL)) < 0 ||
        (code = dict_put_string(&newdict, "ScaleMatrix", &scalemat, NULL)) < 0 ||
        (code = add_FID(NULL, &newdict, newfont, imem)) < 0
        )
        return code;
    newfont->client_data = pdata;
    *pdata = *pfont_data(oldfont);
    pdata->dict = newdict;
    r_clear_attrs(dict_access_ref(&newdict), a_write);
    return 0;
}
コード例 #26
0
/* <num> <radix_int> <string> cvrs <substring> */
static int
zcvrs(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int radix;

    check_type(op[-1], t_integer);
    if (op[-1].value.intval < 2 || op[-1].value.intval > 36)
	return_error(e_rangecheck);
    radix = op[-1].value.intval;
    check_write_type(*op, t_string);
    if (radix == 10) {
	switch (r_type(op - 2)) {
	    case t_integer:
	    case t_real:
		{
		    int code = convert_to_string(imemory, op - 2, op);

		    if (code < 0)
			return code;
		    pop(2);
		    return 0;
		}
            case t__invalid:
                return_error(e_stackunderflow);
	    default:
		return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
	}
    } else {
	uint ival;
	byte digits[sizeof(ulong) * 8];
	byte *endp = &digits[countof(digits)];
	byte *dp = endp;

	switch (r_type(op - 2)) {
	    case t_integer:
		ival = (uint) op[-2].value.intval;
		break;
	    case t_real:
		{
		    float fval = op[-2].value.realval;

		    if (!REAL_CAN_BE_INT(fval))
			return_error(e_rangecheck);
		    ival = (ulong) (long)fval;
		} break;
            case t__invalid:
                return_error(e_stackunderflow);
	    default:
		return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
	}
	do {
	    int dit = ival % radix;

	    *--dp = dit + (dit < 10 ? '0' : ('A' - 10));
	    ival /= radix;
	}
	while (ival);
	if (endp - dp > r_size(op))
	    return_error(e_rangecheck);
	memcpy(op->value.bytes, dp, (uint) (endp - dp));
	r_set_size(op, endp - dp);
    }
    op[-2] = *op;
    pop(2);
    return 0;
}