Coverage Report

Created: 2025-06-10 07:15

/src/ghostpdl/base/gsparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 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.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, 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
1.00M
ENUM_PTRS_WITH(gs_param_typed_value_enum_ptrs, gs_param_typed_value *pvalue) return 0;
27
503k
    case 0:
28
503k
    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
212k
    case gs_param_type_int_array:
34
212k
        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
291k
    default:
42
291k
        return ENUM_OBJ(0);  /* don't stop early */
43
503k
    }
44
1.00M
ENUM_PTRS_END
45
503k
RELOC_PTRS_WITH(gs_param_typed_value_reloc_ptrs, gs_param_typed_value *pvalue) {
46
503k
    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
212k
    case gs_param_type_int_array:
58
212k
        RELOC_VAR(pvalue->value.ia.data);
59
212k
        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
291k
    default:
70
291k
        break;
71
503k
    }
72
503k
}
73
503k
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
3.63M
{
80
3.63M
    plist->procs = procs;
81
3.63M
    plist->memory = mem;
82
3.63M
    plist->persistent_keys = true;
83
3.63M
}
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
5.48M
{
89
5.48M
    plist->persistent_keys = persistent;
90
5.48M
}
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
1.44M
{
96
1.44M
    memset(enumerator, 0, sizeof(*enumerator));
97
1.44M
}
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
550k
{
108
550k
    const gs_param_item_t *pi;
109
550k
    int ecode = 0;
110
111
12.9M
    for (pi = items; pi->key != 0; ++pi) {
112
12.4M
        const char *key = pi->key;
113
12.4M
        void *pvalue = (void *)((char *)obj + pi->offset);
114
12.4M
        gs_param_typed_value typed;
115
12.4M
        int code;
116
117
12.4M
        typed.type = pi->type;
118
12.4M
        code = param_read_requested_typed(plist, key, &typed);
119
12.4M
        switch (code) {
120
0
            default:    /* < 0 */
121
0
                ecode = code;
122
10.9M
            case 1:
123
10.9M
                break;
124
1.52M
            case 0:
125
1.52M
                if (typed.type != pi->type)  /* shouldn't happen! */
126
0
                    ecode = gs_note_error(gs_error_typecheck);
127
1.52M
                else {
128
1.52M
                    switch(typed.type)
129
1.52M
                    {
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
39.9k
                    case gs_param_type_string:
135
39.9k
                    case gs_param_type_name:
136
39.9k
                    {
137
39.9k
                        void *copy;
138
39.9k
                        gs_string *s;
139
39.9k
                        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
39.9k
                        s = ((gs_string *)pvalue);
148
39.9k
                        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
39.9k
                        } else {
157
39.9k
                            copy = s->data;
158
39.9k
                        }
159
39.9k
                        if (typed.value.s.size > 0)
160
0
                            memcpy(copy, typed.value.s.data, typed.value.s.size);
161
39.9k
                        s->data = copy;
162
39.9k
                        ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */
163
39.9k
                        break;
164
39.9k
                    }
165
0
                    case gs_param_type_int_array:
166
41.4k
                    case gs_param_type_float_array:
167
41.4k
                    case gs_param_type_string_array:
168
41.4k
                    case gs_param_type_name_array:
169
41.4k
                    {
170
41.4k
                        int eltsize;
171
41.4k
                        gs_param_string_array *sa;
172
41.4k
                        if (mem == NULL) {
173
                            /* Return pointers to the data in the param list. This
174
                             * means that if the caller wants to keep it around it
175
                             * needs to copy it itself, or run the risk of the
176
                             * param list going away. */
177
0
                            goto copy_pointer;
178
0
                        }
179
                        /* Free any existing data before copying into it. */
180
41.4k
                        eltsize = gs_param_type_base_sizes[typed.type];
181
41.4k
                        sa = ((gs_param_string_array *)pvalue);
182
41.4k
                        if (typed.value.ia.size != sa->size) {
183
25.4k
                            void *copy;
184
25.4k
                            if (typed.type == gs_param_type_name_array ||
185
25.4k
                                typed.type == gs_param_type_string_array) {
186
                                /* Free the strings. */
187
0
                                int i;
188
0
                                gs_param_string *arr;
189
0
                                union { const gs_param_string *cs; gs_param_string *s; } u;
190
0
                                u.cs = sa->data;
191
0
                                arr = u.s; /* Hideous dodge to avoid the const. */
192
0
                                for (i = 0; i < typed.value.sa.size; i++) {
193
                                    /* Hideous hackery to get around the const nature of gs_param_strings. */
194
0
                                    gs_string *arr_non_const = (gs_string *)(void *)(&arr[i]);
195
0
                                    if (arr[i].persistent == 0)
196
0
                                        gs_free_string(mem, arr_non_const->data, arr_non_const->size, "gs_param_read_items");
197
0
                                    arr_non_const->data = NULL;
198
0
                                    arr_non_const->size = 0;
199
0
                                }
200
0
                            }
201
25.4k
                            gs_free_const_object(mem, sa->data, "gs_param_read_items");
202
25.4k
                            sa->data = NULL;
203
25.4k
                            sa->size = 0;
204
25.4k
                            copy = gs_alloc_bytes(mem, eltsize * typed.value.s.size, "gs_param_read_items");
205
25.4k
                            if (copy == NULL)
206
0
                                return_error(gs_error_VMerror);
207
25.4k
                            memset(copy, 0, eltsize * typed.value.s.size);
208
25.4k
                            sa->size = typed.value.s.size;
209
25.4k
                            sa->data = copy;
210
25.4k
                        }
211
                        /* Now copy the elements of the arrays. */
212
41.4k
                        if (typed.type == gs_param_type_name_array ||
213
41.4k
                            typed.type == gs_param_type_string_array) {
214
                            /* Free the strings. */
215
0
                            int i;
216
0
                            const gs_param_string *src = typed.value.sa.data;
217
0
                            gs_param_string *dst;
218
0
                            union { const gs_param_string *cs; gs_param_string *s; } u;
219
0
                            u.cs = sa->data;
220
0
                            dst = u.s; /* Hideous dodge to avoid the const. */
221
0
                            for (i = 0; i < typed.value.sa.size; i++) {
222
                                /* Hideous hackery to get around the const nature of gs_param_strings. */
223
0
                                gs_string *dst_non_const = (gs_string *)(void *)(&dst[i]);
224
0
                                if (dst[i].persistent == 0)
225
0
                                    gs_free_string(mem, dst_non_const->data, dst_non_const->size, "gs_param_read_items");
226
0
                                dst_non_const->data = NULL;
227
0
                                dst_non_const->size = 0;
228
0
                            }
229
                            /* Copy values */
230
0
                            for (i = 0; i < sa->size; i++) {
231
0
                                dst[i].data = gs_alloc_string(mem, src[i].size, "gs_param_read_items");
232
0
                                if (dst[i].data == NULL)
233
0
                                    return_error(gs_error_VMerror);
234
0
                                dst[i].size = src[i].size;
235
0
                                dst[i].persistent = 0; /* 0 => We own this copy */
236
0
                            }
237
41.4k
                        } else {
238
                            /* Hideous hackery to get around the const nature of gs_param_strings. */
239
41.4k
                            gs_string *s = (gs_string *)(void *)sa;
240
41.4k
                            if (typed.value.s.size > 0)
241
41.4k
                                memcpy(s->data, typed.value.s.data, eltsize * typed.value.s.size);
242
41.4k
                        }
243
41.4k
                        ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */
244
41.4k
                        break;
245
41.4k
                    }
246
1.44M
                    default:
247
1.44M
    copy_pointer:
248
1.44M
                        memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]);
249
1.52M
                    }
250
1.52M
                }
