Coverage Report

Created: 2026-10-28 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gsparam.c
Line
Count
Source
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
2.48M
ENUM_PTRS_WITH(gs_param_typed_value_enum_ptrs, gs_param_typed_value *pvalue) return 0;
27
1.24M
    case 0:
28
1.24M
    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
540k
    case gs_param_type_int_array:
34
540k
        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
703k
    default:
42
703k
        return ENUM_OBJ(0);  /* don't stop early */
43
1.24M
    }
44
2.48M
ENUM_PTRS_END
45
1.24M
RELOC_PTRS_WITH(gs_param_typed_value_reloc_ptrs, gs_param_typed_value *pvalue) {
46
1.24M
    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
540k
    case gs_param_type_int_array:
58
540k
        RELOC_VAR(pvalue->value.ia.data);
59
540k
        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
703k
    default:
70
703k
        break;
71
1.24M
    }
72
1.24M
}
73
1.24M
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
23.4M
{
80
23.4M
    plist->procs = procs;
81
23.4M
    plist->memory = mem;
82
23.4M
    plist->persistent_keys = true;
83
23.4M
}
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
14.4M
{
89
14.4M
    plist->persistent_keys = persistent;
90
14.4M
}
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
4.04M
{
96
4.04M
    memset(enumerator, 0, sizeof(*enumerator));
97
4.04M
}
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
1.54M
{
108
1.54M
    const gs_param_item_t *pi;
109
1.54M
    int ecode = 0;
110
111
36.2M
    for (pi = items; pi->key != 0; ++pi) {
112
34.6M
        const char *key = pi->key;
113
34.6M
        void *pvalue = (void *)((char *)obj + pi->offset);
114
34.6M
        gs_param_typed_value typed;
115
34.6M
        int code;
116
117
34.6M
        typed.type = pi->type;
118
34.6M
        code = param_read_requested_typed(plist, key, &typed);
119
34.6M
        switch (code) {
120
0
            default:    /* < 0 */
121
0
                ecode = code;
122
30.8M
            case 1:
123
30.8M
                break;
124
3.82M
            case 0:
125
3.82M
                if (typed.type != pi->type)  /* shouldn't happen! */
126
0
                    ecode = gs_note_error(gs_error_typecheck);
127
3.82M
                else {
128
3.82M
                    switch(typed.type)
129
3.82M
                    {
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
96.2k
                    case gs_param_type_string:
135
96.2k
                    case gs_param_type_name:
136
96.2k
                    {
137
96.2k
                        void *copy;
138
96.2k
                        gs_string *s;
139
96.2k
                        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
96.2k
                        s = ((gs_string *)pvalue);
148
96.2k
                        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
96.2k
                        } else {
157
96.2k
                            copy = s->data;
158
96.2k
                        }
159
96.2k
                        if (typed.value.s.size > 0)
160
0
                            memcpy(copy, typed.value.s.data, typed.value.s.size);
161
96.2k
                        s->data = copy;
162
96.2k
                        ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */
163
96.2k
                        break;
164
96.2k
                    }
165
0
                    case gs_param_type_int_array:
166
103k
                    case gs_param_type_float_array:
167
103k
                    case gs_param_type_string_array:
168
103k
                    case gs_param_type_name_array:
169
103k
                    {
170
103k
                        int eltsize;
171
103k
                        gs_param_string_array *sa;
172
103k
                        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
103k
                        eltsize = gs_param_type_base_sizes[typed.type];
181
103k
                        sa = ((gs_param_string_array *)pvalue);
182
103k
                        if (typed.value.ia.size != sa->size) {
183
65.0k
                            void *copy;
184
65.0k
                            if (typed.type == gs_param_type_name_array ||
185
65.0k
                                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
65.0k
                            gs_free_const_object(mem, sa->data, "gs_param_read_items");
202
65.0k
                            sa->data = NULL;
203
65.0k
                            sa->size = 0;
204
65.0k
                            copy = gs_alloc_bytes(mem, eltsize * typed.value.s.size, "gs_param_read_items");
205
65.0k
                            if (copy == NULL)
206
0
                                return_error(gs_error_VMerror);
207
65.0k
                            memset(copy, 0, eltsize * typed.value.s.size);
208
65.0k
                            sa->size = typed.value.s.size;
209
65.0k
                            sa->data = copy;
210
65.0k
                        }
211
                        /* Now copy the elements of the arrays. */
212
103k
                        if (typed.type == gs_param_type_name_array ||
213
103k
                            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
103k
                        } else {
238
                            /* Hideous hackery to get around the const nature of gs_param_strings. */
239
103k
                            gs_string *s = (gs_string *)(void *)sa;
240
103k
                            if (typed.value.s.size > 0)
241
103k
                                memcpy(s->data, typed.value.s.data, eltsize * typed.value.s.size);
242
103k
                        }
243
103k
                        ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */
244
103k
                        break;
245
103k
                    }
246
3.63M
                    default:
247
3.63M
    copy_pointer:
248
3.63M
                        memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]);
249
3.82M
                    }
250
3.82M
                }
251
34.6M
        }
