blob: 9bd75639286050effc328c49682e510b902344f0 [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 }
69 case ATV_VALUESET:
70 return asn1p_constraint_compare(a->value.constraint,
71 b->value.constraint);
72 case ATV_REFERENCED:
73 return asn1p_ref_compare(a->value.reference, b->value.reference);
74 case ATV_CHOICE_IDENTIFIER:
75 if(strcmp(a->value.choice_identifier.identifier,
76 b->value.choice_identifier.identifier)
77 != 0) {
78 return -1;
79 }
80 return asn1p_value_compare(a->value.choice_identifier.value,
81 b->value.choice_identifier.value);
82 }
83
84 return 0;
85}
Lev Walkinf15320b2004-06-03 03:38:44 +000086
87asn1p_value_t *
88asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) {
89 if(ref) {
90 asn1p_value_t *v = calloc(1, sizeof *v);
91 if(v) {
92 if(do_copy) {
93 v->value.reference = asn1p_ref_clone(ref);
94 if(v->value.reference == NULL) {
95 free(v);
96 return NULL;
97 }
98 } else {
99 v->value.reference = ref;
100 }
101 v->type = ATV_REFERENCED;
102 }
103 return v;
104 } else {
105 errno = EINVAL;
106 return NULL;
107 }
108}
109
110asn1p_value_t *
Lev Walkin5045dfa2006-03-21 09:41:28 +0000111asn1p_value_fromconstr(asn1p_constraint_t *ct, int do_copy) {
112 if(ct) {
113 asn1p_value_t *v = calloc(1, sizeof *v);
114 if(v) {
115 if(do_copy) {
116 v->value.constraint
117 = asn1p_constraint_clone(ct);
118 if(v->value.constraint == NULL) {
119 free(v);
120 return NULL;
121 }
122 } else {
123 v->value.constraint = ct;
124 }
125 v->type = ATV_VALUESET;
126 }
127 return v;
128 } else {
129 errno = EINVAL;
130 return NULL;
131 }
132}
133
134asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000135asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
136 if(bits) {
137 asn1p_value_t *v = calloc(1, sizeof *v);
138 assert(size_in_bits >= 0);
139 if(v) {
140 if(do_copy) {
141 int size = ((size_in_bits + 7) >> 3);
142 void *p;
143 p = malloc(size + 1);
144 if(p) {
145 memcpy(p, bits, size);
146 ((char *)p)[size] = '\0'; /* JIC */
147 } else {
148 free(v);
149 return NULL;
150 }
151 v->value.binary_vector.bits = p;
152 } else {
153 v->value.binary_vector.bits = (void *)bits;
154 }
155 v->value.binary_vector.size_in_bits = size_in_bits;
156 v->type = ATV_BITVECTOR;
157 }
158 return v;
159 } else {
160 errno = EINVAL;
161 return NULL;
162 }
163}
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800164
Lev Walkinf15320b2004-06-03 03:38:44 +0000165asn1p_value_t *
166asn1p_value_frombuf(char *buffer, int size, int do_copy) {
167 if(buffer) {
168 asn1p_value_t *v = calloc(1, sizeof *v);
169 assert(size >= 0);
170 if(v) {
171 if(do_copy) {
172 void *p = malloc(size + 1);
173 if(p) {
174 memcpy(p, buffer, size);
175 ((char *)p)[size] = '\0'; /* JIC */
176 } else {
177 free(v);
178 return NULL;
179 }
180 v->value.string.buf = p;
181 } else {
Lev Walkin84fbd722005-06-15 18:41:50 +0000182 v->value.string.buf = (uint8_t *)buffer;
Lev Walkinf15320b2004-06-03 03:38:44 +0000183 }
184 v->value.string.size = size;
185 v->type = ATV_STRING;
186 }
187 return v;
188 } else {
189 errno = EINVAL;
190 return NULL;
191 }
192}
193
194asn1p_value_t *
195asn1p_value_fromdouble(double d) {
196 asn1p_value_t *v = calloc(1, sizeof *v);
197 if(v) {
198 v->value.v_double = d;
199 v->type = ATV_REAL;
200 }
201 return v;
202}
203
204asn1p_value_t *
Lev Walkind21c5052004-09-29 13:18:09 +0000205asn1p_value_fromint(asn1c_integer_t i) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000206 asn1p_value_t *v = calloc(1, sizeof *v);
207 if(v) {
208 v->value.v_integer = i;
209 v->type = ATV_INTEGER;
210 }
211 return v;
212}
213
214asn1p_value_t *
Lev Walkina9532f42006-09-17 04:52:50 +0000215asn1p_value_fromtype(asn1p_expr_t *expr) {
216 asn1p_value_t *v = calloc(1, sizeof *v);
217 if(v) {
218 v->value.v_type = expr;
219 v->type = ATV_TYPE;
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800220 expr->ref_cnt++;
Lev Walkina9532f42006-09-17 04:52:50 +0000221 }
222 return v;
223}
224
225asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000226asn1p_value_clone(asn1p_value_t *v) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000227 return asn1p_value_clone_with_resolver(v, 0, 0);
228}
229
230asn1p_value_t *
231asn1p_value_clone_with_resolver(asn1p_value_t *v,
232 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
233 void *rarg) {
Lev Walkin9c974182004-09-15 11:59:51 +0000234 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000235 if(v) {
236 switch(v->type) {
237 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000238 case ATV_NULL:
239 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000240 case ATV_REAL:
241 return asn1p_value_fromdouble(v->value.v_double);
Lev Walkina9532f42006-09-17 04:52:50 +0000242 case ATV_TYPE:
243 return asn1p_value_fromtype(v->value.v_type);
Lev Walkinf15320b2004-06-03 03:38:44 +0000244 case ATV_INTEGER:
245 case ATV_MIN:
246 case ATV_MAX:
247 case ATV_FALSE:
248 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000249 case ATV_TUPLE:
250 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000251 clone = asn1p_value_fromint(v->value.v_integer);
252 if(clone) clone->type = v->type;
253 return clone;
254 case ATV_STRING:
Lev Walkin84fbd722005-06-15 18:41:50 +0000255 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000256 v->value.string.size, 1);
257 if(clone) clone->type = v->type;
258 return clone;
259 case ATV_UNPARSED:
Lev Walkin84fbd722005-06-15 18:41:50 +0000260 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000261 v->value.string.size, 1);
262 if(clone) clone->type = ATV_UNPARSED;
263 return clone;
264 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000265 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000266 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000267 case ATV_REFERENCED:
Lev Walkina00d6b32006-03-21 03:40:38 +0000268 if(resolver) {
269 clone = resolver(v, rarg);
270 if(clone) return clone;
271 else if(errno != ESRCH) return NULL;
272 }
Lev Walkin9c974182004-09-15 11:59:51 +0000273 return asn1p_value_fromref(v->value.reference, 1);
Lev Walkin5045dfa2006-03-21 09:41:28 +0000274 case ATV_VALUESET:
275 if(resolver) {
276 clone = resolver(v, rarg);
277 if(clone) return clone;
278 else if(errno != ESRCH) return NULL;
279 }
280 return asn1p_value_fromconstr(v->value.constraint, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000281 case ATV_CHOICE_IDENTIFIER: {
282 char *id = v->value.choice_identifier.identifier;
283 clone = calloc(1, sizeof(*clone));
284 if(!clone) return NULL;
285 clone->type = v->type;
286 id = strdup(id);
287 if(!id) { asn1p_value_free(clone); return NULL; }
288 clone->value.choice_identifier.identifier = id;
289 v = asn1p_value_clone(v->value.choice_identifier.value);
290 if(!v) { asn1p_value_free(clone); return NULL; }
291 clone->value.choice_identifier.value = v;
292 return clone;
293 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000294 }
Lev Walkin9c974182004-09-15 11:59:51 +0000295
296 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000297 }
298 return v;
299}
300
301void
302asn1p_value_free(asn1p_value_t *v) {
303 if(v) {
304 switch(v->type) {
305 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000306 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000307 break;
Lev Walkina9532f42006-09-17 04:52:50 +0000308 case ATV_TYPE:
309 asn1p_expr_free(v->value.v_type);
310 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000311 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000312 case ATV_INTEGER:
313 case ATV_MIN:
314 case ATV_MAX:
315 case ATV_FALSE:
316 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000317 case ATV_TUPLE:
318 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000319 /* No freeing necessary */
320 break;
321 case ATV_STRING:
322 case ATV_UNPARSED:
323 assert(v->value.string.buf);
324 free(v->value.string.buf);
325 break;
326 case ATV_BITVECTOR:
327 assert(v->value.binary_vector.bits);
328 free(v->value.binary_vector.bits);
329 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000330 case ATV_REFERENCED:
331 asn1p_ref_free(v->value.reference);
332 break;
Lev Walkin5045dfa2006-03-21 09:41:28 +0000333 case ATV_VALUESET:
334 asn1p_constraint_free(v->value.constraint);
335 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000336 case ATV_CHOICE_IDENTIFIER:
337 free(v->value.choice_identifier.identifier);
338 asn1p_value_free(v->value.choice_identifier.value);
339 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000340 }
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800341 memset(v, 0, sizeof(*v));
Lev Walkinf15320b2004-06-03 03:38:44 +0000342 free(v);
343 }
344}
345