Coverage Report

Created: 2022-04-16 11:23

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