252
34.6M
    }
253
1.54M
    return ecode;
254
1.54M
}
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
4.45M
{
259
4.45M
    const gs_param_item_t *pi;
260
4.45M
    int ecode = 0;
261
262
103M
    for (pi = items; pi->key != 0; ++pi) {
263
99.5M
        const char *key = pi->key;
264
99.5M
        const void *pvalue = (const void *)((const char *)obj + pi->offset);
265
99.5M
        int size = xfer_item_sizes[pi->type];
266
99.5M
        gs_param_typed_value typed;
267
99.5M
        int code;
268
269
99.5M
        if (default_obj != 0 &&
270
1.28M
            !memcmp((const void *)((const char *)default_obj + pi->offset),
271
1.28M
                    pvalue, size)
272
99.5M
            )
273
976k
            continue;
274
98.5M
        if (size > 0)
275
98.5M
            memcpy(&typed.value, pvalue, size);
276
98.5M
        typed.type = pi->type;
277
        /* Ensure the list doesn't end up keeping a pointer to our values. */
278
98.5M
        typed.value.s.persistent = 0;
279
98.5M
        code = (*plist->procs->xmit_typed) (plist, key, &typed);
280
98.5M
        if (code < 0)
281
0
            ecode = code;
282
98.5M
    }
283
4.45M
    return ecode;
284
4.45M
}
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
71.2M
{
292
71.2M
    if (req_type == gs_param_type_any || pvalue->type == req_type)
293
49.4M
        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
21.7M
    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
19.6M
        case gs_param_type_i64:
378
19.6M
            switch (req_type) {
379
1.38M
                case gs_param_type_size_t:
380
1.38M
                {
381
1.38M
                    size_t z = (size_t)pvalue->value.i64;
382
1.38M
                    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
1.38M
                        )
387
0
                        return_error(gs_error_rangecheck);
388
1.38M
                    pvalue->value.z = z;
389
1.38M
                    goto ok;
390
1.38M
                }
391
13.3M
                case gs_param_type_long:
392
13.3M
                {
393
13.3M
                    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
13.3M
                    pvalue->value.l = l;
399
13.3M
                    goto ok;
400
1.38M
                }
401
4.94M
                case gs_param_type_int:
402
4.94M
                {
403
4.94M
                    int int1 = (int)pvalue->value.i64;
404
4.94M
#if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */
405
4.94M
                    if (pvalue->value.i64 != (int64_t)int1)
406
0
                        return_error(gs_error_rangecheck);
407
4.94M
#endif
408
4.94M
                    pvalue->value.i = int1;
409
4.94M
                    goto ok;
410
4.94M
                }
411
12.1k
                case gs_param_type_float:
412
12.1k
                {
413
12.1k
                    float fl = (float)pvalue->value.i64;
414
12.1k
                    pvalue->value.f = fl;
415
12.1k
                    goto ok;
416
4.94M
                }
417
0
                default:
418
0
                    break;
419
19.6M
            }
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
1
        case gs_param_type_string:
467
1
            if (req_type == gs_param_type_name)
468
0
                goto ok;
469
1
            break;
470
874k
        case gs_param_type_name:
471
874k
            if (req_type == gs_param_type_string)
472
874k
                goto ok;
473
2
            break;
474
80.4k
        case gs_param_type_int_array:
475
80.4k
            switch (req_type) {
476
65.0k
                case gs_param_type_float_array:{
477
65.0k
                        uint size = pvalue->value.ia.size;
478
65.0k
                        float *fv;
479
65.0k
                        uint i;
480
481
65.0k
                        if (mem == 0)
482
0
                            break;
483
65.0k
                        fv = (float *)gs_alloc_byte_array(mem, size, sizeof(float),
484
65.0k
                                                "int array => float array");
485
486
65.0k
                        if (fv == 0)
487
0
                            return_error(gs_error_VMerror);
488
325k
                        for (i = 0; i < size; ++i)
489
260k
                            fv[i] = (float)pvalue->value.ia.data[i];
490
65.0k
                        pvalue->value.fa.data = fv;
491
65.0k
                        pvalue->value.fa.persistent = false;
492
65.0k
                        goto ok;
493
65.0k
                    }
494
15.3k
                default:
495
15.3k
                    break;
496
80.4k
            }
497
15.3k
            break;
498
15.3k
        case gs_param_type_string_array:
499
0
            if (req_type == gs_param_type_name_array)
500
0
                goto ok;
501
0
            break;
502
19.8k
        case gs_param_type_name_array:
