Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/psi/iapi.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
18
/* Public Application Programming Interface to Ghostscript interpreter */
19
20
#include "string_.h"
21
#include "ierrors.h"
22
#include "gscdefs.h"
23
#include "gstypes.h"
24
#include "gdebug.h"
25
#include "iapi.h" /* Public API */
26
#include "psapi.h"
27
#include "iref.h"
28
#include "iminst.h"
29
#include "imain.h"
30
#include "imainarg.h"
31
#include "gsmemory.h"
32
#include "gsmalloc.h"
33
#include "gslibctx.h"
34
#include "gp.h"
35
#include "gsargs.h"
36
#include "gdevdsp.h"
37
#include "gsstate.h"
38
#include "icstate.h"
39
40
typedef struct { int a[(int)GS_ARG_ENCODING_LOCAL   == (int)PS_ARG_ENCODING_LOCAL   ? 1 : -1]; } compile_time_assert_0;
41
typedef struct { int a[(int)GS_ARG_ENCODING_UTF8    == (int)PS_ARG_ENCODING_UTF8    ? 1 : -1]; } compile_time_assert_1;
42
typedef struct { int a[(int)GS_ARG_ENCODING_UTF16LE == (int)PS_ARG_ENCODING_UTF16LE ? 1 : -1]; } compile_time_assert_2;
43
44
/* Return revision numbers and strings of Ghostscript. */
45
/* Used for determining if wrong GSDLL loaded. */
46
/* This may be called before any other function. */
47
GSDLLEXPORT int GSDLLAPI
48
gsapi_revision(gsapi_revision_t *pr, int rvsize)
49
0
{
50
0
    if (rvsize < sizeof(gsapi_revision_t))
51
0
        return sizeof(gsapi_revision_t);
52
0
    pr->product = gs_product;
53
0
    pr->copyright = gs_copyright;
54
0
    pr->revision = gs_revision;
55
0
    pr->revisiondate = gs_revisiondate;
56
0
    return 0;
57
0
}
58
59
/* Create a new instance of Ghostscript.
60
 * First instance per process call with *pinstance == NULL
61
 * next instance in a proces call with *pinstance == copy of valid_instance pointer
62
 * *pinstance is set to a new instance pointer.
63
 */
64
GSDLLEXPORT int GSDLLAPI
65
gsapi_new_instance(void **pinstance, void *caller_handle)
66
162k
{
67
162k
    return psapi_new_instance((gs_lib_ctx_t **)pinstance, caller_handle);
68
162k
}
69
70
/* Destroy an instance of Ghostscript */
71
/* We do not support multiple instances, so make sure
72
 * we use the default instance only once.
73
 */
74
GSDLLEXPORT void GSDLLAPI
75
gsapi_delete_instance(void *instance)
76
162k
{
77
162k
    if (instance == NULL)
78
0
        return;
79
162k
    gp_set_debug_mem_ptr(((gs_lib_ctx_t *)instance)->memory);
80
162k
    psapi_delete_instance(instance);
81
162k
}
82
83
/* Set the callback functions for stdio */
84
GSDLLEXPORT int GSDLLAPI
85
gsapi_set_stdio(void *instance,
86
    int(GSDLLCALL *stdin_fn)(void *caller_handle, char *buf, int len),
87
    int(GSDLLCALL *stdout_fn)(void *caller_handle, const char *str, int len),
88
    int(GSDLLCALL *stderr_fn)(void *caller_handle, const char *str, int len))
89
162k
{
90
162k
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
91
162k
    if (instance == NULL)
92
0
        return gs_error_Fatal;
93
162k
    return gsapi_set_stdio_with_handle(instance,
94
162k
                                       stdin_fn, stdout_fn, stderr_fn,
95
162k
                                       ctx->core->default_caller_handle);
96
162k
}
97
98
GSDLLEXPORT int GSDLLAPI
99
gsapi_set_stdio_with_handle(void *instance,
100
    int(GSDLLCALL *stdin_fn)(void *caller_handle, char *buf, int len),
101
    int(GSDLLCALL *stdout_fn)(void *caller_handle, const char *str, int len),
102
    int(GSDLLCALL *stderr_fn)(void *caller_handle, const char *str, int len),
103
    void *caller_handle)
