1 /* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gsparamx.c,v 1.6 2002/02/21 22:24:52 giles Exp $ */
18 /* Extended parameter dictionary utilities */
19 #include "string_.h"
20 #include "gserror.h"
21 #include "gserrors.h"
22 #include "gstypes.h"
23 #include "gsmemory.h"
24 #include "gsparam.h"
25 #include "gsparamx.h"
26
27 /* Compare a C string and a gs_param_string. */
28 bool
gs_param_string_eq(const gs_param_string * pcs,const char * str)29 gs_param_string_eq(const gs_param_string * pcs, const char *str)
30 {
31 return (strlen(str) == pcs->size &&
32 !strncmp(str, (const char *)pcs->data, pcs->size));
33 }
34
35 /* Put an enumerated value. */
36 int
param_put_enum(gs_param_list * plist,gs_param_name param_name,int * pvalue,const char * const pnames[],int ecode)37 param_put_enum(gs_param_list * plist, gs_param_name param_name,
38 int *pvalue, const char *const pnames[], int ecode)
39 {
40 gs_param_string ens;
41 int code = param_read_name(plist, param_name, &ens);
42
43 switch (code) {
44 case 1:
45 return ecode;
46 case 0:
47 {
48 int i;
49
50 for (i = 0; pnames[i] != 0; ++i)
51 if (gs_param_string_eq(&ens, pnames[i])) {
52 *pvalue = i;
53 return 0;
54 }
55 }
56 code = gs_error_rangecheck;
57 default:
58 ecode = code;
59 param_signal_error(plist, param_name, code);
60 }
61 return code;
62 }
63
64 /* Put a Boolean value. */
65 int
param_put_bool(gs_param_list * plist,gs_param_name param_name,bool * pval,int ecode)66 param_put_bool(gs_param_list * plist, gs_param_name param_name,
67 bool * pval, int ecode)
68 {
69 int code;
70
71 switch (code = param_read_bool(plist, param_name, pval)) {
72 default:
73 ecode = code;
74 param_signal_error(plist, param_name, ecode);
75 case 0:
76 case 1:
77 break;
78 }
79 return ecode;
80 }
81
82 /* Put an integer value. */
83 int
param_put_int(gs_param_list * plist,gs_param_name param_name,int * pval,int ecode)84 param_put_int(gs_param_list * plist, gs_param_name param_name,
85 int *pval, int ecode)
86 {
87 int code;
88
89 switch (code = param_read_int(plist, param_name, pval)) {
90 default:
91 ecode = code;
92 param_signal_error(plist, param_name, ecode);
93 case 0:
94 case 1:
95 break;
96 }
97 return ecode;
98 }
99
100 /* Put a long value. */
101 int
param_put_long(gs_param_list * plist,gs_param_name param_name,long * pval,int ecode)102 param_put_long(gs_param_list * plist, gs_param_name param_name,
103 long *pval, int ecode)
104 {
105 int code;
106
107 switch (code = param_read_long(plist, param_name, pval)) {
108 default:
109 ecode = code;
110 param_signal_error(plist, param_name, ecode);
111 case 0:
112 case 1:
113 break;
114 }
115 return ecode;
116 }
117
118 /* Copy one parameter list to another, recursively if necessary. */
119 int
param_list_copy(gs_param_list * plto,gs_param_list * plfrom)120 param_list_copy(gs_param_list *plto, gs_param_list *plfrom)
121 {
122 gs_param_enumerator_t key_enum;
123 gs_param_key_t key;
124 /*
125 * If plfrom and plto use different allocators, we must copy
126 * aggregate values even if they are "persistent".
127 */
128 bool copy_persists = plto->memory == plfrom->memory;
129 int code;
130
131 param_init_enumerator(&key_enum);
132 while ((code = param_get_next_key(plfrom, &key_enum, &key)) == 0) {
133 char string_key[256]; /* big enough for any reasonable key */
134 gs_param_typed_value value;
135 gs_param_collection_type_t coll_type;
136 gs_param_typed_value copy;
137
138 if (key.size > sizeof(string_key) - 1) {
139 code = gs_note_error(gs_error_rangecheck);
140 break;
141 }
142 memcpy(string_key, key.data, key.size);
143 string_key[key.size] = 0;
144 if ((code = param_read_typed(plfrom, string_key, &value)) != 0) {
145 code = (code > 0 ? gs_note_error(gs_error_unknownerror) : code);
146 break;
147 }
148 gs_param_list_set_persistent_keys(plto, key.persistent);
149 switch (value.type) {
150 case gs_param_type_dict:
151 coll_type = gs_param_collection_dict_any;
152 goto cc;
153 case gs_param_type_dict_int_keys:
154 coll_type = gs_param_collection_dict_int_keys;
155 goto cc;
156 case gs_param_type_array:
157 coll_type = gs_param_collection_array;
158 cc:
159 copy.value.d.size = value.value.d.size;
160 if ((code = param_begin_write_collection(plto, string_key,
161 ©.value.d,
162 coll_type)) < 0 ||
163 (code = param_list_copy(copy.value.d.list,
164 value.value.d.list)) < 0 ||
165 (code = param_end_write_collection(plto, string_key,
166 ©.value.d)) < 0)
167 break;
168 code = param_end_read_collection(plfrom, string_key,
169 &value.value.d);
170 break;
171 case gs_param_type_string:
172 value.value.s.persistent &= copy_persists; goto ca;
173 case gs_param_type_name:
174 value.value.n.persistent &= copy_persists; goto ca;
175 case gs_param_type_int_array:
176 value.value.ia.persistent &= copy_persists; goto ca;
177 case gs_param_type_float_array:
178 value.value.fa.persistent &= copy_persists; goto ca;
179 case gs_param_type_string_array:
180 value.value.sa.persistent &= copy_persists;
181 ca:
182 default:
183 code = param_write_typed(plto, string_key, &value);
184 }
185 if (code < 0)
186 break;
187 }
188 return code;
189 }
190