503
19.8k
            if (req_type == gs_param_type_string_array)
504
19.8k
                goto ok;
505
0
            break;
506
962k
        case gs_param_type_array:
507
962k
            if (pvalue->value.d.size == 0 &&
508
962k
                (req_type == gs_param_type_int_array ||
509
962k
                 req_type == gs_param_type_float_array ||
510
962k
                 req_type == gs_param_type_string_array ||
511
962k
                 req_type == gs_param_type_name_array)
512
962k
                )
513
962k
                goto ok;
514
0
            break;
515
180k
        default:
516
180k
            break;
517
21.7M
    }
518
21.7M
    return_error(gs_error_typecheck);
519
21.5M
  ok:pvalue->type = req_type;
520
21.5M
    return 0;
521
21.7M
}
522
int
523
param_read_requested_typed(gs_param_list * plist, gs_param_name pkey,
524
                           gs_param_typed_value * pvalue)
525
389M
{
526
389M
    gs_param_type req_type = pvalue->type;
527
389M
    int code = (*plist->procs->xmit_typed) (plist, pkey, pvalue);
528
529
389M
    if (code != 0)
530
332M
        return code;
531
57.1M
    return param_coerce_typed(pvalue, req_type, plist->memory);
532
389M
}
533
534
/* ---------------- Fixed-type reading procedures ---------------- */
535
536
#define RETURN_READ_TYPED(alt, ptype)\
537
339M
  gs_param_typed_value typed;\
538
339M
  int code;\
539
339M
\
540
339M
  typed.type = ptype;\
541
339M
  code = param_read_requested_typed(plist, pkey, &typed);\
542
339M
  if ( code == 0 )\
543
339M
    *pvalue = typed.value.alt;\
544
339M
  return code
545
546
int
547
param_read_null(gs_param_list * plist, gs_param_name pkey)
548
180k
{
549
180k
    gs_param_typed_value typed;
550
551
180k
    typed.type = gs_param_type_null;
552
180k
    return param_read_requested_typed(plist, pkey, &typed);
553
180k
}
554
int
555
param_read_bool(gs_param_list * plist, gs_param_name pkey, bool * pvalue)
556
60.9M
{
557
60.9M
    RETURN_READ_TYPED(b, gs_param_type_bool);
558
60.9M
}
559
int
560
param_read_int(gs_param_list * plist, gs_param_name pkey, int *pvalue)
561
64.1M
{
562
64.1M
    RETURN_READ_TYPED(i, gs_param_type_int);
563
64.1M
}
564
int
565
param_read_long(gs_param_list * plist, gs_param_name pkey, long *pvalue)
566
82.6M
{
567
82.6M
    RETURN_READ_TYPED(l, gs_param_type_long);
568
82.6M
}
569
int
570
param_read_i64(gs_param_list * plist, gs_param_name pkey, int64_t *pvalue)
571
3.93M
{
572
3.93M
    RETURN_READ_TYPED(i64, gs_param_type_i64);
573
3.93M
}
574
int
575
param_read_size_t(gs_param_list * plist, gs_param_name pkey, size_t *pvalue)
576
11.8M
{
577
11.8M
    RETURN_READ_TYPED(z, gs_param_type_size_t);
578
11.8M
}
579
int
580
param_read_float(gs_param_list * plist, gs_param_name pkey, float *pvalue)
581
9.37M
{
582
9.37M
    RETURN_READ_TYPED(f, gs_param_type_float);
583
9.37M
}
584
int
585
param_read_string(gs_param_list * plist, gs_param_name pkey,
586
                  gs_param_string * pvalue)
587
79.4M
{
588
79.4M
    RETURN_READ_TYPED(s, gs_param_type_string);
589
79.4M
}
590
int
591
param_read_name(gs_param_list * plist, gs_param_name pkey,
592
                gs_param_string * pvalue)
593
5.56M
{
594
5.56M
    RETURN_READ_TYPED(n, gs_param_type_string);
595
5.56M
}
596
int
597
param_read_int_array(gs_param_list * plist, gs_param_name pkey,
598
                     gs_param_int_array * pvalue)
599
2.12M
{
600
2.12M
    RETURN_READ_TYPED(ia, gs_param_type_int_array);
601
2.12M
}
602
int
603
param_read_float_array(gs_param_list * plist, gs_param_name pkey,
604
                       gs_param_float_array * pvalue)
605
12.9M
{
606
12.9M
    RETURN_READ_TYPED(fa, gs_param_type_float_array);
607
12.9M
}
608
int
609
param_read_string_array(gs_param_list * plist, gs_param_name pkey,
610
                        gs_param_string_array * pvalue)
611
734k
{
612
734k
    RETURN_READ_TYPED(sa, gs_param_type_string_array);
613
734k
}
614
int
615
param_read_name_array(gs_param_list * plist, gs_param_name pkey,
616
                      gs_param_string_array * pvalue)