251
12.4M
        }
252
12.4M
    }
253
550k
    return ecode;
254
550k
}
255
int
256
gs_param_write_items(gs_param_list * plist, const void *obj,
257
                     const void *default_obj, const gs_param_item_t * items)
258
1.69M
{
259
1.69M
    const gs_param_item_t *pi;
260
1.69M
    int ecode = 0;
261
262
38.7M
    for (pi = items; pi->key != 0; ++pi) {
263
37.0M
        const char *key = pi->key;
264
37.0M
        const void *pvalue = (const void *)((const char *)obj + pi->offset);
265
37.0M
        int size = xfer_item_sizes[pi->type];
266
37.0M
        gs_param_typed_value typed;
267
37.0M
        int code;
268
269
37.0M
        if (default_obj != 0 &&
270
37.0M
            !memcmp((const void *)((const char *)default_obj + pi->offset),
271
927k
                    pvalue, size)
272
37.0M
            )
273
697k
            continue;
274
36.3M
        if (size > 0)
275
36.3M
            memcpy(&typed.value, pvalue, size);
276
36.3M
        typed.type = pi->type;
277
        /* Ensure the list doesn't end up keeping a pointer to our values. */
278
36.3M
        typed.value.s.persistent = 0;
279
36.3M
        code = (*plist->procs->xmit_typed) (plist, key, &typed);
280
36.3M
        if (code < 0)
281
0
            ecode = code;
282
36.3M
    }
283
1.69M
    return ecode;
284
1.69M
}
285
286
/* Read a value, with coercion if requested, needed, and possible. */
287
/* If mem != 0, we can coerce int arrays to float arrays. */
288
int
289
param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type,
290
                   gs_memory_t * mem)
