1 | /*
|
---|
2 | * Copyright (c) 1995-2000, Index Data
|
---|
3 | * See the file LICENSE for details.
|
---|
4 | * Sebastian Hammer, Adam Dickmeiss
|
---|
5 | *
|
---|
6 | * $Log$
|
---|
7 | * Revision 1.1 2000/08/03 03:11:24 johnmcp
|
---|
8 | * Added the YAZ toolkit source to the packages directory (for z39.50 stuff)
|
---|
9 | *
|
---|
10 | * Revision 1.27 2000/02/29 13:44:55 adam
|
---|
11 | * Check for config.h (currently not generated).
|
---|
12 | *
|
---|
13 | * Revision 1.26 2000/01/31 13:15:21 adam
|
---|
14 | * Removed uses of assert(3). Cleanup of ODR. CCL parser update so
|
---|
15 | * that some characters are not surrounded by spaces in resulting term.
|
---|
16 | * ILL-code updates.
|
---|
17 | *
|
---|
18 | * Revision 1.25 1999/11/30 13:47:11 adam
|
---|
19 | * Improved installation. Moved header files to include/yaz.
|
---|
20 | *
|
---|
21 | * Revision 1.24 1999/04/20 09:56:48 adam
|
---|
22 | * Added 'name' paramter to encoder/decoder routines (typedef Odr_fun).
|
---|
23 | * Modified all encoders/decoders to reflect this change.
|
---|
24 | *
|
---|
25 | * Revision 1.23 1998/03/20 14:45:01 adam
|
---|
26 | * Implemented odr_enum and odr_set_of.
|
---|
27 | *
|
---|
28 | * Revision 1.22 1998/02/11 11:53:34 adam
|
---|
29 | * Changed code so that it compiles as C++.
|
---|
30 | *
|
---|
31 | * Revision 1.21 1997/11/24 11:33:56 adam
|
---|
32 | * Using function odr_nullval() instead of global ODR_NULLVAL when
|
---|
33 | * appropriate.
|
---|
34 | *
|
---|
35 | * Revision 1.20 1997/09/29 07:17:31 adam
|
---|
36 | * Added typecast to avoid warnings on MSVC.
|
---|
37 | *
|
---|
38 | * Revision 1.19 1997/06/23 10:31:11 adam
|
---|
39 | * Added RVDM's SEQUENCE OF patch again!
|
---|
40 | *
|
---|
41 | * Revision 1.18 1997/05/14 06:53:58 adam
|
---|
42 | * C++ support.
|
---|
43 | *
|
---|
44 | * Revision 1.17 1997/05/05 11:21:09 adam
|
---|
45 | * In handling of SEQUENCE OF: Counter set to zero when SEQUENCE
|
---|
46 | * OF isn't there at all.
|
---|
47 | *
|
---|
48 | * Revision 1.16 1995/09/29 17:12:26 quinn
|
---|
49 | * Smallish
|
---|
50 | *
|
---|
51 | * Revision 1.15 1995/09/27 15:03:00 quinn
|
---|
52 | * Modified function heads & prototypes.
|
---|
53 | *
|
---|
54 | * Revision 1.14 1995/08/15 11:16:39 quinn
|
---|
55 | * Fixed pretty-printers.
|
---|
56 | *
|
---|
57 | * Revision 1.13 1995/05/22 14:56:57 quinn
|
---|
58 | * Fixed problem in decoding empty sequence.
|
---|
59 | *
|
---|
60 | * Revision 1.12 1995/05/18 13:06:32 quinn
|
---|
61 | * Smallish.
|
---|
62 | *
|
---|
63 | * Revision 1.11 1995/05/17 08:41:54 quinn
|
---|
64 | * Small, hopefully insignificant change.
|
---|
65 | *
|
---|
66 | * Revision 1.10 1995/05/16 08:50:59 quinn
|
---|
67 | * License, documentation, and memory fixes
|
---|
68 | *
|
---|
69 | * Revision 1.9 1995/03/17 10:17:57 quinn
|
---|
70 | * Added memory management.
|
---|
71 | *
|
---|
72 | * Revision 1.8 1995/03/15 11:18:05 quinn
|
---|
73 | * Fixed serious bug in odr_cons
|
---|
74 | *
|
---|
75 | * Revision 1.7 1995/03/08 12:12:30 quinn
|
---|
76 | * Added better error checking.
|
---|
77 | *
|
---|
78 | * Revision 1.6 1995/02/10 15:55:29 quinn
|
---|
79 | * Bug fixes, mostly.
|
---|
80 | *
|
---|
81 | * Revision 1.5 1995/02/09 15:51:49 quinn
|
---|
82 | * Works better now.
|
---|
83 | *
|
---|
84 | * Revision 1.4 1995/02/07 17:53:00 quinn
|
---|
85 | * A damn mess, but now things work, I think.
|
---|
86 | *
|
---|
87 | * Revision 1.3 1995/02/07 14:13:46 quinn
|
---|
88 | * Bug fixes.
|
---|
89 | *
|
---|
90 | * Revision 1.2 1995/02/06 16:45:03 quinn
|
---|
91 | * Small mods.
|
---|
92 | *
|
---|
93 | * Revision 1.1 1995/02/02 16:21:54 quinn
|
---|
94 | * First kick.
|
---|
95 | *
|
---|
96 | */
|
---|
97 |
|
---|
98 | #if HAVE_CONFIG_H
|
---|
99 | #include <config.h>
|
---|
100 | #endif
|
---|
101 |
|
---|
102 | #include <yaz/odr.h>
|
---|
103 |
|
---|
104 | int odr_sequence_begin(ODR o, void *p, int size, const char *name)
|
---|
105 | {
|
---|
106 | char **pp = (char**) p;
|
---|
107 |
|
---|
108 | if (o->error)
|
---|
109 | return 0;
|
---|
110 | if (o->t_class < 0)
|
---|
111 | {
|
---|
112 | o->t_class = ODR_UNIVERSAL;
|
---|
113 | o->t_tag = ODR_SEQUENCE;
|
---|
114 | }
|
---|
115 | if (o->direction == ODR_DECODE)
|
---|
116 | *pp = 0;
|
---|
117 | if (odr_constructed_begin(o, p, o->t_class, o->t_tag, name))
|
---|
118 | {
|
---|
119 | if (o->direction == ODR_DECODE && size)
|
---|
120 | *pp = (char *)odr_malloc(o, size);
|
---|
121 | return 1;
|
---|
122 | }
|
---|
123 | else
|
---|
124 | return 0;
|
---|
125 | }
|
---|
126 |
|
---|
127 | int odr_set_begin(ODR o, void *p, int size, const char *name)
|
---|
128 | {
|
---|
129 | char **pp = (char**) p;
|
---|
130 |
|
---|
131 | if (o->error)
|
---|
132 | return 0;
|
---|
133 | if (o->t_class < 0)
|
---|
134 | {
|
---|
135 | o->t_class = ODR_UNIVERSAL;
|
---|
136 | o->t_tag = ODR_SET;
|
---|
137 | }
|
---|
138 | if (o->direction == ODR_DECODE)
|
---|
139 | *pp = 0;
|
---|
140 | if (odr_constructed_begin(o, p, o->t_class, o->t_tag, name))
|
---|
141 | {
|
---|
142 | if (o->direction == ODR_DECODE && size)
|
---|
143 | *pp = (char *)odr_malloc(o, size);
|
---|
144 | return 1;
|
---|
145 | }
|
---|
146 | else
|
---|
147 | return 0;
|
---|
148 | }
|
---|
149 |
|
---|
150 | int odr_sequence_end(ODR o)
|
---|
151 | {
|
---|
152 | return odr_constructed_end(o);
|
---|
153 | }
|
---|
154 |
|
---|
155 | int odr_set_end(ODR o)
|
---|
156 | {
|
---|
157 | return odr_constructed_end(o);
|
---|
158 | }
|
---|
159 |
|
---|
160 | static int odr_sequence_more(ODR o)
|
---|
161 | {
|
---|
162 | return odr_constructed_more(o);
|
---|
163 | }
|
---|
164 |
|
---|
165 | static int odr_sequence_x (ODR o, Odr_fun type, void *p, int *num)
|
---|
166 | {
|
---|
167 | char ***pp = (char***) p; /* for dereferencing */
|
---|
168 | char **tmp = 0;
|
---|
169 | int size = 0, i;
|
---|
170 |
|
---|
171 | switch (o->direction)
|
---|
172 | {
|
---|
173 | case ODR_DECODE:
|
---|
174 | *num = 0;
|
---|
175 | *pp = (char **)odr_nullval();
|
---|
176 | while (odr_sequence_more(o))
|
---|
177 | {
|
---|
178 | /* outgrown array? */
|
---|
179 | if (*num * (int) sizeof(void*) >= size)
|
---|
180 | {
|
---|
181 | /* double the buffer size */
|
---|
182 | tmp = (char **)odr_malloc(o, sizeof(void*) *
|
---|
183 | (size += size ? size : 128));
|
---|
184 | if (*num)
|
---|
185 | {
|
---|
186 | memcpy(tmp, *pp, *num * sizeof(void*));
|
---|
187 | /*
|
---|
188 | * For now, we just throw the old *p away, since we use
|
---|
189 | * nibble memory anyway (disgusting, isn't it?).
|
---|
190 | */
|
---|
191 | }
|
---|
192 | *pp = tmp;
|
---|
193 | }
|
---|
194 | if (!(*type)(o, (*pp) + *num, 0, 0))
|
---|
195 | return 0;
|
---|
196 | (*num)++;
|
---|
197 | }
|
---|
198 | break;
|
---|
199 | case ODR_ENCODE: case ODR_PRINT:
|
---|
200 | #ifdef ODR_DEBUG
|
---|
201 | fprintf(stderr, "[seqof: num=%d]", *num);
|
---|
202 | #endif
|
---|
203 | for (i = 0; i < *num; i++)
|
---|
204 | {
|
---|
205 | #ifdef ODR_DEBUG
|
---|
206 | fprintf(stderr, "[seqof: elem #%d]", i);
|
---|
207 | #endif
|
---|
208 | if (!(*type)(o, *pp + i, 0, 0))
|
---|
209 | return 0;
|
---|
210 | }
|
---|
211 | break;
|
---|
212 | default:
|
---|
213 | o->error = OOTHER;
|
---|
214 | return 0;
|
---|
215 | }
|
---|
216 | return odr_sequence_end(o);
|
---|
217 | }
|
---|
218 |
|
---|
219 | int odr_set_of(ODR o, Odr_fun type, void *p, int *num, const char *name)
|
---|
220 | {
|
---|
221 | if (!odr_set_begin(o, p, 0, name)) {
|
---|
222 | if (o->direction == ODR_DECODE)
|
---|
223 | *num = 0;
|
---|
224 | return 0;
|
---|
225 | }
|
---|
226 | return odr_sequence_x (o, type, p, num);
|
---|
227 | }
|
---|
228 |
|
---|
229 | int odr_sequence_of(ODR o, Odr_fun type, void *p, int *num,
|
---|
230 | const char *name)
|
---|
231 | {
|
---|
232 | if (!odr_sequence_begin(o, p, 0, name)) {
|
---|
233 | if (o->direction == ODR_DECODE)
|
---|
234 | *num = 0;
|
---|
235 | return 0;
|
---|
236 | }
|
---|
237 | return odr_sequence_x (o, type, p, num);
|
---|
238 | }
|
---|
239 |
|
---|