Esempio n. 1
0
/* Copy one parameter list to another, recursively if necessary. */
int
param_list_copy(gs_param_list *plto, gs_param_list *plfrom)
{
    gs_param_enumerator_t key_enum;
    gs_param_key_t key;
    /*
     * If plfrom and plto use different allocators, we must copy
     * aggregate values even if they are "persistent".
     */
    bool copy_persists = plto->memory == plfrom->memory;
    int code;

    param_init_enumerator(&key_enum);
    while ((code = param_get_next_key(plfrom, &key_enum, &key)) == 0) {
	char string_key[256];	/* big enough for any reasonable key */
	gs_param_typed_value value;
	gs_param_collection_type_t coll_type;
	gs_param_typed_value copy;

	if (key.size > sizeof(string_key) - 1) {
	    code = gs_note_error(gs_error_rangecheck);
	    break;
	}
	memcpy(string_key, key.data, key.size);
	string_key[key.size] = 0;
	if ((code = param_read_typed(plfrom, string_key, &value)) != 0) {
	    code = (code > 0 ? gs_note_error(gs_error_unknownerror) : code);
	    break;
	}
	gs_param_list_set_persistent_keys(plto, key.persistent);
	switch (value.type) {
	case gs_param_type_dict:
	    coll_type = gs_param_collection_dict_any;
	    goto cc;
	case gs_param_type_dict_int_keys:
	    coll_type = gs_param_collection_dict_int_keys;
	    goto cc;
	case gs_param_type_array:
	    coll_type = gs_param_collection_array;
	cc:
	    copy.value.d.size = value.value.d.size;
	    if ((code = param_begin_write_collection(plto, string_key,
						     &copy.value.d,
						     coll_type)) < 0 ||
		(code = param_list_copy(copy.value.d.list,
					value.value.d.list)) < 0 ||
		(code = param_end_write_collection(plto, string_key,
						   &copy.value.d)) < 0)
		break;
	    code = param_end_read_collection(plfrom, string_key,
					     &value.value.d);
	    break;
	case gs_param_type_string:
	    value.value.s.persistent &= copy_persists; goto ca;
	case gs_param_type_name:
	    value.value.n.persistent &= copy_persists; goto ca;
	case gs_param_type_int_array:
	    value.value.ia.persistent &= copy_persists; goto ca;
	case gs_param_type_float_array:
	    value.value.fa.persistent &= copy_persists; goto ca;
	case gs_param_type_string_array:
	    value.value.sa.persistent &= copy_persists;
	ca:
	default:
	    code = param_write_typed(plto, string_key, &value);
	}
	if (code < 0)
	    break;
    }
    return code;
}
Esempio n. 2
0
/* Expand a buffer into a gs_param_list (including sub-dicts) */
int				/* ret -ve err, +ve # of chars read from buffer */
gs_param_list_unserialize(
                             gs_param_list * list,	/* root of list to expand to */
                                        /* list MUST BE IN WRITE MODE */
                             const byte * buf	/* source buffer */
)
{
    int code = 0;
    const byte *orig_buf = buf;

    do {
        gs_param_typed_value typed;
        gs_param_name key;
        unsigned key_sizeof;
        int value_top_sizeof;
        int value_base_sizeof;
        int temp_code;
        gs_param_type type;

        /* key length, 0 indicates end of data */
        key_sizeof = buf_get_word(&buf);
        if (key_sizeof == 0)	/* end of data */
            break;

        /* data type */
        type = (gs_param_type) buf_get_word(&buf);

        /* key */
        key = (gs_param_name) buf;
        buf += key_sizeof;

        /* Data values */
        value_top_sizeof = gs_param_type_sizes[type];
        value_base_sizeof = gs_param_type_base_sizes[type];
        typed.type = type;
        if (type != gs_param_type_dict && type != gs_param_type_dict_int_keys) {
            memcpy(&typed.value, buf, value_top_sizeof);
            buf += value_top_sizeof;
        }
        switch (type) {
            case gs_param_type_null:
            case gs_param_type_bool:
            case gs_param_type_int:
            case gs_param_type_long:
            case gs_param_type_float:
                break;

            case gs_param_type_string:
            case gs_param_type_name:
            case gs_param_type_int_array:
            case gs_param_type_float_array:
                ptr_align_to(&buf, value_base_sizeof);
                typed.value.s.data = buf;
                typed.value.s.persistent = false;
                buf += typed.value.s.size * value_base_sizeof;
                break;

            case gs_param_type_string_array:
            case gs_param_type_name_array:
                ptr_align_to(&buf, sizeof(void *));

                typed.value.sa.data = (const gs_param_string *)buf;
                typed.value.sa.persistent = false;
                buf += typed.value.s.size * value_base_sizeof;
                {
                    int str_count;
                    gs_param_string *sa;

                    for (str_count = typed.value.sa.size,
                         sa = (gs_param_string *) typed.value.sa.data;
                         str_count-- > 0; ++sa) {
                        sa->data = buf;
                        sa->persistent = false;
                        buf += sa->size;
                    }
                }
                break;

            case gs_param_type_dict:
            case gs_param_type_dict_int_keys:
                typed.value.d.size = buf_get_word(&buf);
                code = param_begin_write_dict
                    (list, key, &typed.value.d, type == gs_param_type_dict_int_keys);
                if (code < 0)
                    break;
                ptr_align_to(&buf, sizeof(void *));

                code = gs_param_list_unserialize(typed.value.d.list, buf);
                temp_code = param_end_write_dict(list, key, &typed.value.d);
                if (code >= 0) {
                    buf += code;
                    code = temp_code;
                }
                break;

            default:
                code = gs_note_error(gs_error_unknownerror);
                break;
        }
        if (code < 0)
            break;
        if (typed.type != gs_param_type_dict && typed.type != gs_param_type_dict_int_keys)
            code = param_write_typed(list, key, &typed);
    }
    while (code >= 0);

    return code >= 0 ? buf - orig_buf : code;
}