104
162k
{
105
162k
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
106
162k
    if (instance == NULL)
107
0
        return gs_error_Fatal;
108
162k
    ctx->core->stdin_fn = stdin_fn;
109
162k
    ctx->core->stdout_fn = stdout_fn;
110
162k
    ctx->core->stderr_fn = stderr_fn;
111
162k
    ctx->core->std_caller_handle = caller_handle;
112
162k
    return 0;
113
162k
}
114
115
/* Set the callback function for polling */
116
GSDLLEXPORT int GSDLLAPI
117
gsapi_set_poll(void *instance,
118
    int(GSDLLCALL *poll_fn)(void *caller_handle))
119
0
{
120
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
121
0
    if (instance == NULL)
122
0
        return gs_error_Fatal;
123
0
    return gsapi_set_poll_with_handle(instance, poll_fn,
124
0
                                      ctx->core->default_caller_handle);
125
0
}
126
127
GSDLLEXPORT int GSDLLAPI
128
gsapi_set_poll_with_handle(void *instance,
129
    int(GSDLLCALL *poll_fn)(void *caller_handle),
130
    void *caller_handle)
131
0
{
132
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
133
0
    if (instance == NULL)
134
0
        return gs_error_Fatal;
135
0
    ctx->core->poll_fn = poll_fn;
136
0
    ctx->core->poll_caller_handle = caller_handle;
137
0
    return 0;
138
0
}
139
140
static int
141
legacy_display_callout(void *instance,
142
                       void *handle,
143
                       const char *dev_name,
144
                       int id,
145
                       int size,
146
                       void *data)
147
0
{
148
0
    gs_main_instance *inst = (gs_main_instance *)instance;
149
150
0
    if (dev_name == NULL)
151
0
        return -1;
152
0
    if (strcmp(dev_name, "display") != 0)
153
0
        return -1;
154
155
0
    if (id == DISPLAY_CALLOUT_GET_CALLBACK_LEGACY) {
156
        /* get display callbacks */
157
0
        gs_display_get_callback_t *cb = (gs_display_get_callback_t *)data;
158
0
        cb->callback = inst->display;
159
0
        return 0;
160
0
    }
161
0
    return -1;
162
0
}
163
164
/* Set the display callback structure */
165
GSDLLEXPORT int GSDLLAPI
166
gsapi_set_display_callback(void *instance, display_callback *callback)
167
0
{
168
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
169
0
    gs_main_instance *minst;
170
0
    int code;
171
0
    if (instance == NULL)
172
0
        return gs_error_Fatal;
173
0
    gp_set_debug_mem_ptr(ctx->memory);
174
0
    minst = get_minst_from_memory(ctx->memory);
175
0
    if (minst->display == NULL && callback != NULL) {
176
        /* First registration. */
177
0
        code = gs_lib_ctx_register_callout(minst->heap,
178
0
                                           legacy_display_callout,
179
0
                                           minst);
180
0
        if (code < 0)
181
0
            return code;
182
0
    }
183
0
    if (minst->display != NULL && callback == NULL) {
184
        /* Deregistered. */
185
0
        gs_lib_ctx_deregister_callout(minst->heap,
186
0
                                      legacy_display_callout,
187
0
                                      minst);
188
0
    }
189
0
    minst->display = callback;
190
    /* not in a language switched build */
191
0
    return 0;
192
0
}
193
194
GSDLLEXPORT int GSDLLAPI
195
gsapi_register_callout(void *instance, gs_callout fn, void *handle)
196
0
{
197
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
198
0
    if (instance == NULL)
199
0
        return gs_error_Fatal;
200
0
    gp_set_debug_mem_ptr(ctx->memory);
201
0
    return gs_lib_ctx_register_callout(ctx->memory, fn, handle);
202
0
}
203
204
GSDLLEXPORT void GSDLLAPI
205
gsapi_deregister_callout(void *instance, gs_callout fn, void *handle)
206
0
{
207
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
208
0
    if (instance == NULL)
209
0
        return;
210
0
    gp_set_debug_mem_ptr(ctx->memory);
211
0
    gs_lib_ctx_deregister_callout(ctx->memory, fn, handle);
212
0
}
213
214
/* Set/Get the default device list string */
215
GSDLLEXPORT int GSDLLAPI
216
gsapi_set_default_device_list(void *instance, const char *list, int listlen)
217
0
{
218
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
219
0
    if (instance == NULL)
220
0
        return gs_error_Fatal;
221
0
    gp_set_debug_mem_ptr(ctx->memory);
222
0
    return gs_lib_ctx_set_default_device_list(ctx->memory, list, listlen);
223
0
}
224
225
GSDLLEXPORT int GSDLLAPI
226
gsapi_get_default_device_list(void *instance, char **list, int *listlen)
227
0
{
228
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
229
0
    if (instance == NULL)
230
0
        return gs_error_Fatal;
231
0
    gp_set_debug_mem_ptr(ctx->memory);
232
0
    return gs_lib_ctx_get_default_device_list(ctx->memory, list, listlen);
233
0
}
234
235
/* Initialise the interpreter */
236
GSDLLEXPORT int GSDLLAPI
237
gsapi_set_arg_encoding(void *instance, int encoding)
238
162k
{
239
162k
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
240
162k
    if (instance == NULL)
241
0
        return gs_error_Fatal;
242
162k
    gp_set_debug_mem_ptr(ctx->memory);
243
162k
    return psapi_set_arg_encoding(ctx, encoding);
244
162k
}
245
246
GSDLLEXPORT int GSDLLAPI
247
gsapi_init_with_args(void *instance, int argc, char **argv)
248
162k
{
249
162k
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
250
162k
    if (instance == NULL)
251
0
        return gs_error_Fatal;
252
162k
    gp_set_debug_mem_ptr(ctx->memory);
253
162k
    return psapi_init_with_args(ctx, argc, argv);
254
162k
}
255
256
/* The gsapi_run_* functions are like gs_main_run_* except
257
 * that the error_object is omitted.
258
 * An error object in minst is used instead.
259
 */