291
14.9M
{
292
14.9M
    if (req_type == gs_param_type_any || pvalue->type == req_type)
293
13.1M
        return 0;
294
    /*
295
     * Look for coercion opportunities.  It would be wonderful if we
296
     * could convert int/float arrays and name/string arrays, but
297
     * right now we can't.  However, a 0-length heterogenous array
298
     * will satisfy a request for any specific type.
299
     */
300
    /* Strictly speaking assigning one element of union
301
     * to another, overlapping element of a different size is
302
     * undefined behavior, hence assign to intermediate variables
303
     */
304
1.81M
    switch (pvalue->type /* actual type */ ) {
305
0
        case gs_param_type_int:
306
0
            switch (req_type) {
307
0
                case gs_param_type_i64:
308
0
                {
309
0
                    int64_t i64 = (int64_t)pvalue->value.i;
310
0
                    pvalue->value.i64 = i64;
311
0
                    goto ok;
312
0
                }
313
0
                case gs_param_type_size_t:
314
0
                {
315
0
                    size_t z = (size_t)pvalue->value.i;
316
0
                    if (pvalue->value.i < 0)
317
0
                        return gs_error_rangecheck;
318
0
                    pvalue->value.z = z;
319
0
                    goto ok;
320
0
                }
321
0
                case gs_param_type_long:
322
0
                {
323
0
                    long l = (long)pvalue->value.i;
324
0
                    pvalue->value.l = l;
325
0
                    goto ok;
326
0
                }
327
0
                case gs_param_type_float:
328
0
                {
329
0
                    float fl = (float)pvalue->value.i;
330
0
                    pvalue->value.f = fl;
331
0
                    goto ok;
332
0
                }
333
0
                default:
334
0
                    break;
335
0
            }
336
0
            break;
337
0
        case gs_param_type_long:
338
0
            switch (req_type) {
339
0
                case gs_param_type_i64:
340
0
                {
341
0
                    int64_t i64 = (int64_t)pvalue->value.l;
342
0
                    pvalue->value.i64 = i64;
343
0
                    goto ok;
344
0
                }
345
0
                case gs_param_type_size_t:
346
0
                {
347
0
                    size_t z = (size_t)pvalue->value.l;
348
0
                    if (pvalue->value.l < 0
349
#if ARCH_SIZEOF_SIZE_T < ARCH_SIZEOF_LONG
350
                        || pvalue->value.l != (long)z
351
#endif
352
0
                        )
353
0
                        return_error(gs_error_rangecheck);
354
0
                    pvalue->value.z = z;
355
0
                    goto ok;
356
0
                }
357
0
                case gs_param_type_int:
358
0
                {
359
0
                    int int1 = (int)pvalue->value.l;
360
0
#if ARCH_SIZEOF_INT < ARCH_SIZEOF_LONG
361
0
                    if (pvalue->value.l != (long)int1)
362
0
                        return_error(gs_error_rangecheck);
363
0
#endif
364
0
                    pvalue->value.i = int1;
365
0
                    goto ok;
366
0
                }
367
0
                case gs_param_type_float:
368
0
                {
369
0
                    float fl = (float)pvalue->value.l;
370
0
                    pvalue->value.f = fl;
371
0
                    goto ok;
372
0
                }
373
0
                default:
374
0
                    break;
375
0
            }
376
0
            break;
377
1.31M
        case gs_param_type_i64:
378
1.31M
            switch (req_type) {
379
121k
                case gs_param_type_size_t:
380
121k
                {
381
121k
                    size_t z = (size_t)pvalue->value.i64;
382
121k
                    if (pvalue->value.i64 < 0
383
#if ARCH_SIZEOF_SIZE_T < 8 /* sizeof(int64_t) */
384
                        || pvalue->value.i64 != (int64_t)z
385
#endif
386
121k
                        )
387
0
                        return_error(gs_error_rangecheck);
388
121k
                    pvalue->value.z = z;
389
121k
                    goto ok;
390
121k
                }
391
611k
                case gs_param_type_long:
392
611k
                {
393
611k
                    long l = (long)pvalue->value.i64;
394
#if ARCH_SIZEOF_LONG < 8 /* sizeof(int64_t) */
395
                    if (pvalue->value.i64 != (int64_t)l)
396
                        return_error(gs_error_rangecheck);
397
#endif
398
611k
                    pvalue->value.l = l;
399
611k
                    goto ok;
400
121k
                }
401
581k
                case gs_param_type_int:
402
581k
                {
403
581k
                    int int1 = (int)pvalue->value.i64;
404
581k
#if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */
405
581k
                    if (pvalue->value.i64 != (int64_t)int1)
406
0
                        return_error(gs_error_rangecheck);
407
581k
#endif
408
581k
                    pvalue->value.i = int1;
409
581k
                    goto ok;
410
581k
                }
411
0
                case gs_param_type_float:
412
0
                {
413
0
                    float fl = (float)pvalue->value.i64;
414
0
                    pvalue->value.f = fl;
415
0
                    goto ok;
416
581k
                }
417
0
                default:
418
0
                    break;
419
1.31M
            }
420
0
            break;
421
0
        case gs_param_type_size_t:
422
0
            switch (req_type) {
423
0
                case gs_param_type_i64:
424
0
                {
425
0
                    int64_t i64 = (int64_t)pvalue->value.z;
426
0
                    if (i64 < 0
427
#if 8 /* sizeof(int64_t) */ < ARCH_SIZEOF_SIZE_T
428
                        /* Unlikely, but let's plan for the day when we need 128bit addressing :) */
429
                        || pvalue->value.z != (size_t)i64
430
#endif
431
0
                        )
432
0
                        return_error(gs_error_rangecheck);
433
0
                    pvalue->value.i64 = i64;
434
0
                    goto ok;
435
0
                }
436
0
                case gs_param_type_long:
437
0
                {
438
0
                    long l = (long)pvalue->value.z;
439
#if ARCH_SIZEOF_LONG < 8 /* sizeof(int64_t) */
440
                    if (pvalue->value.z != (size_t)l)
441
                        return_error(gs_error_rangecheck);
442
#endif
443
0
                    pvalue->value.l = l;
444
0
                    goto ok;
445
0
                }
446
0
                case gs_param_type_int:
447
0
                {
448
0
                    int int1 = (int)pvalue->value.z;
449
0
#if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */
450
0
                    if (pvalue->value.z != (size_t)int1)
451
0
                        return_error(gs_error_rangecheck);
452
0
#endif
453
0
                    pvalue->value.i = int1;
454
0
                    goto ok;
455
0
                }
456
0
                case gs_param_type_float:
457
0
                {
458
0
                    float fl = (float)pvalue->value.z;
459
0
                    pvalue->value.f = fl;
460
0
                    goto ok;
461
0
                }
462
0
                default:
463
0
                    break;
464
0
            }
465
0
            break;
466
0
        case gs_param_type_string:
467
0
            if (req_type == gs_param_type_name)
468
0
                goto ok;
469
0
            break;
470
293k
        case gs_param_type_name:
471
293k
            if (req_type == gs_param_type_string)
472
293k
                goto ok;
473
0
            break;
474
25.4k
        case gs_param_type_int_array:
475
25.4k
            switch (req_type) {
476
25.4k
                case gs_param_type_float_array:{
477
25.4k
                        uint size = pvalue->value.ia.size;
478
25.4k
                        float *fv;
479
25.4k
                        uint i;
480
481
25.4k
                        if (mem == 0)
482
0
                            break;
483
25.4k
                        fv = (float *)gs_alloc_byte_array(mem, size, sizeof(float),
484
25.4k
                                                "int array => float array");
485
486
25.4k
                        if (fv == 0)
487
0
                            return_error(gs_error_VMerror);
488
127k
                        for (i = 0; i < size; ++i)
489
101k
                            fv[i] = (float)pvalue->value.ia.data[i];
490
25.4k
                        pvalue->value.fa.data = fv;
491
25.4k
                        pvalue->value.fa.persistent = false;
492
25.4k
                        goto ok;
493
25.4k
                    }
494
12
                default:
495
12
                    break;
496
25.4k
            }
497
12
            break;
498
12
        case gs_param_type_string_array:
499
0
            if (req_type == gs_param_type_name_array)
500
0
                goto ok;
501
0
            break;
502
4.61k
        case gs_param_type_name_array:
503
4.61k
            if (req_type == gs_param_type_string_array)
504
4.61k
                goto ok;
505
0
            break;
506
156k
        case gs_param_type_array:
507
156k
            if (pvalue->value.d.size == 0 &&
508
156k
                (req_type == gs_param_type_int_array ||
509
156k
                 req_type == gs_param_type_float_array ||
510
156k
                 req_type == gs_param_type_string_array ||
511
156k
                 req_type == gs_param_type_name_array)
512
156k
                )
513
156k
                goto ok;
514
0
            break;
515
15.9k
        default:
516
15.9k
            break;
517
1.81M
    }
518
1.81M
    return_error(gs_error_typecheck);
519
1.79M
  ok:pvalue->type = req_type;
520
1.79M
    return 0;
521
1.81M
}
522
int
523
param_read_requested_typed(gs_param_list * plist, gs_param_name pkey,
524
                           gs_param_typed_value * pvalue)
