blob: 0c89888000e354d8097085ca506eafb452116ac7 [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;
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800141 expr->ref_cnt++;
Lev Walkina9532f42006-09-17 04:52:50 +0000142 }
143 return v;
144}
145
146asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000147asn1p_value_clone(asn1p_value_t *v) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000148 return asn1p_value_clone_with_resolver(v, 0, 0);
149}
150
151asn1p_value_t *
152asn1p_value_clone_with_resolver(asn1p_value_t *v,
153 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
154 void *rarg) {
Lev Walkin9c974182004-09-15 11:59:51 +0000155 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000156 if(v) {
157 switch(v->type) {
158 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000159 case ATV_NULL:
160 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000161 case ATV_REAL:
162 return asn1p_value_fromdouble(v->value.v_double);
Lev Walkina9532f42006-09-17 04:52:50 +0000163 case ATV_TYPE:
164 return asn1p_value_fromtype(v->value.v_type);
Lev Walkinf15320b2004-06-03 03:38:44 +0000165 case ATV_INTEGER:
166 case ATV_MIN:
167 case ATV_MAX:
168 case ATV_FALSE:
169 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000170 case ATV_TUPLE:
171 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000172 clone = asn1p_value_fromint(v->value.v_integer);
173 if(clone) clone->type = v->type;
174 return clone;
175 case ATV_STRING:
Lev Walkin84fbd722005-06-15 18:41:50 +0000176 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000177 v->value.string.size, 1);
178 if(clone) clone->type = v->type;
179 return clone;
180 case ATV_UNPARSED:
Lev Walkin84fbd722005-06-15 18:41:50 +0000181 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000182 v->value.string.size, 1);
183 if(clone) clone->type = ATV_UNPARSED;
184 return clone;
185 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000186 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000187 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000188 case ATV_REFERENCED:
Lev Walkina00d6b32006-03-21 03:40:38 +0000189 if(resolver) {
190 clone = resolver(v, rarg);
191 if(clone) return clone;
192 else if(errno != ESRCH) return NULL;
193 }
Lev Walkin9c974182004-09-15 11:59:51 +0000194 return asn1p_value_fromref(v->value.reference, 1);
Lev Walkin5045dfa2006-03-21 09:41:28 +0000195 case ATV_VALUESET:
196 if(resolver) {
197 clone = resolver(v, rarg);
198 if(clone) return clone;
199 else if(errno != ESRCH) return NULL;
200 }
201 return asn1p_value_fromconstr(v->value.constraint, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000202 case ATV_CHOICE_IDENTIFIER: {
203 char *id = v->value.choice_identifier.identifier;
204 clone = calloc(1, sizeof(*clone));
205 if(!clone) return NULL;
206 clone->type = v->type;
207 id = strdup(id);
208 if(!id) { asn1p_value_free(clone); return NULL; }
209 clone->value.choice_identifier.identifier = id;
210 v = asn1p_value_clone(v->value.choice_identifier.value);
211 if(!v) { asn1p_value_free(clone); return NULL; }
212 clone->value.choice_identifier.value = v;
213 return clone;
214 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000215 }
Lev Walkin9c974182004-09-15 11:59:51 +0000216
217 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000218 }
219 return v;
220}
221
222void
223asn1p_value_free(asn1p_value_t *v) {
224 if(v) {
225 switch(v->type) {
226 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000227 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000228 break;
Lev Walkina9532f42006-09-17 04:52:50 +0000229 case ATV_TYPE:
230 asn1p_expr_free(v->value.v_type);
231 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000232 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000233 case ATV_INTEGER:
234 case ATV_MIN:
235 case ATV_MAX:
236 case ATV_FALSE:
237 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000238 case ATV_TUPLE:
239 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000240 /* No freeing necessary */
241 break;
242 case ATV_STRING:
243 case ATV_UNPARSED:
244 assert(v->value.string.buf);
245 free(v->value.string.buf);
246 break;
247 case ATV_BITVECTOR:
248 assert(v->value.binary_vector.bits);
249 free(v->value.binary_vector.bits);
250 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000251 case ATV_REFERENCED:
252 asn1p_ref_free(v->value.reference);
253 break;
Lev Walkin5045dfa2006-03-21 09:41:28 +0000254 case ATV_VALUESET:
255 asn1p_constraint_free(v->value.constraint);
256 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000257 case ATV_CHOICE_IDENTIFIER:
258 free(v->value.choice_identifier.identifier);
259 asn1p_value_free(v->value.choice_identifier.value);
260 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000261 }
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800262 memset(v, 0, sizeof(*v));
Lev Walkinf15320b2004-06-03 03:38:44 +0000263 free(v);
264 }
265}
266