260
261
/* Setup up a suspendable run_string */
262
GSDLLEXPORT int GSDLLAPI
263
gsapi_run_string_begin(void *instance,
264
                       int   user_errors,
265
                       int  *pexit_code)
266
0
{
267
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
268
0
    if (instance == NULL)
269
0
        return gs_error_Fatal;
270
0
    gp_set_debug_mem_ptr(ctx->memory);
271
0
    return psapi_run_string_begin(ctx, user_errors, pexit_code);
272
0
}
273
274
GSDLLEXPORT int GSDLLAPI
275
gsapi_run_string_continue(void         *instance,
276
                          const char   *str,
277
                          unsigned int  length,
278
                          int           user_errors,
279
                          int          *pexit_code)
280
0
{
281
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
282
0
    if (instance == NULL)
283
0
        return gs_error_Fatal;
284
0
    gp_set_debug_mem_ptr(ctx->memory);
285
0
    return psapi_run_string_continue(ctx, str, length, user_errors, pexit_code);
286
0
}
287
288
GSDLLEXPORT int GSDLLAPI
289
gsapi_run_string_end(void *instance,
290
                     int   user_errors,
291
                     int  *pexit_code)
292
0
{
293
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
294
0
    if (instance == NULL)
295
0
        return gs_error_Fatal;
296
0
    gp_set_debug_mem_ptr(ctx->memory);
297
0
    return psapi_run_string_end(ctx, user_errors, pexit_code);
298
0
}
299
300
GSDLLEXPORT int GSDLLAPI
301
gsapi_run_string_with_length(void         *instance,
302
                             const char   *str,
303
                             unsigned int  length,
304
                             int           user_errors,
305
                             int          *pexit_code)
306
0
{
307
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
308
0
    if (instance == NULL)
309
0
        return gs_error_Fatal;
310
0
    gp_set_debug_mem_ptr(ctx->memory);
311
0
    return psapi_run_string_with_length(ctx, str, length, user_errors, pexit_code);
312
0
}
313
314
GSDLLEXPORT int GSDLLAPI
315
gsapi_run_string(void       *instance,
316
                 const char *str,
317
                 int         user_errors,
318
                 int        *pexit_code)
