blob: fa3c1f49623cb8b9d2a8f198ab3c287108df9654 [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}
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080086
Lev Walkinf15320b2004-06-03 03:38:44 +000087asn1p_value_t *
88asn1p_value_frombuf(char *buffer, int size, int do_copy) {
89 if(buffer) {
90 asn1p_value_t *v = calloc(1, sizeof *v);
91 assert(size >= 0);
92 if(v) {
93 if(do_copy) {
94 void *p = malloc(size + 1);
95 if(p) {
96 memcpy(p, buffer, size);
97 ((char *)p)[size] = '\0'; /* JIC */
98 } else {
99 free(v);
100 return NULL;
101 }
102 v->value.string.buf = p;
103 } else {
Lev Walkin84fbd722005-06-15 18:41:50 +0000104 v->value.string.buf = (uint8_t *)buffer;
Lev Walkinf15320b2004-06-03 03:38:44 +0000105 }
106 v->value.string.size = size;
107 v->type = ATV_STRING;
108 }
109 return v;
110 } else {
111 errno = EINVAL;
112 return NULL;
113 }
114}
115
116asn1p_value_t *
117asn1p_value_fromdouble(double d) {
118 asn1p_value_t *v = calloc(1, sizeof *v);
119 if(v) {
120 v->value.v_double = d;
121 v->type = ATV_REAL;
122 }
123 return v;
124}
125
126asn1p_value_t *
Lev Walkind21c5052004-09-29 13:18:09 +0000127asn1p_value_fromint(asn1c_integer_t i) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000128 asn1p_value_t *v = calloc(1, sizeof *v);
129 if(v) {
130 v->value.v_integer = i;
131 v->type = ATV_INTEGER;
132 }
133 return v;
134}
135
136asn1p_value_t *
Lev Walkina9532f42006-09-17 04:52:50 +0000137asn1p_value_fromtype(asn1p_expr_t *expr) {
138 asn1p_value_t *v = calloc(1, sizeof *v);
139 if(v) {
140 v->value.v_type = expr;
141 v->type = ATV_TYPE;
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800142 expr->ref_cnt++;
Lev Walkina9532f42006-09-17 04:52:50 +0000143 }
144 return v;
145}
146
147asn1p_value_t *
Lev Walkinf15320b2004-06-03 03:38:44 +0000148asn1p_value_clone(asn1p_value_t *v) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000149 return asn1p_value_clone_with_resolver(v, 0, 0);
150}
151
152asn1p_value_t *
153asn1p_value_clone_with_resolver(asn1p_value_t *v,
154 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
155 void *rarg) {
Lev Walkin9c974182004-09-15 11:59:51 +0000156 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000157 if(v) {
158 switch(v->type) {
159 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000160 case ATV_NULL:
161 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000162 case ATV_REAL:
163 return asn1p_value_fromdouble(v->value.v_double);
Lev Walkina9532f42006-09-17 04:52:50 +0000164 case ATV_TYPE:
165 return asn1p_value_fromtype(v->value.v_type);
Lev Walkinf15320b2004-06-03 03:38:44 +0000166 case ATV_INTEGER:
167 case ATV_MIN:
168 case ATV_MAX:
169 case ATV_FALSE:
170 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000171 case ATV_TUPLE:
172 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000173 clone = asn1p_value_fromint(v->value.v_integer);
174 if(clone) clone->type = v->type;
175 return clone;
176 case ATV_STRING:
Lev Walkin84fbd722005-06-15 18:41:50 +0000177 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000178 v->value.string.size, 1);
179 if(clone) clone->type = v->type;
180 return clone;
181 case ATV_UNPARSED:
Lev Walkin84fbd722005-06-15 18:41:50 +0000182 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000183 v->value.string.size, 1);
184 if(clone) clone->type = ATV_UNPARSED;
185 return clone;
186 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000187 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000188 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000189 case ATV_REFERENCED:
Lev Walkina00d6b32006-03-21 03:40:38 +0000190 if(resolver) {
191 clone = resolver(v, rarg);
192 if(clone) return clone;
193 else if(errno != ESRCH) return NULL;
194 }
Lev Walkin9c974182004-09-15 11:59:51 +0000195 return asn1p_value_fromref(v->value.reference, 1);
Lev Walkin5045dfa2006-03-21 09:41:28 +0000196 case ATV_VALUESET:
197 if(resolver) {
198 clone = resolver(v, rarg);
199 if(clone) return clone;
200 else if(errno != ESRCH) return NULL;
201 }
202 return asn1p_value_fromconstr(v->value.constraint, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000203 case ATV_CHOICE_IDENTIFIER: {
204 char *id = v->value.choice_identifier.identifier;
205 clone = calloc(1, sizeof(*clone));
206 if(!clone) return NULL;
207 clone->type = v->type;
208 id = strdup(id);
209 if(!id) { asn1p_value_free(clone); return NULL; }
210 clone->value.choice_identifier.identifier = id;
211 v = asn1p_value_clone(v->value.choice_identifier.value);
212 if(!v) { asn1p_value_free(clone); return NULL; }
213 clone->value.choice_identifier.value = v;
214 return clone;
215 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000216 }
Lev Walkin9c974182004-09-15 11:59:51 +0000217
218 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000219 }
220 return v;
221}
222
223void
224asn1p_value_free(asn1p_value_t *v) {
225 if(v) {
226 switch(v->type) {
227 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000228 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000229 break;
Lev Walkina9532f42006-09-17 04:52:50 +0000230 case ATV_TYPE:
231 asn1p_expr_free(v->value.v_type);
232 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000233 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000234 case ATV_INTEGER:
235 case ATV_MIN:
236 case ATV_MAX:
237 case ATV_FALSE:
238 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000239 case ATV_TUPLE:
240 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000241 /* No freeing necessary */
242 break;
243 case ATV_STRING:
244 case ATV_UNPARSED:
245 assert(v->value.string.buf);
246 free(v->value.string.buf);
247 break;
248 case ATV_BITVECTOR:
249 assert(v->value.binary_vector.bits);
250 free(v->value.binary_vector.bits);
251 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000252 case ATV_REFERENCED:
253 asn1p_ref_free(v->value.reference);
254 break;
Lev Walkin5045dfa2006-03-21 09:41:28 +0000255 case ATV_VALUESET:
256 asn1p_constraint_free(v->value.constraint);
257 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000258 case ATV_CHOICE_IDENTIFIER:
259 free(v->value.choice_identifier.identifier);
260 asn1p_value_free(v->value.choice_identifier.value);
261 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000262 }
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800263 memset(v, 0, sizeof(*v));
Lev Walkinf15320b2004-06-03 03:38:44 +0000264 free(v);
265 }
266}
267