525
41.2M
{
526
41.2M
    gs_param_type req_type = pvalue->type;
527
41.2M
    int code = (*plist->procs->xmit_typed) (plist, pkey, pvalue);
528
529
41.2M
    if (code != 0)
530
31.5M
        return code;
531
9.75M
    return param_coerce_typed(pvalue, req_type, plist->memory);
532
41.2M
}
533
534
/* ---------------- Fixed-type reading procedures ---------------- */
535
536
#define RETURN_READ_TYPED(alt, ptype)\
537
23.3M
  gs_param_typed_value typed;\
538
23.3M
  int code;\
539
23.3M
\
540
23.3M
  typed.type = ptype;\
541
23.3M
  code = param_read_requested_typed(plist, pkey, &typed);\
542
23.3M
  if ( code == 0 )\
543
23.3M
    *pvalue = typed.value.alt;\
544
23.3M
  return code
545
546
int
547
param_read_null(gs_param_list * plist, gs_param_name pkey)
548
15.9k
{
549
15.9k
    gs_param_typed_value typed;
550
551
15.9k
    typed.type = gs_param_type_null;
552
15.9k
    return param_read_requested_typed(plist, pkey, &typed);
553
15.9k
}
554
int
555
param_read_bool(gs_param_list * plist, gs_param_name pkey, bool * pvalue)
556
4.45M
{
557
4.45M
    RETURN_READ_TYPED(b, gs_param_type_bool);
558
4.45M
}
559
int
560
param_read_int(gs_param_list * plist, gs_param_name pkey, int *pvalue)
561
3.19M
{
562
3.19M
    RETURN_READ_TYPED(i, gs_param_type_int);
563
3.19M
}
564
int
565
param_read_long(gs_param_list * plist, gs_param_name pkey, long *pvalue)
566
4.60M
{
567
4.60M
    RETURN_READ_TYPED(l, gs_param_type_long);
568
4.60M
}
569
int
570
param_read_i64(gs_param_list * plist, gs_param_name pkey, int64_t *pvalue)
571
348k
{
572
348k
    RETURN_READ_TYPED(i64, gs_param_type_i64);
573
348k
}
574
int
575
param_read_size_t(gs_param_list * plist, gs_param_name pkey, size_t *pvalue)
576
789k
{
577
789k
    RETURN_READ_TYPED(z, gs_param_type_size_t);
578
789k
}
579
int
580
param_read_float(gs_param_list * plist, gs_param_name pkey, float *pvalue)
581
440k
{
582
440k
    RETURN_READ_TYPED(f, gs_param_type_float);
583
440k
}
584
int
585
param_read_string(gs_param_list * plist, gs_param_name pkey,
586
                  gs_param_string * pvalue)