319
0
{
320
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
321
0
    if (instance == NULL)
322
0
        return gs_error_Fatal;
323
0
    gp_set_debug_mem_ptr(ctx->memory);
324
0
    return psapi_run_string_with_length(ctx,
325
0
                                        str,
326
0
                                        (unsigned int)strlen(str),
327
0
                                        user_errors,
328
0
                                        pexit_code);
329
0
}
330
331
GSDLLEXPORT int GSDLLAPI
332
gsapi_run_file(void       *instance,
333
               const char *file_name,
334
               int         user_errors,
335
               int        *pexit_code)
336
0
{
337
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
338
0
    if (instance == NULL)
339
0
        return gs_error_Fatal;
340
0
    gp_set_debug_mem_ptr(ctx->memory);
341
0
    return psapi_run_file(ctx, file_name, user_errors, pexit_code);
342
0
}
343
344
#ifdef __WIN32__
345
GSDLLEXPORT int GSDLLAPI
346
gsapi_init_with_argsW(void     *instance,
347
                      int       argc,
348
                      wchar_t **argv)
349
{
350
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
351
    int code;
352
    gs_arg_get_codepoint *old;
353
    if (instance == NULL)
354
        return gs_error_Fatal;
355
356
    gp_set_debug_mem_ptr(ctx->memory);
357
    old = gs_main_inst_get_arg_decode(get_minst_from_memory(ctx->memory));
358
    code = psapi_set_arg_encoding(ctx, PS_ARG_ENCODING_UTF16LE);
359
    if (code != 0)
360
        return code;
361
    code = psapi_init_with_args(ctx, 2*argc, (char **)argv);
362
    gs_main_inst_arg_decode(get_minst_from_memory(ctx->memory), old);
363
    return code;
364
}
365
366
GSDLLEXPORT int GSDLLAPI
367
gsapi_init_with_argsA(void  *instance,
368
                      int    argc,
369
                      char **argv)
370
{
371
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
372
    int code;
373
    gs_arg_get_codepoint *old;
374
    if (instance == NULL)
375
        return gs_error_Fatal;
376
377
    gp_set_debug_mem_ptr(ctx->memory);
378
    old = gs_main_inst_get_arg_decode(get_minst_from_memory(ctx->memory));
379
    code = psapi_set_arg_encoding(ctx, PS_ARG_ENCODING_LOCAL);
380
    if (code != 0)
381
        return code;
382
    code = psapi_init_with_args(ctx, 2*argc, (char **)argv);
383
    gs_main_inst_arg_decode(get_minst_from_memory(ctx->memory), old);
384
    return code;
385
}
386
387
GSDLLEXPORT int GSDLLAPI
388
gsapi_run_fileW(void          *instance,
389
                const wchar_t *file_name,
390
                int            user_errors,
391
                int           *pexit_code)
392
{
393
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
394
    int code;
395
    gs_arg_get_codepoint *old;
396
    if (instance == NULL)
397
        return gs_error_Fatal;
398
399
    gp_set_debug_mem_ptr(ctx->memory);
400
    old = gs_main_inst_get_arg_decode(get_minst_from_memory(ctx->memory));
401
    code = psapi_set_arg_encoding(ctx, PS_ARG_ENCODING_UTF16LE);
402
    if (code != 0)
403
        return code;
404
    code = psapi_run_file(ctx, (const char *)file_name, user_errors, pexit_code);
405
    gs_main_inst_arg_decode(get_minst_from_memory(ctx->memory), old);
406
    return code;
407
}
408
409
GSDLLEXPORT int GSDLLAPI
410
gsapi_run_fileA(void       *instance,
411
                const char *file_name,
412
                int         user_errors,
413
                int        *pexit_code)
414
{
415
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
416
    int code;
417
    gs_arg_get_codepoint *old;
418
    if (instance == NULL)
419
        return gs_error_Fatal;
420
421
    gp_set_debug_mem_ptr(ctx->memory);
422
    old = gs_main_inst_get_arg_decode(get_minst_from_memory(ctx->memory));
423
    code = psapi_set_arg_encoding(ctx, PS_ARG_ENCODING_LOCAL);
424
    if (code != 0)
425
        return code;
426
    code = psapi_run_file(ctx, (const char *)file_name, user_errors, pexit_code);
427
    gs_main_inst_arg_decode(get_minst_from_memory(ctx->memory), old);
428
    return code;
429
}
430
#endif
431
432
/* Exit the interpreter */
433
GSDLLEXPORT int GSDLLAPI
434
gsapi_exit(void *instance)
435
162k
{
436
162k
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
437
162k
    if (instance == NULL)
438
0
        return gs_error_Fatal;
439
162k
    gp_set_debug_mem_ptr(ctx->memory);
440
162k
    return psapi_exit(ctx);
441
162k
}
442
443
GSDLLEXPORT int GSDLLAPI
444
gsapi_set_param(void *lib, const char *param, const void *value, gs_set_param_type type)
445
0
{
446
0
    int code = 0;
447
0
    gs_param_string str_value;
448
0
    bool bval;
449
0
    int more_to_come = type & gs_spt_more_to_come;
450
0
    gs_main_instance *minst;
451
0
    gs_c_param_list *params;
452
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)lib;
453
454
0
    if (lib == NULL)
