Coverage Report

Created: 2025-06-10 07:27

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