587
5.64M
{
588
5.64M
    RETURN_READ_TYPED(s, gs_param_type_string);
589
5.64M
}
590
int
591
param_read_name(gs_param_list * plist, gs_param_name pkey,
592
                gs_param_string * pvalue)
593
1.32M
{
594
1.32M
    RETURN_READ_TYPED(n, gs_param_type_string);
595
1.32M
}
596
int
597
param_read_int_array(gs_param_list * plist, gs_param_name pkey,
598
                     gs_param_int_array * pvalue)
599
110k
{
600
110k
    RETURN_READ_TYPED(ia, gs_param_type_int_array);
601
110k
}
602
int
603
param_read_float_array(gs_param_list * plist, gs_param_name pkey,
604
                       gs_param_float_array * pvalue)
605
660k
{
606
660k
    RETURN_READ_TYPED(fa, gs_param_type_float_array);
607
660k
}
608
int
609
param_read_string_array(gs_param_list * plist, gs_param_name pkey,
610
                        gs_param_string_array * pvalue)
611
229k
{
612
229k
    RETURN_READ_TYPED(sa, gs_param_type_string_array);
613
229k
}
614
int
615
param_read_name_array(gs_param_list * plist, gs_param_name pkey,
616
                      gs_param_string_array * pvalue)
617
1.54M
{
618
1.54M
    RETURN_READ_TYPED(na, gs_param_type_name_array);
619
1.54M
}
620
621
#undef RETURN_READ_TYPED
622
623
/* ---------------- Default writing procedures ---------------- */
624
625
#define RETURN_WRITE_TYPED(alt, ptype)\
626
35.5M
  gs_param_typed_value typed;\