455
0
        return gs_error_Fatal;
456
0
    gp_set_debug_mem_ptr(ctx->memory);
457
0
    minst = get_minst_from_memory(ctx->memory);
458
459
    /* First off, ensure we have a param list to work with. */
460
0
    params = minst->param_list;
461
0
    if (params == NULL) {
462
0
        params = minst->param_list =
463
0
                   gs_c_param_list_alloc(minst->heap, "gs_main_instance_param_list");
464
0
        if (params == NULL)
465
0
            return_error(gs_error_VMerror);
466
0
        gs_c_param_list_write(params, minst->heap);
467
0
        gs_param_list_set_persistent_keys((gs_param_list *)params, false);
468
0
    }
469
470
0
    type &= ~gs_spt_more_to_come;
471
472
    /* Set the passed param in the device params */
473
0
    gs_c_param_list_write_more(params);
474
0
    switch (type)
475
0
    {
476
0
    case gs_spt_null:
477
0
        code = param_write_null((gs_param_list *) params,
478
0
                                param);
479
0
        break;
480
0
    case gs_spt_bool:
481
0
        bval = !!*(int *)value;
482
0
        code = param_write_bool((gs_param_list *) params,
483
0
                                param, &bval);
484
0
        break;
485
0
    case gs_spt_int:
486
0
        code = param_write_int((gs_param_list *) params,
487
0
                               param, (int *)value);
488
0
        break;
489
0
    case gs_spt_float:
490
0
        code = param_write_float((gs_param_list *) params,
491
0
                                 param, (float *)value);
492
0
        break;
493
0
    case gs_spt_name:
494
0
        param_string_from_transient_string(str_value, value);
495
0
        code = param_write_name((gs_param_list *) params,
496
0
                                param, &str_value);
497
0
        break;
498
0
    case gs_spt_string:
499
0
        param_string_from_transient_string(str_value, value);
500
0
        code = param_write_string((gs_param_list *) params,
501
0
                                  param, &str_value);
502
0
        break;
503
0
    case gs_spt_long:
504
0
        code = param_write_long((gs_param_list *) params,
505
0
                                param, (long *)value);
506
0
        break;
507
0
    case gs_spt_i64:
508
0
        code = param_write_i64((gs_param_list *) params,
509
0
                               param, (int64_t *)value);
510
0
        break;
511
0
    case gs_spt_size_t:
512
0
        code = param_write_size_t((gs_param_list *) params,
513
0
                                  param, (size_t *)value);
514
0
        break;
515
0
    case gs_spt_parsed:
516
0
        code = gs_param_list_add_parsed_value((gs_param_list *)params,
517
0
                                              param, (void *)value);
518
0
        break;
519
0
    default:
520
0
        code = gs_note_error(gs_error_rangecheck);
521
0
    }
522
0
    if (code < 0) {
523
0
        gs_c_param_list_release(params);
524
0
        return code;
525
0
    }
526
0
    gs_c_param_list_read(params);
527
528
0
    if (more_to_come || minst->i_ctx_p == NULL) {
529
        /* Leave it in the param list for later. */
530
0
        return 0;
531
0
    }
532
533
    /* Send it to the device. */
534
0
    code = psapi_set_device_param(ctx, (gs_param_list *)params);
535
0
    if (code < 0)
536
0
        return code;
537
538
0
    code = psapi_set_param(ctx, (gs_param_list *)params);
539
0
    if (code < 0)
540
0
        return code;
541
542
    /* Trigger an initgraphics */
