Coverage Report

Created: 2025-06-24 07:01

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