/src/ghostpdl/base/gsparam.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2021 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, |
13 | | CA 94945, U.S.A., +1(415)492-9861, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Support for parameter lists */ |
18 | | #include "memory_.h" |
19 | | #include "string_.h" |
20 | | #include "gx.h" |
21 | | #include "gserrors.h" |
22 | | #include "gsparam.h" |
23 | | #include "gsstruct.h" |
24 | | |
25 | | /* GC procedures */ |
26 | 0 | ENUM_PTRS_WITH(gs_param_typed_value_enum_ptrs, gs_param_typed_value *pvalue) return 0; |
27 | 0 | case 0: |
28 | 0 | switch (pvalue->type) { |
29 | 0 | case gs_param_type_string: |
30 | 0 | return ENUM_STRING(&pvalue->value.s); |
31 | 0 | case gs_param_type_name: |
32 | 0 | return ENUM_STRING(&pvalue->value.n); |
33 | 0 | case gs_param_type_int_array: |
34 | 0 | return ENUM_OBJ(pvalue->value.ia.data); |
35 | 0 | case gs_param_type_float_array: |
36 | 0 | return ENUM_OBJ(pvalue->value.fa.data); |
37 | 0 | case gs_param_type_string_array: |
38 | 0 | return ENUM_OBJ(pvalue->value.sa.data); |
39 | 0 | case gs_param_type_name_array: |
40 | 0 | return ENUM_OBJ(pvalue->value.na.data); |
41 | 0 | default: |
42 | 0 | return ENUM_OBJ(0); /* don't stop early */ |
43 | 0 | } |
44 | 0 | ENUM_PTRS_END |
45 | 0 | RELOC_PTRS_WITH(gs_param_typed_value_reloc_ptrs, gs_param_typed_value *pvalue) { |
46 | 0 | switch (pvalue->type) { |
47 | 0 | case gs_param_type_string: |
48 | 0 | case gs_param_type_name: { |
49 | 0 | gs_const_string str; |
50 | |
|
51 | 0 | str.data = pvalue->value.s.data; /* n == s */ |
52 | 0 | str.size = pvalue->value.s.size; |
53 | 0 | RELOC_CONST_STRING_VAR(str); |
54 | 0 | pvalue->value.s.data = str.data; |
55 | 0 | break; |
56 | 0 | } |
57 | 0 | case gs_param_type_int_array: |
58 | 0 | RELOC_VAR(pvalue->value.ia.data); |
59 | 0 | break; |
60 | 0 | case gs_param_type_float_array: |
61 | 0 | RELOC_VAR(pvalue->value.fa.data); |
62 | 0 | break; |
63 | 0 | case gs_param_type_string_array: |
64 | 0 | RELOC_VAR(pvalue->value.sa.data); |
65 | 0 | break; |
66 | 0 | case gs_param_type_name_array: |
67 | 0 | RELOC_VAR(pvalue->value.na.data); |
68 | 0 | break; |
69 | 0 | default: |
70 | 0 | break; |
71 | 0 | } |
72 | 0 | } |
73 | 0 | RELOC_PTRS_END |
74 | | |
75 | | /* Internal procedure to initialize the common part of a parameter list. */ |
76 | | void |
77 | | gs_param_list_init(gs_param_list *plist, const gs_param_list_procs *procs, |
78 | | gs_memory_t *mem) |
79 | 59.4k | { |
80 | 59.4k | plist->procs = procs; |
81 | 59.4k | plist->memory = mem; |
82 | 59.4k | plist->persistent_keys = true; |
83 | 59.4k | } |
84 | | |
85 | | /* Set whether the keys for param_write_XXX are persistent. */ |
86 | | void |
87 | | gs_param_list_set_persistent_keys(gs_param_list *plist, bool persistent) |
88 | 41 | { |
89 | 41 | plist->persistent_keys = persistent; |
90 | 41 | } |
91 | | |
92 | | /* Reset a gs_param_key_t enumerator to its initial state */ |
93 | | void |
94 | | param_init_enumerator(gs_param_enumerator_t * enumerator) |
95 | 0 | { |
96 | 0 | memset(enumerator, 0, sizeof(*enumerator)); |
97 | 0 | } |
98 | | |
99 | | /* Transfer a collection of parameters. */ |
100 | | static const byte xfer_item_sizes[] = { |
101 | | GS_PARAM_TYPE_SIZES(0) |
102 | | }; |
103 | | int |
104 | | gs_param_read_items(gs_param_list * plist, void *obj, |
105 | | const gs_param_item_t * items, |
106 | | gs_memory_t *mem) |
107 | 0 | { |
108 | 0 | const gs_param_item_t *pi; |
109 | 0 | int ecode = 0; |
110 | |
|
111 | 0 | for (pi = items; pi->key != 0; ++pi) { |
112 | 0 | const char *key = pi->key; |
113 | 0 | void *pvalue = (void *)((char *)obj + pi->offset); |
114 | 0 | gs_param_typed_value typed; |
115 | 0 | int code; |
116 | |
|
117 | 0 | typed.type = pi->type; |
118 | 0 | code = param_read_requested_typed(plist, key, &typed); |
119 | 0 | switch (code) { |
120 | 0 | default: /* < 0 */ |
121 | 0 | ecode = code; |
122 | 0 | case 1: |
123 | 0 | break; |
124 | 0 | case 0: |
125 | 0 | if (typed.type != pi->type) /* shouldn't happen! */ |
126 | 0 | ecode = gs_note_error(gs_error_typecheck); |
127 | 0 | else { |
128 | 0 | switch(typed.type) |
129 | 0 | { |
130 | 0 | case gs_param_type_dict: |
131 | 0 | case gs_param_type_dict_int_keys: |
132 | 0 | case gs_param_type_array: |
133 | 0 | return_error(gs_error_rangecheck); |
134 | 0 | case gs_param_type_string: |
135 | 0 | case gs_param_type_name: |
136 | 0 | { |
137 | 0 | void *copy; |
138 | 0 | gs_string *s; |
139 | 0 | if (mem == NULL) { |
140 | | /* Return pointers to the data in the param list. This |
141 | | * means that if the caller wants to keep it around it |
142 | | * needs to copy it itself, or run the risk of the |
143 | | * param list going away. */ |
144 | 0 | goto copy_pointer; |
145 | 0 | } |
146 | | /* Free any existing data before copying into it. */ |
147 | 0 | s = ((gs_string *)pvalue); |
148 | 0 | if (typed.value.s.size != s->size) { |
149 | 0 | gs_free_string(mem, s->data, s->size, "gs_param_read_items"); |
150 | 0 | s->data = NULL; |
151 | 0 | s->size = 0; |
152 | 0 | copy = gs_alloc_string(mem, typed.value.s.size, "gs_param_read_items"); |
153 | 0 | if (copy == NULL) |
154 | 0 | return_error(gs_error_VMerror); |
155 | 0 | s->size = typed.value.s.size; |
156 | 0 | } else { |
157 | 0 | copy = s->data; |
158 | 0 | } |
159 | 0 | memcpy(copy, typed.value.s.data, typed.value.s.size); |
160 | 0 | s->data = copy; |
161 | 0 | ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */ |
162 | 0 | break; |
163 | 0 | } |
164 | 0 | case gs_param_type_int_array: |
165 | 0 | case gs_param_type_float_array: |
166 | 0 | case gs_param_type_string_array: |
167 | 0 | case gs_param_type_name_array: |
168 | 0 | { |
169 | 0 | int eltsize; |
170 | 0 | gs_param_string_array *sa; |
171 | 0 | if (mem == NULL) { |
172 | | /* Return pointers to the data in the param list. This |
173 | | * means that if the caller wants to keep it around it |
174 | | * needs to copy it itself, or run the risk of the |
175 | | * param list going away. */ |
176 | 0 | goto copy_pointer; |
177 | 0 | } |
178 | | /* Free any existing data before copying into it. */ |
179 | 0 | eltsize = gs_param_type_base_sizes[typed.type]; |
180 | 0 | sa = ((gs_param_string_array *)pvalue); |
181 | 0 | if (typed.value.ia.size != sa->size) { |
182 | 0 | void *copy; |
183 | 0 | if (typed.type == gs_param_type_name_array || |
184 | 0 | typed.type == gs_param_type_string_array) { |
185 | | /* Free the strings. */ |
186 | 0 | int i; |
187 | 0 | gs_param_string *arr; |
188 | 0 | union { const gs_param_string *cs; gs_param_string *s; } u; |
189 | 0 | u.cs = sa->data; |
190 | 0 | arr = u.s; /* Hideous dodge to avoid the const. */ |
191 | 0 | for (i = 0; i < typed.value.sa.size; i++) { |
192 | | /* Hideous hackery to get around the const nature of gs_param_strings. */ |
193 | 0 | gs_string *arr_non_const = (gs_string *)(void *)(&arr[i]); |
194 | 0 | if (arr[i].persistent == 0) |
195 | 0 | gs_free_string(mem, arr_non_const->data, arr_non_const->size, "gs_param_read_items"); |
196 | 0 | arr_non_const->data = NULL; |
197 | 0 | arr_non_const->size = 0; |
198 | 0 | } |
199 | 0 | } |
200 | 0 | gs_free_const_object(mem, sa->data, "gs_param_read_items"); |
201 | 0 | sa->data = NULL; |
202 | 0 | sa->size = 0; |
203 | 0 | copy = gs_alloc_bytes(mem, eltsize * typed.value.s.size, "gs_param_read_items"); |
204 | 0 | if (copy == NULL) |
205 | 0 | return_error(gs_error_VMerror); |
206 | 0 | memset(copy, 0, eltsize * typed.value.s.size); |
207 | 0 | sa->size = typed.value.s.size; |
208 | 0 | sa->data = copy; |
209 | 0 | } |
210 | | /* Now copy the elements of the arrays. */ |
211 | 0 | if (typed.type == gs_param_type_name_array || |
212 | 0 | typed.type == gs_param_type_string_array) { |
213 | | /* Free the strings. */ |
214 | 0 | int i; |
215 | 0 | const gs_param_string *src = typed.value.sa.data; |
216 | 0 | gs_param_string *dst; |
217 | 0 | union { const gs_param_string *cs; gs_param_string *s; } u; |
218 | 0 | u.cs = sa->data; |
219 | 0 | dst = u.s; /* Hideous dodge to avoid the const. */ |
220 | 0 | for (i = 0; i < typed.value.sa.size; i++) { |
221 | | /* Hideous hackery to get around the const nature of gs_param_strings. */ |
222 | 0 | gs_string *dst_non_const = (gs_string *)(void *)(&dst[i]); |
223 | 0 | if (dst[i].persistent == 0) |
224 | 0 | gs_free_string(mem, dst_non_const->data, dst_non_const->size, "gs_param_read_items"); |
225 | 0 | dst_non_const->data = NULL; |
226 | 0 | dst_non_const->size = 0; |
227 | 0 | } |
228 | | /* Copy values */ |
229 | 0 | for (i = 0; i < sa->size; i++) { |
230 | 0 | dst[i].data = gs_alloc_string(mem, src[i].size, "gs_param_read_items"); |
231 | 0 | if (dst[i].data == NULL) |
232 | 0 | return_error(gs_error_VMerror); |
233 | 0 | dst[i].size = src[i].size; |
234 | 0 | dst[i].persistent = 0; /* 0 => We own this copy */ |
235 | 0 | } |
236 | 0 | } else { |
237 | | /* Hideous hackery to get around the const nature of gs_param_strings. */ |
238 | 0 | gs_string *s = (gs_string *)(void *)sa; |
239 | 0 | memcpy(s->data, typed.value.s.data, eltsize * typed.value.s.size); |
240 | 0 | } |
241 | 0 | ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */ |
242 | 0 | break; |
243 | 0 | } |
244 | 0 | default: |
245 | 0 | copy_pointer: |
246 | 0 | memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]); |
247 | 0 | } |
248 | 0 | } |
249 | 0 | } |
250 | 0 | } |
251 | 0 | return ecode; |
252 | 0 | } |
253 | | int |
254 | | gs_param_write_items(gs_param_list * plist, const void *obj, |
255 | | const void *default_obj, const gs_param_item_t * items) |
256 | 0 | { |
257 | 0 | const gs_param_item_t *pi; |
258 | 0 | int ecode = 0; |
259 | |
|
260 | 0 | for (pi = items; pi->key != 0; ++pi) { |
261 | 0 | const char *key = pi->key; |
262 | 0 | const void *pvalue = (const void *)((const char *)obj + pi->offset); |
263 | 0 | int size = xfer_item_sizes[pi->type]; |
264 | 0 | gs_param_typed_value typed; |
265 | 0 | int code; |
266 | |
|
267 | 0 | if (default_obj != 0 && |
268 | 0 | !memcmp((const void *)((const char *)default_obj + pi->offset), |
269 | 0 | pvalue, size) |
270 | 0 | ) |
271 | 0 | continue; |
272 | 0 | memcpy(&typed.value, pvalue, size); |
273 | 0 | typed.type = pi->type; |
274 | | /* Ensure the list doesn't end up keeping a pointer to our values. */ |
275 | 0 | typed.value.s.persistent = 0; |
276 | 0 | code = (*plist->procs->xmit_typed) (plist, key, &typed); |
277 | 0 | if (code < 0) |
278 | 0 | ecode = code; |
279 | 0 | } |
280 | 0 | return ecode; |
281 | 0 | } |
282 | | |
283 | | /* Read a value, with coercion if requested, needed, and possible. */ |
284 | | /* If mem != 0, we can coerce int arrays to float arrays. */ |
285 | | int |
286 | | param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type, |
287 | | gs_memory_t * mem) |
288 | 280k | { |
289 | 280k | if (req_type == gs_param_type_any || pvalue->type == req_type) |
290 | 158k | return 0; |
291 | | /* |
292 | | * Look for coercion opportunities. It would be wonderful if we |
293 | | * could convert int/float arrays and name/string arrays, but |
294 | | * right now we can't. However, a 0-length heterogenous array |
295 | | * will satisfy a request for any specific type. |
296 | | */ |
297 | | /* Strictly speaking assigning one element of union |
298 | | * to another, overlapping element of a different size is |
299 | | * undefined behavior, hence assign to intermediate variables |
300 | | */ |
301 | 121k | switch (pvalue->type /* actual type */ ) { |
302 | 0 | case gs_param_type_int: |
303 | 0 | switch (req_type) { |
304 | 0 | case gs_param_type_i64: |
305 | 0 | { |
306 | 0 | int64_t i64 = (int64_t)pvalue->value.i; |
307 | 0 | pvalue->value.i64 = i64; |
308 | 0 | goto ok; |
309 | 0 | } |
310 | 0 | case gs_param_type_size_t: |
311 | 0 | { |
312 | 0 | size_t z = (size_t)pvalue->value.i; |
313 | 0 | if (pvalue->value.i < 0) |
314 | 0 | return gs_error_rangecheck; |
315 | 0 | pvalue->value.z = z; |
316 | 0 | goto ok; |
317 | 0 | } |
318 | 0 | case gs_param_type_long: |
319 | 0 | { |
320 | 0 | long l = (long)pvalue->value.i; |
321 | 0 | pvalue->value.l = l; |
322 | 0 | goto ok; |
323 | 0 | } |
324 | 0 | case gs_param_type_float: |
325 | 0 | { |
326 | 0 | float fl = (float)pvalue->value.i; |
327 | 0 | pvalue->value.f = fl; |
328 | 0 | goto ok; |
329 | 0 | } |
330 | 0 | default: |
331 | 0 | break; |
332 | 0 | } |
333 | 0 | break; |
334 | 0 | case gs_param_type_long: |
335 | 0 | switch (req_type) { |
336 | 0 | case gs_param_type_i64: |
337 | 0 | { |
338 | 0 | int64_t i64 = (int64_t)pvalue->value.l; |
339 | 0 | pvalue->value.i64 = i64; |
340 | 0 | goto ok; |
341 | 0 | } |
342 | 0 | case gs_param_type_size_t: |
343 | 0 | { |
344 | 0 | size_t z = (size_t)pvalue->value.l; |
345 | 0 | if (pvalue->value.l < 0 |
346 | | #if ARCH_SIZEOF_SIZE_T < ARCH_SIZEOF_LONG |
347 | | || pvalue->value.l != (long)z |
348 | | #endif |
349 | 0 | ) |
350 | 0 | return_error(gs_error_rangecheck); |
351 | 0 | pvalue->value.z = z; |
352 | 0 | goto ok; |
353 | 0 | } |
354 | 0 | case gs_param_type_int: |
355 | 0 | { |
356 | 0 | int int1 = (int)pvalue->value.l; |
357 | 0 | #if ARCH_SIZEOF_INT < ARCH_SIZEOF_LONG |
358 | 0 | if (pvalue->value.l != (long)int1) |
359 | 0 | return_error(gs_error_rangecheck); |
360 | 0 | #endif |
361 | 0 | pvalue->value.i = int1; |
362 | 0 | goto ok; |
363 | 0 | } |
364 | 0 | case gs_param_type_float: |
365 | 0 | { |
366 | 0 | float fl = (float)pvalue->value.l; |
367 | 0 | pvalue->value.f = fl; |
368 | 0 | goto ok; |
369 | 0 | } |
370 | 0 | default: |
371 | 0 | break; |
372 | 0 | } |
373 | 0 | break; |
374 | 114k | case gs_param_type_i64: |
375 | 114k | switch (req_type) { |
376 | 8.35k | case gs_param_type_size_t: |
377 | 8.35k | { |
378 | 8.35k | size_t z = (size_t)pvalue->value.i64; |
379 | 8.35k | if (pvalue->value.i64 < 0 |
380 | | #if ARCH_SIZEOF_SIZE_T < 8 /* sizeof(int64_t) */ |
381 | | || pvalue->value.i64 != (int64_t)z |
382 | | #endif |
383 | 8.35k | ) |
384 | 0 | return_error(gs_error_rangecheck); |
385 | 8.35k | pvalue->value.z = z; |
386 | 8.35k | goto ok; |
387 | 8.35k | } |
388 | 28.9k | case gs_param_type_long: |
389 | 28.9k | { |
390 | 28.9k | long l = (long)pvalue->value.i64; |
391 | | #if ARCH_SIZEOF_LONG < 8 /* sizeof(int64_t) */ |
392 | | if (pvalue->value.i64 != (int64_t)l) |
393 | | return_error(gs_error_rangecheck); |
394 | | #endif |
395 | 28.9k | pvalue->value.l = l; |
396 | 28.9k | goto ok; |
397 | 8.35k | } |
398 | 77.7k | case gs_param_type_int: |
399 | 77.7k | { |
400 | 77.7k | int int1 = (int)pvalue->value.i64; |
401 | 77.7k | #if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */ |
402 | 77.7k | if (pvalue->value.i64 != (int64_t)int1) |
403 | 0 | return_error(gs_error_rangecheck); |
404 | 77.7k | #endif |
405 | 77.7k | pvalue->value.i = int1; |
406 | 77.7k | goto ok; |
407 | 77.7k | } |
408 | 0 | case gs_param_type_float: |
409 | 0 | { |
410 | 0 | float fl = (float)pvalue->value.i64; |
411 | 0 | pvalue->value.f = fl; |
412 | 0 | goto ok; |
413 | 77.7k | } |
414 | 0 | default: |
415 | 0 | break; |
416 | 114k | } |
417 | 0 | break; |
418 | 0 | case gs_param_type_size_t: |
419 | 0 | switch (req_type) { |
420 | 0 | case gs_param_type_i64: |
421 | 0 | { |
422 | 0 | int64_t i64 = (int64_t)pvalue->value.z; |
423 | 0 | if (i64 < 0 |
424 | | #if 8 /* sizeof(int64_t) */ < ARCH_SIZEOF_SIZE_T |
425 | | /* Unlikely, but let's plan for the day when we need 128bit addressing :) */ |
426 | | || pvalue->value.z != (size_t)i64 |
427 | | #endif |
428 | 0 | ) |
429 | 0 | return_error(gs_error_rangecheck); |
430 | 0 | pvalue->value.i64 = i64; |
431 | 0 | goto ok; |
432 | 0 | } |
433 | 0 | case gs_param_type_long: |
434 | 0 | { |
435 | 0 | long l = (long)pvalue->value.z; |
436 | | #if ARCH_SIZEOF_LONG < 8 /* sizeof(int64_t) */ |
437 | | if (pvalue->value.z != (size_t)l) |
438 | | return_error(gs_error_rangecheck); |
439 | | #endif |
440 | 0 | pvalue->value.l = l; |
441 | 0 | goto ok; |
442 | 0 | } |
443 | 0 | case gs_param_type_int: |
444 | 0 | { |
445 | 0 | int int1 = (int)pvalue->value.z; |
446 | 0 | #if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */ |
447 | 0 | if (pvalue->value.z != (size_t)int1) |
448 | 0 | return_error(gs_error_rangecheck); |
449 | 0 | #endif |
450 | 0 | pvalue->value.i = int1; |
451 | 0 | goto ok; |
452 | 0 | } |
453 | 0 | case gs_param_type_float: |
454 | 0 | { |
455 | 0 | float fl = (float)pvalue->value.z; |
456 | 0 | pvalue->value.f = fl; |
457 | 0 | goto ok; |
458 | 0 | } |
459 | 0 | default: |
460 | 0 | break; |
461 | 0 | } |
462 | 0 | break; |
463 | 0 | case gs_param_type_string: |
464 | 0 | if (req_type == gs_param_type_name) |
465 | 0 | goto ok; |
466 | 0 | break; |
467 | 2.45k | case gs_param_type_name: |
468 | 2.45k | if (req_type == gs_param_type_string) |
469 | 2.45k | goto ok; |
470 | 0 | break; |
471 | 0 | case gs_param_type_int_array: |
472 | 0 | switch (req_type) { |
473 | 0 | case gs_param_type_float_array:{ |
474 | 0 | uint size = pvalue->value.ia.size; |
475 | 0 | float *fv; |
476 | 0 | uint i; |
477 | |
|
478 | 0 | if (mem == 0) |
479 | 0 | break; |
480 | 0 | fv = (float *)gs_alloc_byte_array(mem, size, sizeof(float), |
481 | 0 | "int array => float array"); |
482 | |
|
483 | 0 | if (fv == 0) |
484 | 0 | return_error(gs_error_VMerror); |
485 | 0 | for (i = 0; i < size; ++i) |
486 | 0 | fv[i] = (float)pvalue->value.ia.data[i]; |
487 | 0 | pvalue->value.fa.data = fv; |
488 | 0 | pvalue->value.fa.persistent = false; |
489 | 0 | goto ok; |
490 | 0 | } |
491 | 0 | default: |
492 | 0 | break; |
493 | 0 | } |
494 | 0 | break; |
495 | 0 | case gs_param_type_string_array: |
496 | 0 | if (req_type == gs_param_type_name_array) |
497 | 0 | goto ok; |
498 | 0 | break; |
499 | 0 | case gs_param_type_name_array: |
500 | 0 | if (req_type == gs_param_type_string_array) |
501 | 0 | goto ok; |
502 | 0 | break; |
503 | 1.22k | case gs_param_type_array: |
504 | 1.22k | if (pvalue->value.d.size == 0 && |
505 | 1.22k | (req_type == gs_param_type_int_array || |
506 | 1.22k | req_type == gs_param_type_float_array || |
507 | 1.22k | req_type == gs_param_type_string_array || |
508 | 1.22k | req_type == gs_param_type_name_array) |
509 | 1.22k | ) |
510 | 1.22k | goto ok; |
511 | 0 | break; |
512 | 2.45k | default: |
513 | 2.45k | break; |
514 | 121k | } |
515 | 121k | return_error(gs_error_typecheck); |
516 | 118k | ok:pvalue->type = req_type; |
517 | 118k | return 0; |
518 | 121k | } |
519 | | int |
520 | | param_read_requested_typed(gs_param_list * plist, gs_param_name pkey, |
521 | | gs_param_typed_value * pvalue) |
522 | 1.58M | { |
523 | 1.58M | gs_param_type req_type = pvalue->type; |
524 | 1.58M | int code = (*plist->procs->xmit_typed) (plist, pkey, pvalue); |
525 | | |
526 | 1.58M | if (code != 0) |
527 | 1.30M | return code; |
528 | 280k | return param_coerce_typed(pvalue, req_type, plist->memory); |
529 | 1.58M | } |
530 | | |
531 | | /* ---------------- Fixed-type reading procedures ---------------- */ |
532 | | |
533 | | #define RETURN_READ_TYPED(alt, ptype)\ |
534 | 1.57M | gs_param_typed_value typed;\ |
535 | 1.57M | int code;\ |
536 | 1.57M | \ |
537 | 1.57M | typed.type = ptype;\ |
538 | 1.57M | code = param_read_requested_typed(plist, pkey, &typed);\ |
539 | 1.57M | if ( code == 0 )\ |
540 | 1.57M | *pvalue = typed.value.alt;\ |
541 | 1.57M | return code |
542 | | |
543 | | int |
544 | | param_read_null(gs_param_list * plist, gs_param_name pkey) |
545 | 2.45k | { |
546 | 2.45k | gs_param_typed_value typed; |
547 | | |
548 | 2.45k | typed.type = gs_param_type_null; |
549 | 2.45k | return param_read_requested_typed(plist, pkey, &typed); |
550 | 2.45k | } |
551 | | int |
552 | | param_read_bool(gs_param_list * plist, gs_param_name pkey, bool * pvalue) |
553 | 269k | { |
554 | 269k | RETURN_READ_TYPED(b, gs_param_type_bool); |
555 | 269k | } |
556 | | int |
557 | | param_read_int(gs_param_list * plist, gs_param_name pkey, int *pvalue) |
558 | 390k | { |
559 | 390k | RETURN_READ_TYPED(i, gs_param_type_int); |
560 | 390k | } |
561 | | int |
562 | | param_read_long(gs_param_list * plist, gs_param_name pkey, long *pvalue) |
563 | 247k | { |
564 | 247k | RETURN_READ_TYPED(l, gs_param_type_long); |
565 | 247k | } |
566 | | int |
567 | | param_read_i64(gs_param_list * plist, gs_param_name pkey, int64_t *pvalue) |
568 | 18.4k | { |
569 | 18.4k | RETURN_READ_TYPED(i64, gs_param_type_i64); |
570 | 18.4k | } |
571 | | int |
572 | | param_read_size_t(gs_param_list * plist, gs_param_name pkey, size_t *pvalue) |
573 | 43.7k | { |
574 | 43.7k | RETURN_READ_TYPED(z, gs_param_type_size_t); |
575 | 43.7k | } |
576 | | int |
577 | | param_read_float(gs_param_list * plist, gs_param_name pkey, float *pvalue) |
578 | 107k | { |
579 | 107k | RETURN_READ_TYPED(f, gs_param_type_float); |
580 | 107k | } |
581 | | int |
582 | | param_read_string(gs_param_list * plist, gs_param_name pkey, |
583 | | gs_param_string * pvalue) |
584 | 417k | { |
585 | 417k | RETURN_READ_TYPED(s, gs_param_type_string); |
586 | 417k | } |
587 | | int |
588 | | param_read_name(gs_param_list * plist, gs_param_name pkey, |
589 | | gs_param_string * pvalue) |
590 | 6.32k | { |
591 | 6.32k | RETURN_READ_TYPED(n, gs_param_type_string); |
592 | 6.32k | } |
593 | | int |
594 | | param_read_int_array(gs_param_list * plist, gs_param_name pkey, |
595 | | gs_param_int_array * pvalue) |
596 | 6.32k | { |
597 | 6.32k | RETURN_READ_TYPED(ia, gs_param_type_int_array); |
598 | 6.32k | } |
599 | | int |
600 | | param_read_float_array(gs_param_list * plist, gs_param_name pkey, |
601 | | gs_param_float_array * pvalue) |
602 | 64.6k | { |
603 | 64.6k | RETURN_READ_TYPED(fa, gs_param_type_float_array); |
604 | 64.6k | } |
605 | | int |
606 | | param_read_string_array(gs_param_list * plist, gs_param_name pkey, |
607 | | gs_param_string_array * pvalue) |
608 | 0 | { |
609 | 0 | RETURN_READ_TYPED(sa, gs_param_type_string_array); |
610 | 0 | } |
611 | | int |
612 | | param_read_name_array(gs_param_list * plist, gs_param_name pkey, |
613 | | gs_param_string_array * pvalue) |
614 | 6.32k | { |
615 | 6.32k | RETURN_READ_TYPED(na, gs_param_type_name_array); |
616 | 6.32k | } |
617 | | |
618 | | #undef RETURN_READ_TYPED |
619 | | |
620 | | /* ---------------- Default writing procedures ---------------- */ |
621 | | |
622 | | #define RETURN_WRITE_TYPED(alt, ptype)\ |
623 | 2.30M | gs_param_typed_value typed;\ |
624 | 2.30M | \ |
625 | 2.30M | typed.value.alt = *pvalue;\ |
626 | 2.30M | typed.type = ptype;\ |
627 | 2.30M | return param_write_typed(plist, pkey, &typed) |
628 | | |
629 | | int |
630 | | param_write_null(gs_param_list * plist, gs_param_name pkey) |
631 | 41.4k | { |
632 | 41.4k | gs_param_typed_value typed; |
633 | | |
634 | 41.4k | typed.type = gs_param_type_null; |
635 | 41.4k | return param_write_typed(plist, pkey, &typed); |
636 | 41.4k | } |
637 | | int |
638 | | param_write_bool(gs_param_list * plist, gs_param_name pkey, const bool * pvalue) |
639 | 442k | { |
640 | 442k | RETURN_WRITE_TYPED(b, gs_param_type_bool); |
641 | 442k | } |
642 | | int |
643 | | param_write_int(gs_param_list * plist, gs_param_name pkey, const int *pvalue) |
644 | 796k | { |
645 | 796k | RETURN_WRITE_TYPED(i, gs_param_type_int); |
646 | 796k | } |
647 | | int |
648 | | param_write_long(gs_param_list * plist, gs_param_name pkey, const long *pvalue) |
649 | 75.4k | { |
650 | 75.4k | RETURN_WRITE_TYPED(l, gs_param_type_long); |
651 | 75.4k | } |
652 | | int |
653 | | param_write_i64(gs_param_list * plist, gs_param_name pkey, const int64_t *pvalue) |
654 | 3.41k | { |
655 | 3.41k | RETURN_WRITE_TYPED(i64, gs_param_type_i64); |
656 | 3.41k | } |
657 | | int |
658 | | param_write_size_t(gs_param_list * plist, gs_param_name pkey, const size_t *pvalue) |
659 | 61.3k | { |
660 | 61.3k | RETURN_WRITE_TYPED(z, gs_param_type_size_t); |
661 | 61.3k | } |
662 | | int |
663 | | param_write_float(gs_param_list * plist, gs_param_name pkey, |
664 | | const float *pvalue) |
665 | 234k | { |
666 | 234k | RETURN_WRITE_TYPED(f, gs_param_type_float); |
667 | 234k | } |
668 | | int |
669 | | param_write_string(gs_param_list * plist, gs_param_name pkey, |
670 | | const gs_param_string * pvalue) |
671 | 552k | { |
672 | 552k | RETURN_WRITE_TYPED(s, gs_param_type_string); |
673 | 552k | } |
674 | | int |
675 | | param_write_name(gs_param_list * plist, gs_param_name pkey, |
676 | | const gs_param_string * pvalue) |
677 | 41.4k | { |
678 | 41.4k | RETURN_WRITE_TYPED(n, gs_param_type_name); |
679 | 41.4k | } |
680 | | int |
681 | | param_write_int_array(gs_param_list * plist, gs_param_name pkey, |
682 | | const gs_param_int_array * pvalue) |
683 | 13.8k | { |
684 | 13.8k | RETURN_WRITE_TYPED(ia, gs_param_type_int_array); |
685 | 13.8k | } |
686 | | int |
687 | | param_write_int_values(gs_param_list * plist, gs_param_name pkey, |
688 | | const int *values, uint size, bool persistent) |
689 | 0 | { |
690 | 0 | gs_param_int_array ia; |
691 | |
|
692 | 0 | ia.data = values, ia.size = size, ia.persistent = persistent; |
693 | 0 | return param_write_int_array(plist, pkey, &ia); |
694 | 0 | } |
695 | | int |
696 | | param_write_float_array(gs_param_list * plist, gs_param_name pkey, |
697 | | const gs_param_float_array * pvalue) |
698 | 69.7k | { |
699 | 69.7k | RETURN_WRITE_TYPED(fa, gs_param_type_float_array); |
700 | 69.7k | } |
701 | | int |
702 | | param_write_float_values(gs_param_list * plist, gs_param_name pkey, |
703 | | const float *values, uint size, bool persistent) |
704 | 0 | { |
705 | 0 | gs_param_float_array fa; |
706 | |
|
707 | 0 | fa.data = values, fa.size = size, fa.persistent = persistent; |
708 | 0 | return param_write_float_array(plist, pkey, &fa); |
709 | 0 | } |
710 | | int |
711 | | param_write_string_array(gs_param_list * plist, gs_param_name pkey, |
712 | | const gs_param_string_array * pvalue) |
713 | 0 | { |
714 | 0 | RETURN_WRITE_TYPED(sa, gs_param_type_string_array); |
715 | 0 | } |
716 | | int |
717 | | param_write_name_array(gs_param_list * plist, gs_param_name pkey, |
718 | | const gs_param_string_array * pvalue) |
719 | 13.8k | { |
720 | 13.8k | RETURN_WRITE_TYPED(na, gs_param_type_name_array); |
721 | 13.8k | } |
722 | | |
723 | | #undef RETURN_WRITE_TYPED |
724 | | |
725 | | /* ---------------- Default request implementation ---------------- */ |
726 | | |
727 | | int |
728 | | gs_param_request_default(gs_param_list * plist, gs_param_name pkey) |
729 | 0 | { |
730 | 0 | return 0; |
731 | 0 | } |
732 | | |
733 | | int |
734 | | gs_param_requested_default(const gs_param_list * plist, gs_param_name pkey) |
735 | 0 | { |
736 | 0 | return -1; /* requested by default */ |
737 | 0 | } |