543
0
    code = gs_initgraphics(minst->i_ctx_p->pgs);
544
545
0
    gs_c_param_list_release(params);
546
547
0
    return code;
548
0
}
549
550
GSDLLEXPORT int GSDLLAPI
551
gsapi_get_param(void *lib, const char *param, void *value, gs_set_param_type type)
552
0
{
553
0
    int code = 0;
554
0
    gs_param_string str_value;
555
0
    gs_c_param_list params;
556
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)lib;
557
558
0
    if (lib == NULL)
559
0
        return gs_error_Fatal;
560
561
0
    gp_set_debug_mem_ptr(ctx->memory);
562
0
    gs_c_param_list_write(&params, ctx->memory);
563
564
    /* Should never be set, but clear the more to come bit anyway in case. */
565
0
    type &= ~gs_spt_more_to_come;
566
567
0
    code = psapi_get_device_params(ctx, (gs_param_list *)&params);
568
0
    if (code < 0) {
569
0
        gs_c_param_list_release(&params);
570
0
        return code;
571
0
    }
572
573
0
    gs_c_param_list_read(&params);
574
0
    switch (type)
575
0
    {
576
0
    case gs_spt_null:
577
0
        code = param_read_null((gs_param_list *)&params, param);
578
0
        if (code == 1)
579
0
            code = gs_error_undefined;
580
0
        if (code < 0)
581
0
            break;
582
0
        code = 0;
583
0
        break;
584
0
    case gs_spt_bool:
585
0
    {
586
0
        bool b;
587
0
        code = param_read_bool((gs_param_list *)&params, param, &b);
588
0
        if (code == 1)
589
0
            code = gs_error_undefined;
590
0
        if (code < 0)
591
0
            break;
592
0
        code = sizeof(int);
593
0
        if (value != NULL)
594
0
            *(int *)value = !!b;
595
0
        break;
596
0
    }
597
0
    case gs_spt_int:
598
0
    {
599
0
        int i;
600
0
        code = param_read_int((gs_param_list *)&params, param, &i);
601
0
        if (code == 1)
602
0
            code = gs_error_undefined;
603
0
        if (code < 0)
604
0
            break;
605
0
        code = sizeof(int);
606
0
        if (value != NULL)
607
0
            *(int *)value = i;
608
0
        break;
609
0
    }
610
0
    case gs_spt_float:
611
0
    {
612
0
        float f;
613
0
        code = param_read_float((gs_param_list *)&params, param, &f);
614
0
        if (code == 1)
615
0
            code = gs_error_undefined;
616
0
        if (code < 0)
617
0
            break;
618
0
        code = sizeof(float);
619
0
        if (value != NULL)
620
0
            *(float *)value = f;
621
0
        break;
622
0
    }
623
0
    case gs_spt_name:
624
0
        code = param_read_name((gs_param_list *)&params, param, &str_value);
625
0
        if (code == 1)
626
0
            code = gs_error_undefined;
627
0
        if (code < 0)
628
0
            break;
629
0
        if (value != NULL) {
630
0
            memcpy(value, str_value.data, str_value.size);
631
0
            ((char *)value)[str_value.size] = 0;
632
0
        }
633
0
        code = str_value.size+1;
634
0
        break;
635
0
    case gs_spt_string:
636
0
        code = param_read_string((gs_param_list *)&params, param, &str_value);
637
0
        if (code == 1)
638
0
            code = gs_error_undefined;
639
0
        if (code < 0)
640
0
            break;
641
0
        if (value != NULL) {
642
0
            memcpy(value, str_value.data, str_value.size);
643
0
            ((char *)value)[str_value.size] = 0;
644
0
        }
645
0
        code = str_value.size+1;
646
0
        break;
647
0
    case gs_spt_long:
648
0
    {
649
0
        long l;
650
0
        code = param_read_long((gs_param_list *)&params, param, &l);
651
0
        if (code == 1)
652
0
            code = gs_error_undefined;
653
0
        if (code < 0)
654
0
            break;
655
0
        if (value != NULL)
656
0
            *(long *)value = l;
657
0
        code = sizeof(long);
658
0
        break;
659
0
    }
660
0
    case gs_spt_i64:
661
0
    {
662
0
        int64_t i64;
663
0
        code = param_read_i64((gs_param_list *)&params, param, &i64);
664
0
        if (code == 1)
665
0
            code = gs_error_undefined;
666
0
        if (code < 0)
667
0
            break;
668
0
        if (value != NULL)
669
0
            *(int64_t *)value = i64;
670
0
        code = sizeof(int64_t);
671
0
        break;
672
0
    }
673
0
    case gs_spt_size_t:
674
0
    {
675
0
        size_t z;
676
0
        code = param_read_size_t((gs_param_list *)&params, param, &z);
677
0
        if (code == 1)
678
0
            code = gs_error_undefined;
679
0
        if (code < 0)
680
0
            break;
681
0
        if (value != NULL)
682
0
            *(size_t *)value = z;
683
0
        code = sizeof(size_t);
684
0
        break;
685
0
    }
686
0
    case gs_spt_parsed:
687
0
    {
688
0
        int len;
689
0
        code = gs_param_list_to_string((gs_param_list *)&params,
690
0
                                       param, (char *)value, &len);
691
0
        if (code == 1)
692
0
            code = gs_error_undefined;
693
0
        if (code >= 0)
694
0
            code = len;
695
0
        break;
696
0
    }
697
0
    default:
698
0
        code = gs_note_error(gs_error_rangecheck);
699
0
    }
