1 /* Copyright (C) 2000 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: ziodevst.c,v 1.1 2003/02/18 19:57:16 igor Exp $ */
18 /* %static% IODevice implementation */
19 #include "ghost.h"
20 #include "gserrors.h"
21 #include "gsstruct.h"
22 #include "gxiodev.h"
23 #include "istruct.h"
24 #include "idict.h"
25 #include "iconf.h"
26 #include "oper.h"
27 #include "store.h"
28 #include "stream.h"
29 #include "files.h"
30 #include "string_.h"
31 #include "memory_.h"
32
33
34
35 typedef struct iostatic_state_s {
36 ref data;
37 } iostatic_state;
38
39 private
CLEAR_MARKS_PROC(iostatic_state_clear_marks)40 CLEAR_MARKS_PROC(iostatic_state_clear_marks)
41 { iostatic_state *const pptr = vptr;
42
43 r_clear_attrs(&pptr->data, l_mark);
44 }
45 private
46 ENUM_PTRS_WITH(iostatic_state_enum_ptrs, iostatic_state *pptr) return 0;
47 case 0:
48 ENUM_RETURN_REF(&pptr->data);
49 ENUM_PTRS_END
50 private RELOC_PTRS_WITH(iostatic_state_reloc_ptrs, iostatic_state *pptr);
51 RELOC_REF_VAR(pptr->data);
52 r_clear_attrs(&pptr->data, l_mark);
53 RELOC_PTRS_END
54
55 gs_private_st_complex_only(st_iostatic_state, iostatic_state,\
56 "iostatic_state", iostatic_state_clear_marks, iostatic_state_enum_ptrs,
57 iostatic_state_reloc_ptrs, 0);
58
59 const char iodev_dtype_static[] = "Special";
60
61 private int
iostatic_init(gx_io_device * iodev,gs_memory_t * mem)62 iostatic_init(gx_io_device * iodev, gs_memory_t * mem)
63 {
64 iostatic_state *pstate = gs_alloc_struct(mem, iostatic_state, &st_iostatic_state,
65 "iostatic_init");
66 if (!pstate)
67 return gs_error_VMerror;
68 make_null(&pstate->data);
69 iodev->state = pstate;
70 return 0;
71 }
72
73 private int
iostatic_open_file(gx_io_device * iodev,const char * fname,uint namelen,const char * access,stream ** ps,gs_memory_t * mem)74 iostatic_open_file(gx_io_device * iodev, const char *fname, uint namelen,
75 const char *access, stream ** ps, gs_memory_t * mem)
76 {
77 const char *cat_name = fname + 1, *inst_name;
78 int cat_name_len, inst_name_len, code;
79 iostatic_state *state = (iostatic_state *)iodev->state;
80 char buf[30];
81 ref *cat, *inst, *beg_pos, *end_pos, file;
82
83 if (fname[0] != '/')
84 return_error(gs_error_undefinedfilename);
85 inst_name = strchr(cat_name, '/');
86 if (inst_name == NULL)
87 return_error(gs_error_undefinedfilename);
88 cat_name_len = inst_name - cat_name;
89 inst_name++;
90 inst_name_len = fname + namelen - inst_name;
91 if (cat_name_len > sizeof(buf) - 1 || inst_name_len > sizeof(buf) - 1) {
92 /* The operator 'file' doesn't allow rangecheck here. */
93 return_error(gs_error_undefinedfilename);
94 }
95 memcpy(buf, cat_name, cat_name_len);
96 buf[cat_name_len] = 0;
97 code = dict_find_string(&state->data, buf, &cat);
98 if (code < 0)
99 return code;
100 if (code == 0 || r_type(cat) != t_dictionary)
101 return_error(gs_error_unregistered); /* Wrong gs_resst.ps . */
102 memcpy(buf, inst_name, inst_name_len);
103 buf[inst_name_len] = 0;
104 code = dict_find_string(cat, buf, &inst);
105 if (code < 0)
106 return code;
107 if (code == 0 || r_type(inst) != t_dictionary)
108 return_error(gs_error_unregistered); /* Wrong gs_resst.ps . */
109 code = dict_find_string(inst, "StaticFilePos", &beg_pos);
110 if (code < 0)
111 return code;
112 if (code == 0 || r_type(beg_pos) != t_integer)
113 return_error(gs_error_unregistered); /* Wrong gs_resst.ps . */
114 code = dict_find_string(inst, "StaticFileEnd", &end_pos);
115 if (code < 0)
116 return code;
117 if (code == 0 || r_type(end_pos) != t_integer)
118 return_error(gs_error_unregistered); /* Wrong gs_resst.ps . */
119 code = file_read_string(gs_init_string + beg_pos->value.intval,
120 end_pos->value.intval - beg_pos->value.intval,
121 &file, (gs_ref_memory_t *)mem);
122 if (code < 0)
123 return code;
124 *ps = file.value.pfile;
125 return 0;
126 }
127
128 const gx_io_device gs_iodev_static = {
129 "%static%", iodev_dtype_static,
130 { iostatic_init, iodev_no_open_device, iostatic_open_file,
131 iodev_no_fopen, iodev_no_fclose,
132 iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,
133 iodev_no_enumerate_files, NULL, NULL,
134 iodev_no_get_params, iodev_no_put_params
135 }
136 };
137
138 /* <dict> .setup_io_static - */
139 private int
zsetup_io_static(i_ctx_t * i_ctx_p)140 zsetup_io_static(i_ctx_t *i_ctx_p)
141 {
142 os_ptr op = osp;
143 gx_io_device *piodev;
144
145 check_read_type(*op, t_dictionary);
146
147 piodev = gs_findiodevice((const byte *)"%static%", 8);
148 if (piodev == NULL)
149 return_error(gs_error_unregistered); /* Must not happen. */
150 ref_assign_new(&((iostatic_state *)piodev->state)->data, op);
151 pop(1);
152 return 0;
153 }
154
155 const op_def ziodevst_op_defs[] =
156 {
157 {"0.setup_io_static", zsetup_io_static},
158 op_def_end(0)
159 };
160
161
162
163
164
165