627
35.5M
\
628
35.5M
  typed.value.alt = *pvalue;\
629
35.5M
  typed.type = ptype;\
630
35.5M
  return param_write_typed(plist, pkey, &typed)
631
632
int
633
param_write_null(gs_param_list * plist, gs_param_name pkey)
634
957k
{
635
957k
    gs_param_typed_value typed;
636
637
957k
    typed.type = gs_param_type_null;
638
957k
    return param_write_typed(plist, pkey, &typed);
639
957k
}
640
int
641
param_write_bool(gs_param_list * plist, gs_param_name pkey, const bool * pvalue)
642
6.47M
{
643
6.47M
    RETURN_WRITE_TYPED(b, gs_param_type_bool);
644
6.47M
}
645
int
646
param_write_int(gs_param_list * plist, gs_param_name pkey, const int *pvalue)
647
8.94M
{
648
8.94M
    RETURN_WRITE_TYPED(i, gs_param_type_int);
649
8.94M
}
650
int
651
param_write_long(gs_param_list * plist, gs_param_name pkey, const long *pvalue)
652
1.55M
{
653
1.55M
    RETURN_WRITE_TYPED(l, gs_param_type_long);
654
1.55M
}
655
int
656
param_write_i64(gs_param_list * plist, gs_param_name pkey, const int64_t *pvalue)
657
63.6k
{
658
63.6k
    RETURN_WRITE_TYPED(i64, gs_param_type_i64);
659
63.6k
}
660
int
661
param_write_size_t(gs_param_list * plist, gs_param_name pkey, const size_t *pvalue)
662
1.39M
{
663
1.39M
    RETURN_WRITE_TYPED(z, gs_param_type_size_t);
664
1.39M
}
665
int
666
param_write_float(gs_param_list * plist, gs_param_name pkey,
667
                  const float *pvalue)