700
0
    gs_c_param_list_release(&params);
701
702
0
    return code;
703
0
}
704
705
GSDLLEXPORT int GSDLLAPI
706
gsapi_enumerate_params(void *instance, void **iter, const char **key, gs_set_param_type *type)
707
0
{
708
0
    gs_main_instance *minst;
709
0
    gs_c_param_list *params;
710
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
711
0
    int code = 0;
712
0
    gs_param_key_t keyp;
713
714
0
    if (ctx == NULL)
715
0
        return gs_error_Fatal;
716
717
0
    gp_set_debug_mem_ptr(ctx->memory);
718
0
    minst = get_minst_from_memory(ctx->memory);
719
0
    params = &minst->enum_params;
720
721
0
    if (key == NULL)
722
0
        return -1;
723
0
    *key = NULL;
724
0
    if (iter == NULL)
725
0
        return -1;
726
727
0
    if (*iter == NULL) {
728
        /* Free any existing param list. */
729
0
        gs_c_param_list_release(params);
730
0
        if (minst->i_ctx_p == NULL) {
731
0
            return 1;
732
0
        }
733
        /* Set up a new one. */
734
0
        gs_c_param_list_write(params, minst->heap);
735
        /* Get the keys. */
736
0
        code = psapi_get_device_params(ctx, (gs_param_list *)params);
737
0
        if (code < 0)
738
0
            return code;
739
740
0
        param_init_enumerator(&minst->enum_iter);
741
0
        *iter = &minst->enum_iter;
742
0
    } else if (*iter != &minst->enum_iter)
743
0
        return -1;
744
745
0
    gs_c_param_list_read(params);
746
0
    code = param_get_next_key((gs_param_list *)params, &minst->enum_iter, &keyp);
747
0
    if (code < 0)
748
0
        return code;
749
0
    if (code != 0) {
750
        /* End of iteration. */
751
0
        *iter = NULL;
752
0
        return 1;
753
0
    }
754
0
    if (minst->enum_keybuf_max < keyp.size+1) {
755
0
        int newsize = keyp.size+1;
756
0
        char *newkey;
757
0
        if (newsize < 128)
758
0
            newsize = 128;
759
0
        if (minst->enum_keybuf == NULL) {
760
0
            newkey = (char *)gs_alloc_bytes(minst->heap, newsize, "enumerator key buffer");
761
0
        } else {
762
0
            newkey = (char *)gs_resize_object(minst->heap, minst->enum_keybuf, newsize, "enumerator key buffer");
763
0
        }
764
0
        if (newkey == NULL)
765
0
            return_error(gs_error_VMerror);
766
0
        minst->enum_keybuf = newkey;
767
0
        minst->enum_keybuf_max = newsize;
768
0
    }
769
0
    memcpy(minst->enum_keybuf, keyp.data, keyp.size);
770
0
    minst->enum_keybuf[keyp.size] = 0;
771
0
    *key = minst->enum_keybuf;
772
773
0
    if (type) {
774
0
        gs_param_typed_value pvalue;
775
0
        pvalue.type = gs_param_type_any;
776
0
        code = param_read_typed((gs_param_list *)params, *key, &pvalue);
777
0
        if (code < 0)
778
0
            return code;
779
0
        if (code > 0)
780
0
            return_error(gs_error_unknownerror);
781
782
0
        switch (pvalue.type) {
783
0
        case gs_param_type_null:
784
0
            *type = gs_spt_null;
785
0
            break;
786
0
        case gs_param_type_bool:
787
0
            *type = gs_spt_bool;
788
0
            break;
789
0
        case gs_param_type_int:
790
0
            *type = gs_spt_int;
791
0
            break;
792
0
        case gs_param_type_long:
793
0
            *type = gs_spt_long;
794
0
            break;
795
0
        case gs_param_type_size_t:
796
0
            *type = gs_spt_size_t;
797
0
            break;
798
0
        case gs_param_type_i64:
799
0
            *type = gs_spt_i64;
800
0
            break;
801
0
        case gs_param_type_float:
802
0
            *type = gs_spt_float;
803
0
            break;
804
0
        case gs_param_type_string:
805
0
            *type = gs_spt_string;
806
0
            break;
807
0
        case gs_param_type_name:
808
0
            *type = gs_spt_name;
809
0
            break;
810
0
        default:
811
0
            *type = gs_spt_parsed;
812
0
            break;
813
0
        }
814
0
    }
815
816
0
    return code;
817
0
}
818
819
GSDLLEXPORT int GSDLLAPI
820
gsapi_add_control_path(void *instance, int type, const char *path)
821
0
{
822
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
823
0
    if (ctx == NULL)
824
0
        return gs_error_Fatal;
825
0
    gp_set_debug_mem_ptr(ctx->memory);
826
0
    return gs_add_control_path(ctx->memory, type, path);
827
0
}
828
829
GSDLLEXPORT int GSDLLAPI
830
gsapi_remove_control_path(void *instance, int type, const char *path)
831
0
{
832
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
833
0
    if (ctx == NULL)
834
0
        return gs_error_Fatal;
835
0
    gp_set_debug_mem_ptr(ctx->memory);
836
0
    return gs_remove_control_path(ctx->memory, type, path);
837
0
}
838
839
GSDLLEXPORT void GSDLLAPI
840
gsapi_purge_control_paths(void *instance, int type)
841
0
{
842
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
843
0
    if (ctx == NULL)
844
0
        return;
845
0
    gp_set_debug_mem_ptr(ctx->memory);
846
0
    gs_purge_control_paths(ctx->memory, type);
847
0
}
848
849
GSDLLEXPORT void GSDLLAPI
850
gsapi_activate_path_control(void *instance, int enable)
851
0
{
852
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
853
0
    if (ctx == NULL)
854
0
        return;
855
0
    gp_set_debug_mem_ptr(ctx->memory);
856
0
    gs_activate_path_control(ctx->memory, enable);
857
0
}
858
859
GSDLLEXPORT int GSDLLAPI
860
gsapi_is_path_control_active(void *instance)
861
0
{
862
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
863
0
    if (ctx == NULL)
864
0
        return 0;
865
0
    gp_set_debug_mem_ptr(ctx->memory);
866
0
    return gs_is_path_control_active(ctx->memory);
867
0
}
868
869
GSDLLEXPORT int GSDLLAPI
870
gsapi_add_fs(void *instance, gsapi_fs_t *fs, void *secret)
871
0
{
872
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
873
0
    if (ctx == NULL)
874
0
        return 0;
875
0
    gp_set_debug_mem_ptr(ctx->memory);
876
0
    return gs_add_fs(ctx->memory, (gs_fs_t *)fs, secret);
877
0
}
878
879
GSDLLEXPORT void GSDLLAPI
880
gsapi_remove_fs(void *instance, gsapi_fs_t *fs, void *secret)
881
0
{
882
0
    gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)instance;
883
0
    if (ctx == NULL)
884
0
        return;
885
0
    gp_set_debug_mem_ptr(ctx->memory);
886
0
    gs_remove_fs(ctx->memory, (gs_fs_t *)fs, secret);
887
0
}
888
889
/* end of iapi.c */