xref: /plan9/sys/src/cmd/gs/src/ziodevst.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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