blob: 957b9e47108ea626d7184ce164f9a6a695004524 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdlib.h>
2#include <string.h>
3#include <errno.h>
4#include <assert.h>
5
6#include "asn1parser.h"
Lev Walkinea6635b2017-08-06 23:23:04 -07007#include "asn1p_expr.h"
Lev Walkinf15320b2004-06-03 03:38:44 +00008
Lev Walkinea6635b2017-08-06 23:23:04 -07009void
10asn1p_value_set_source(asn1p_value_t *value, asn1p_module_t *module,
11 int lineno) {
12 if(value) {
13 switch(value->type) {
14 case ATV_TYPE:
15 asn1p_expr_set_source(value->value.v_type, module, lineno);
16 break;
17 case ATV_REFERENCED:
18 asn1p_ref_set_source(value->value.reference, module, lineno);
19 break;
20 case ATV_VALUESET:
21 asn1p_constraint_set_source(value->value.constraint, module,
22 lineno);
23 break;
24 default:
25 break;
26 }
27 }
28}
29
30int
31asn1p_value_compare(const asn1p_value_t *a, const asn1p_value_t *b) {
32 if(a->type != b->type) {
33 return -1;
34 }
35
36 switch(a->type) {
37 case ATV_NULL:
38 case ATV_NOVALUE:
39 case ATV_MAX:
40 case ATV_MIN:
41 case ATV_FALSE:
42 case ATV_TRUE:
43 break;
44 case ATV_TYPE:
45 return asn1p_expr_compare(a->value.v_type, b->value.v_type);
46 case ATV_REAL:
47 return (a->value.v_double == b->value.v_double) ? 0 : -1;
48 case ATV_INTEGER:
49 case ATV_TUPLE:
50 case ATV_QUADRUPLE:
51 return (a->value.v_integer == b->value.v_integer) ? 0 : -1;
52 case ATV_STRING:
53 case ATV_UNPARSED:
54 if(a->value.string.size != b->value.string.size
55 || memcmp(a->value.string.buf, b->value.string.buf,
56 a->value.string.size)
57 != 0) {
58 return -1;
59 }
60 return 0;
61 case ATV_BITVECTOR:
62 if(a->value.binary_vector.size_in_bits
63 != b->value.binary_vector.size_in_bits
64 || memcmp(a->value.binary_vector.bits, b->value.binary_vector.bits,
65 (a->value.binary_vector.size_in_bits+7) >> 3)
66 != 0) {
67 return -1;
68 }
Lev Walkin48e82d12017-10-19 03:06:35 -070069 return 0;
Lev Walkinea6635b2017-08-06 23:23:04 -070070 case ATV_VALUESET:
71 return asn1p_constraint_compare(a->value.constraint,
72 b->value.constraint);
73 case ATV_REFERENCED:
74 return asn1p_ref_compare(a->value.reference, b->value.reference);
75 case ATV_CHOICE_IDENTIFIER:
76 if(strcmp(a->value.choice_identifier.identifier,
77 b->value.choice_identifier.identifier)
78 != 0) {
79 return -1;
80 }
81 return asn1p_value_compare(a->value.choice_identifier.value,
82 b->value.choice_identifier.value);
83 }
84
85 return 0;
86}
Lev Walkinf15320b2004-06-03 03:38:44 +000087
88asn1p_value_t *
89asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) {
90 if(ref) {
91 asn1p_value_t *v = calloc(1, sizeof *v);
92 if(v) {
93 if(do_copy) {
94 v->value.reference = asn1p_ref_clone(ref);
95 if(v->value.reference == NULL) {
96 free(v);
97 return NULL;
98 }
99 } else {
100 v->value.reference = ref;
101 }
102 v->type = ATV_REFERENCED;
103 }
104 return v;
105 } else {
106 errno = EINVAL;
107 return NULL;
108 }
109}
110
111asn1p_value_t *
Lev Walkin5045dfa2006-03-21 09:41:28 +0000112asn1p_value_fromconstr(asn1p_constraint_t *ct, int do_copy) {
113 if(ct) {
114 asn1p_value_t *v = calloc(1, sizeof *v);
115 if(v) {
116 if(do_copy) {
117 v->value.constraint
118 = asn1p_constraint_clone(ct);
119 if(v->value.constraint == NULL) {
120 free(v);
121 return NULL;
122 }
123 } else {
124 v->value.constraint = ct;
125 }
126 v->type = ATV_VALUESET;
127 }
128 return v;
129 } else {
130 errno = EINVAL;
131 return NULL;
132 }
133}
134
135asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000136asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
137 if(bits) {
138 asn1p_value_t *v = calloc(1, sizeof *v);
139 assert(size_in_bits >= 0);
140 if(v) {
141 if(do_copy) {
142 int size = ((size_in_bits + 7) >> 3);
143 void *p;
144 p = malloc(size + 1);
145 if(p) {
146 memcpy(p, bits, size);
147 ((char *)p)[size] = '\0'; /* JIC */
148 } else {
149 free(v);
150 return NULL;
151 }
152 v->value.binary_vector.bits = p;
153 } else {
154 v->value.binary_vector.bits = (void *)bits;
155 }
156 v->value.binary_vector.size_in_bits = size_in_bits;
157 v->type = ATV_BITVECTOR;
158 }
159 return v;
160 } else {
161 errno = EINVAL;
162 return NULL;
163 }
164}
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800165
Lev Walkinf15320b2004-06-03 03:38:44 +0000166asn1p_value_t *
167asn1p_value_frombuf(char *buffer, int size, int do_copy) {
168 if(buffer) {
169 asn1p_value_t *v = calloc(1, sizeof *v);
170 assert(size >= 0);
171 if(v) {
172 if(do_copy) {
173 void *p = malloc(size + 1);
174 if(p) {
175 memcpy(p, buffer, size);
176 ((char *)p)[size] = '\0'; /* JIC */
177 } else {
178 free(v);
179 return NULL;
180 }
181 v->value.string.buf = p;
182 } else {
Lev Walkin84fbd722005-06-15 18:41:50 +0000183 v->value.string.buf = (uint8_t *)buffer;
Lev Walkinf15320b2004-06-03 03:38:44 +0000184 }
185 v->value.string.size = size;
186 v->type = ATV_STRING;
187 }
188 return v;
189 } else {
190 errno = EINVAL;
191 return NULL;
192 }
193}
194
195asn1p_value_t *
196asn1p_value_fromdouble(double d) {
197 asn1p_value_t *v = calloc(1, sizeof *v);
198 if(v) {
199 v->value.v_double = d;
200 v->type = ATV_REAL;
201 }
202 return v;
203}
204
205asn1p_value_t *
Lev Walkind21c5052004-09-29 13:18:09 +0000206asn1p_value_fromint(asn1c_integer_t i) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000207 asn1p_value_t *v = calloc(1, sizeof *v);
208 if(v) {
209 v->value.v_integer = i;
210 v->type = ATV_INTEGER;
211 }
212 return v;
213}
214
215asn1p_value_t *
Lev Walkina9532f42006-09-17 04:52:50 +0000216asn1p_value_fromtype(asn1p_expr_t *expr) {
217 asn1p_value_t *v = calloc(1, sizeof *v);
218 if(v) {
219 v->value.v_type = expr;
220 v->type = ATV_TYPE;
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800221 expr->ref_cnt++;
Lev Walkina9532f42006-09-17 04:52:50 +0000222 }
223 return v;
224}
225
226asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000227asn1p_value_clone(asn1p_value_t *v) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000228 return asn1p_value_clone_with_resolver(v, 0, 0);
229}
230
231asn1p_value_t *
232asn1p_value_clone_with_resolver(asn1p_value_t *v,
233 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
234 void *rarg) {
Lev Walkin9c974182004-09-15 11:59:51 +0000235 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000236 if(v) {
237 switch(v->type) {
238 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000239 case ATV_NULL:
240 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000241 case ATV_REAL:
242 return asn1p_value_fromdouble(v->value.v_double);
Lev Walkina9532f42006-09-17 04:52:50 +0000243 case ATV_TYPE:
244 return asn1p_value_fromtype(v->value.v_type);
Lev Walkinf15320b2004-06-03 03:38:44 +0000245 case ATV_INTEGER:
246 case ATV_MIN:
247 case ATV_MAX:
248 case ATV_FALSE:
249 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000250 case ATV_TUPLE:
251 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000252 clone = asn1p_value_fromint(v->value.v_integer);
253 if(clone) clone->type = v->type;
254 return clone;
255 case ATV_STRING:
Lev Walkin84fbd722005-06-15 18:41:50 +0000256 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000257 v->value.string.size, 1);
258 if(clone) clone->type = v->type;
259 return clone;
260 case ATV_UNPARSED:
Lev Walkin84fbd722005-06-15 18:41:50 +0000261 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000262 v->value.string.size, 1);
263 if(clone) clone->type = ATV_UNPARSED;
264 return clone;
265 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000266 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000267 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000268 case ATV_REFERENCED:
Lev Walkina00d6b32006-03-21 03:40:38 +0000269 if(resolver) {
270 clone = resolver(v, rarg);
271 if(clone) return clone;
272 else if(errno != ESRCH) return NULL;
273 }
Lev Walkin9c974182004-09-15 11:59:51 +0000274 return asn1p_value_fromref(v->value.reference, 1);
Lev Walkin5045dfa2006-03-21 09:41:28 +0000275 case ATV_VALUESET:
276 if(resolver) {
277 clone = resolver(v, rarg);
278 if(clone) return clone;
279 else if(errno != ESRCH) return NULL;
280 }
281 return asn1p_value_fromconstr(v->value.constraint, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000282 case ATV_CHOICE_IDENTIFIER: {
283 char *id = v->value.choice_identifier.identifier;
284 clone = calloc(1, sizeof(*clone));
285 if(!clone) return NULL;
286 clone->type = v->type;
287 id = strdup(id);
288 if(!id) { asn1p_value_free(clone); return NULL; }
289 clone->value.choice_identifier.identifier = id;
290 v = asn1p_value_clone(v->value.choice_identifier.value);
291 if(!v) { asn1p_value_free(clone); return NULL; }
292 clone->value.choice_identifier.value = v;
293 return clone;
294 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000295 }
Lev Walkin9c974182004-09-15 11:59:51 +0000296
297 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000298 }
299 return v;
300}
301
302void
303asn1p_value_free(asn1p_value_t *v) {
304 if(v) {
305 switch(v->type) {
306 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000307 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000308 break;
Lev Walkina9532f42006-09-17 04:52:50 +0000309 case ATV_TYPE:
310 asn1p_expr_free(v->value.v_type);
311 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000312 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000313 case ATV_INTEGER:
314 case ATV_MIN:
315 case ATV_MAX:
316 case ATV_FALSE:
317 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000318 case ATV_TUPLE:
319 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000320 /* No freeing necessary */
321 break;
322 case ATV_STRING:
323 case ATV_UNPARSED:
324 assert(v->value.string.buf);
325 free(v->value.string.buf);
326 break;
327 case ATV_BITVECTOR:
328 assert(v->value.binary_vector.bits);
329 free(v->value.binary_vector.bits);
330 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000331 case ATV_REFERENCED:
332 asn1p_ref_free(v->value.reference);
333 break;
Lev Walkin5045dfa2006-03-21 09:41:28 +0000334 case ATV_VALUESET:
335 asn1p_constraint_free(v->value.constraint);
336 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000337 case ATV_CHOICE_IDENTIFIER:
338 free(v->value.choice_identifier.identifier);
339 asn1p_value_free(v->value.choice_identifier.value);
340 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000341 }
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800342 memset(v, 0, sizeof(*v));
Lev Walkinf15320b2004-06-03 03:38:44 +0000343 free(v);
344 }
345}
346