668
957k
{
669
957k
    RETURN_WRITE_TYPED(f, gs_param_type_float);
670
957k
}
671
int
672
param_write_string(gs_param_list * plist, gs_param_name pkey,
673
                   const gs_param_string * pvalue)
674
5.91M
{
675
5.91M
    RETURN_WRITE_TYPED(s, gs_param_type_string);
676
5.91M
}
677
int
678
param_write_name(gs_param_list * plist, gs_param_name pkey,
679
                 const gs_param_string * pvalue)
680
5.12M
{
681
5.12M
    RETURN_WRITE_TYPED(n, gs_param_type_name);
682
5.12M
}
683
int
684
param_write_int_array(gs_param_list * plist, gs_param_name pkey,
685
                      const gs_param_int_array * pvalue)
686
322k
{
687
322k
    RETURN_WRITE_TYPED(ia, gs_param_type_int_array);
688
322k
}
689
int
690
param_write_int_values(gs_param_list * plist, gs_param_name pkey,
691
                       const int *values, uint size, bool persistent)
692
2.68k
{
693
2.68k
    gs_param_int_array ia;
694
695
2.68k
    ia.data = values, ia.size = size, ia.persistent = persistent;
696
2.68k
    return param_write_int_array(plist, pkey, &ia);
697
2.68k
}
698
int
699
param_write_float_array(gs_param_list * plist, gs_param_name pkey,
700
                        const gs_param_float_array * pvalue)
701
1.65M
{
702
1.65M
    RETURN_WRITE_TYPED(fa, gs_param_type_float_array);
703
1.65M
}
704
int
705
param_write_float_values(gs_param_list * plist, gs_param_name pkey,
706
                         const float *values, uint size, bool persistent)
707
7.06k
{
708
7.06k
    gs_param_float_array fa;
709
710
7.06k
    fa.data = values, fa.size = size, fa.persistent = persistent;
711
7.06k
    return param_write_float_array(plist, pkey, &fa);
712
7.06k
}
713
int
714
param_write_string_array(gs_param_list * plist, gs_param_name pkey,
715
                         const gs_param_string_array * pvalue)
716
319k
{
717
319k
    RETURN_WRITE_TYPED(sa, gs_param_type_string_array);
718
319k
}
719
int
720
param_write_name_array(gs_param_list * plist, gs_param_name pkey,
721
                       const gs_param_string_array * pvalue)
722
2.87M
{
723
2.87M
    RETURN_WRITE_TYPED(na, gs_param_type_name_array);
724
2.87M
}
725
726
#undef RETURN_WRITE_TYPED
727
728
/* ---------------- Default request implementation ---------------- */
729
730
int
731
gs_param_request_default(gs_param_list * plist, gs_param_name pkey)
732
0
{
733
0
    return 0;
734
0
}
735
736
int
737
gs_param_requested_default(const gs_param_list * plist, gs_param_name pkey)
738
0
{
739
0
    return -1;      /* requested by default */
740
0
}