blob: 63c80c7e923a1999bc78bf99274872156c151576 [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"
7
8
9asn1p_value_t *
10asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) {
11 if(ref) {
12 asn1p_value_t *v = calloc(1, sizeof *v);
13 if(v) {
14 if(do_copy) {
15 v->value.reference = asn1p_ref_clone(ref);
16 if(v->value.reference == NULL) {
17 free(v);
18 return NULL;
19 }
20 } else {
21 v->value.reference = ref;
22 }
23 v->type = ATV_REFERENCED;
24 }
25 return v;
26 } else {
27 errno = EINVAL;
28 return NULL;
29 }
30}
31
32asn1p_value_t *
Lev Walkin5045dfa2006-03-21 09:41:28 +000033asn1p_value_fromconstr(asn1p_constraint_t *ct, int do_copy) {
34 if(ct) {
35 asn1p_value_t *v = calloc(1, sizeof *v);
36 if(v) {
37 if(do_copy) {
38 v->value.constraint
39 = asn1p_constraint_clone(ct);
40 if(v->value.constraint == NULL) {
41 free(v);
42 return NULL;
43 }
44 } else {
45 v->value.constraint = ct;
46 }
47 v->type = ATV_VALUESET;
48 }
49 return v;
50 } else {
51 errno = EINVAL;
52 return NULL;
53 }
54}
55
56asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +000057asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
58 if(bits) {
59 asn1p_value_t *v = calloc(1, sizeof *v);
60 assert(size_in_bits >= 0);
61 if(v) {
62 if(do_copy) {
63 int size = ((size_in_bits + 7) >> 3);
64 void *p;
65 p = malloc(size + 1);
66 if(p) {
67 memcpy(p, bits, size);
68 ((char *)p)[size] = '\0'; /* JIC */
69 } else {
70 free(v);
71 return NULL;
72 }
73 v->value.binary_vector.bits = p;
74 } else {
75 v->value.binary_vector.bits = (void *)bits;
76 }
77 v->value.binary_vector.size_in_bits = size_in_bits;
78 v->type = ATV_BITVECTOR;
79 }
80 return v;
81 } else {
82 errno = EINVAL;
83 return NULL;
84 }
85}
86asn1p_value_t *
87asn1p_value_frombuf(char *buffer, int size, int do_copy) {
88 if(buffer) {
89 asn1p_value_t *v = calloc(1, sizeof *v);
90 assert(size >= 0);
91 if(v) {
92 if(do_copy) {
93 void *p = malloc(size + 1);
94 if(p) {
95 memcpy(p, buffer, size);
96 ((char *)p)[size] = '\0'; /* JIC */
97 } else {
98 free(v);
99 return NULL;
100 }
101 v->value.string.buf = p;
102 } else {
Lev Walkin84fbd722005-06-15 18:41:50 +0000103 v->value.string.buf = (uint8_t *)buffer;
Lev Walkinf15320b2004-06-03 03:38:44 +0000104 }
105 v->value.string.size = size;
106 v->type = ATV_STRING;
107 }
108 return v;
109 } else {
110 errno = EINVAL;
111 return NULL;
112 }
113}
114
115asn1p_value_t *
116asn1p_value_fromdouble(double d) {
117 asn1p_value_t *v = calloc(1, sizeof *v);
118 if(v) {
119 v->value.v_double = d;
120 v->type = ATV_REAL;
121 }
122 return v;
123}
124
125asn1p_value_t *
Lev Walkind21c5052004-09-29 13:18:09 +0000126asn1p_value_fromint(asn1c_integer_t i) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000127 asn1p_value_t *v = calloc(1, sizeof *v);
128 if(v) {
129 v->value.v_integer = i;
130 v->type = ATV_INTEGER;
131 }
132 return v;
133}
134
135asn1p_value_t *
Lev Walkina9532f42006-09-17 04:52:50 +0000136asn1p_value_fromtype(asn1p_expr_t *expr) {
137 asn1p_value_t *v = calloc(1, sizeof *v);
138 if(v) {
139 v->value.v_type = expr;
140 v->type = ATV_TYPE;
141 }
142 return v;
143}
144
145asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000146asn1p_value_clone(asn1p_value_t *v) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000147 return asn1p_value_clone_with_resolver(v, 0, 0);
148}
149
150asn1p_value_t *
151asn1p_value_clone_with_resolver(asn1p_value_t *v,
152 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
153 void *rarg) {
Lev Walkin9c974182004-09-15 11:59:51 +0000154 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000155 if(v) {
156 switch(v->type) {
157 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000158 case ATV_NULL:
159 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000160 case ATV_REAL:
161 return asn1p_value_fromdouble(v->value.v_double);
Lev Walkina9532f42006-09-17 04:52:50 +0000162 case ATV_TYPE:
163 return asn1p_value_fromtype(v->value.v_type);
Lev Walkinf15320b2004-06-03 03:38:44 +0000164 case ATV_INTEGER:
165 case ATV_MIN:
166 case ATV_MAX:
167 case ATV_FALSE:
168 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000169 case ATV_TUPLE:
170 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000171 clone = asn1p_value_fromint(v->value.v_integer);
172 if(clone) clone->type = v->type;
173 return clone;
174 case ATV_STRING:
Lev Walkin84fbd722005-06-15 18:41:50 +0000175 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000176 v->value.string.size, 1);
177 if(clone) clone->type = v->type;
178 return clone;
179 case ATV_UNPARSED:
Lev Walkin84fbd722005-06-15 18:41:50 +0000180 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000181 v->value.string.size, 1);
182 if(clone) clone->type = ATV_UNPARSED;
183 return clone;
184 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000185 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000186 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000187 case ATV_REFERENCED:
Lev Walkina00d6b32006-03-21 03:40:38 +0000188 if(resolver) {
189 clone = resolver(v, rarg);
190 if(clone) return clone;
191 else if(errno != ESRCH) return NULL;
192 }
Lev Walkin9c974182004-09-15 11:59:51 +0000193 return asn1p_value_fromref(v->value.reference, 1);
Lev Walkin5045dfa2006-03-21 09:41:28 +0000194 case ATV_VALUESET:
195 if(resolver) {
196 clone = resolver(v, rarg);
197 if(clone) return clone;
198 else if(errno != ESRCH) return NULL;
199 }
200 return asn1p_value_fromconstr(v->value.constraint, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000201 case ATV_CHOICE_IDENTIFIER: {
202 char *id = v->value.choice_identifier.identifier;
203 clone = calloc(1, sizeof(*clone));
204 if(!clone) return NULL;
205 clone->type = v->type;
206 id = strdup(id);
207 if(!id) { asn1p_value_free(clone); return NULL; }
208 clone->value.choice_identifier.identifier = id;
209 v = asn1p_value_clone(v->value.choice_identifier.value);
210 if(!v) { asn1p_value_free(clone); return NULL; }
211 clone->value.choice_identifier.value = v;
212 return clone;
213 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000214 }
Lev Walkin9c974182004-09-15 11:59:51 +0000215
216 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000217 }
218 return v;
219}
220
221void
222asn1p_value_free(asn1p_value_t *v) {
223 if(v) {
224 switch(v->type) {
225 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000226 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000227 break;
Lev Walkina9532f42006-09-17 04:52:50 +0000228 case ATV_TYPE:
229 asn1p_expr_free(v->value.v_type);
230 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000231 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000232 case ATV_INTEGER:
233 case ATV_MIN:
234 case ATV_MAX:
235 case ATV_FALSE:
236 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000237 case ATV_TUPLE:
238 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000239 /* No freeing necessary */
240 break;
241 case ATV_STRING:
242 case ATV_UNPARSED:
243 assert(v->value.string.buf);
244 free(v->value.string.buf);
245 break;
246 case ATV_BITVECTOR:
247 assert(v->value.binary_vector.bits);
248 free(v->value.binary_vector.bits);
249 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000250 case ATV_REFERENCED:
251 asn1p_ref_free(v->value.reference);
252 break;
Lev Walkin5045dfa2006-03-21 09:41:28 +0000253 case ATV_VALUESET:
254 asn1p_constraint_free(v->value.constraint);
255 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000256 case ATV_CHOICE_IDENTIFIER:
257 free(v->value.choice_identifier.identifier);
258 asn1p_value_free(v->value.choice_identifier.value);
259 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000260 }
261 free(v);
262 }
263}
264