617
6.03M
{
618
6.03M
    RETURN_READ_TYPED(na, gs_param_type_name_array);
619
6.03M
}
620
621
#undef RETURN_READ_TYPED
622
623
/* ---------------- Default writing procedures ---------------- */
624
625
#define RETURN_WRITE_TYPED(alt, ptype)\
626
485M
  gs_param_typed_value typed;\
627
485M
\
628
485M
  typed.value.alt = *pvalue;\
629
485M
  typed.type = ptype;\
630
485M
  return param_write_typed(plist, pkey, &typed)
631
632
int
633
param_write_null(gs_param_list * plist, gs_param_name pkey)
634
10.4M
{
635
10.4M
    gs_param_typed_value typed;
636
637
10.4M
    typed.type = gs_param_type_null;
638
10.4M
    return param_write_typed(plist, pkey, &typed);
639
10.4M
}
640
int
641
param_write_bool(gs_param_list * plist, gs_param_name pkey, const bool * pvalue)
642
88.6M
{
643
88.6M
    RETURN_WRITE_TYPED(b, gs_param_type_bool);
644
88.6M
}
645
int
646
param_write_int(gs_param_list * plist, gs_param_name pkey, const int *pvalue)
647
121M
{
648
121M
    RETURN_WRITE_TYPED(i, gs_param_type_int);
649
121M
}
650
int
651
param_write_long(gs_param_list * plist, gs_param_name pkey, const long *pvalue)
652
76.4M
{
653
76.4M
    RETURN_WRITE_TYPED(l, gs_param_type_long);
654
76.4M
}
655
int
656
param_write_i64(gs_param_list * plist, gs_param_name pkey, const int64_t *pvalue)
657
324k
{
658
324k
    RETURN_WRITE_TYPED(i64, gs_param_type_i64);
659
324k
}
660
int
661
param_write_size_t(gs_param_list * plist, gs_param_name pkey, const size_t *pvalue)
662
17.0M
{
663
17.0M
    RETURN_WRITE_TYPED(z, gs_param_type_size_t);
664
17.0M
}
665
int
666
param_write_float(gs_param_list * plist, gs_param_name pkey,
667
                  const float *pvalue)
668
21.2M
{
669
21.2M
    RETURN_WRITE_TYPED(f, gs_param_type_float);
670
21.2M
}
671
int
672
param_write_string(gs_param_list * plist, gs_param_name pkey,
673
                   const gs_param_string * pvalue)
674
103M
{
675
103M
    RETURN_WRITE_TYPED(s, gs_param_type_string);
676
103M
}
677
int
678
param_write_name(gs_param_list * plist, gs_param_name pkey,
679
                 const gs_param_string * pvalue)
680
23.2M
{
681
23.2M
    RETURN_WRITE_TYPED(n, gs_param_type_name);
682
23.2M
}
683
int
684
param_write_int_array(gs_param_list * plist, gs_param_name pkey,
685
                      const gs_param_int_array * pvalue)
686
3.75M
{
687
3.75M
    RETURN_WRITE_TYPED(ia, gs_param_type_int_array);
688
3.75M
}
689
int
690
param_write_int_values(gs_param_list * plist, gs_param_name pkey,
691
                       const int *values, uint size, bool persistent)
692
10.7k
{
693
10.7k
    gs_param_int_array ia;
694
695
10.7k
    ia.data = values, ia.size = size, ia.persistent = persistent;
696
10.7k
    return param_write_int_array(plist, pkey, &ia);
697
10.7k
}
698
int
699
param_write_float_array(gs_param_list * plist, gs_param_name pkey,
700
                        const gs_param_float_array * pvalue)
701
18.1M
{
702
18.1M
    RETURN_WRITE_TYPED(fa, gs_param_type_float_array);
703
18.1M
}
704
int
705
param_write_float_values(gs_param_list * plist, gs_param_name pkey,
706
                         const float *values, uint size, bool persistent)
707
37.2k
{
708
37.2k
    gs_param_float_array fa;
709
710
37.2k
    fa.data = values, fa.size = size, fa.persistent = persistent;
711
37.2k
    return param_write_float_array(plist, pkey, &fa);
712
37.2k
}
713
int
714
param_write_string_array(gs_param_list * plist, gs_param_name pkey,
715
                         const gs_param_string_array * pvalue)
716
898k
{
717
898k
    RETURN_WRITE_TYPED(sa, gs_param_type_string_array);
718
898k
}
719
int
720
param_write_name_array(gs_param_list * plist, gs_param_name pkey,
721
                       const gs_param_string_array * pvalue)
722
10.8M
{
723
10.8M
    RETURN_WRITE_TYPED(na, gs_param_type_name_array);
724
10.8M
}
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
}