blob: cafc1f936be969f391b938642c2259141f9ba614 [file] [log] [blame]
vlmfa67ddc2004-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 *
vlmdfbff8c2006-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 *
vlmfa67ddc2004-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 {
vlm55289c12005-06-15 18:41:50 +0000103 v->value.string.buf = (uint8_t *)buffer;
vlmfa67ddc2004-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 *
vlmec6acd42004-09-29 13:18:09 +0000126asn1p_value_fromint(asn1c_integer_t i) {
vlmfa67ddc2004-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 *
136asn1p_value_clone(asn1p_value_t *v) {
vlm0c6d3812006-03-21 03:40:38 +0000137 return asn1p_value_clone_with_resolver(v, 0, 0);
138}
139
140asn1p_value_t *
141asn1p_value_clone_with_resolver(asn1p_value_t *v,
142 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
143 void *rarg) {
vlmc94e28f2004-09-15 11:59:51 +0000144 asn1p_value_t *clone = NULL;
vlmfa67ddc2004-06-03 03:38:44 +0000145 if(v) {
146 switch(v->type) {
147 case ATV_NOVALUE:
vlmc94e28f2004-09-15 11:59:51 +0000148 case ATV_NULL:
149 return calloc(1, sizeof(*clone));
vlmfa67ddc2004-06-03 03:38:44 +0000150 case ATV_REAL:
151 return asn1p_value_fromdouble(v->value.v_double);
152 case ATV_INTEGER:
153 case ATV_MIN:
154 case ATV_MAX:
155 case ATV_FALSE:
156 case ATV_TRUE:
vlme1e6ed82005-03-24 14:26:38 +0000157 case ATV_TUPLE:
158 case ATV_QUADRUPLE:
vlmfa67ddc2004-06-03 03:38:44 +0000159 clone = asn1p_value_fromint(v->value.v_integer);
160 if(clone) clone->type = v->type;
161 return clone;
162 case ATV_STRING:
vlm55289c12005-06-15 18:41:50 +0000163 clone = asn1p_value_frombuf((char *)v->value.string.buf,
vlmfa67ddc2004-06-03 03:38:44 +0000164 v->value.string.size, 1);
165 if(clone) clone->type = v->type;
166 return clone;
167 case ATV_UNPARSED:
vlm55289c12005-06-15 18:41:50 +0000168 clone = asn1p_value_frombuf((char *)v->value.string.buf,
vlmfa67ddc2004-06-03 03:38:44 +0000169 v->value.string.size, 1);
170 if(clone) clone->type = ATV_UNPARSED;
171 return clone;
172 case ATV_BITVECTOR:
vlm938c1042005-04-13 12:47:35 +0000173 return asn1p_value_frombits(v->value.binary_vector.bits,
vlmfa67ddc2004-06-03 03:38:44 +0000174 v->value.binary_vector.size_in_bits, 1);
vlmc94e28f2004-09-15 11:59:51 +0000175 case ATV_REFERENCED:
vlm0c6d3812006-03-21 03:40:38 +0000176 if(resolver) {
177 clone = resolver(v, rarg);
178 if(clone) return clone;
179 else if(errno != ESRCH) return NULL;
180 }
vlmc94e28f2004-09-15 11:59:51 +0000181 return asn1p_value_fromref(v->value.reference, 1);
vlmdfbff8c2006-03-21 09:41:28 +0000182 case ATV_VALUESET:
183 if(resolver) {
184 clone = resolver(v, rarg);
185 if(clone) return clone;
186 else if(errno != ESRCH) return NULL;
187 }
188 return asn1p_value_fromconstr(v->value.constraint, 1);
vlmc94e28f2004-09-15 11:59:51 +0000189 case ATV_CHOICE_IDENTIFIER: {
190 char *id = v->value.choice_identifier.identifier;
191 clone = calloc(1, sizeof(*clone));
192 if(!clone) return NULL;
193 clone->type = v->type;
194 id = strdup(id);
195 if(!id) { asn1p_value_free(clone); return NULL; }
196 clone->value.choice_identifier.identifier = id;
197 v = asn1p_value_clone(v->value.choice_identifier.value);
198 if(!v) { asn1p_value_free(clone); return NULL; }
199 clone->value.choice_identifier.value = v;
200 return clone;
201 }
vlmfa67ddc2004-06-03 03:38:44 +0000202 }
vlmc94e28f2004-09-15 11:59:51 +0000203
204 assert(!"UNREACHABLE");
vlmfa67ddc2004-06-03 03:38:44 +0000205 }
206 return v;
207}
208
209void
210asn1p_value_free(asn1p_value_t *v) {
211 if(v) {
212 switch(v->type) {
213 case ATV_NOVALUE:
vlmc94e28f2004-09-15 11:59:51 +0000214 case ATV_NULL:
vlmfa67ddc2004-06-03 03:38:44 +0000215 break;
vlmc94e28f2004-09-15 11:59:51 +0000216 case ATV_REAL:
vlmfa67ddc2004-06-03 03:38:44 +0000217 case ATV_INTEGER:
218 case ATV_MIN:
219 case ATV_MAX:
220 case ATV_FALSE:
221 case ATV_TRUE:
vlme1e6ed82005-03-24 14:26:38 +0000222 case ATV_TUPLE:
223 case ATV_QUADRUPLE:
vlmfa67ddc2004-06-03 03:38:44 +0000224 /* No freeing necessary */
225 break;
226 case ATV_STRING:
227 case ATV_UNPARSED:
228 assert(v->value.string.buf);
229 free(v->value.string.buf);
230 break;
231 case ATV_BITVECTOR:
232 assert(v->value.binary_vector.bits);
233 free(v->value.binary_vector.bits);
234 break;
vlmc94e28f2004-09-15 11:59:51 +0000235 case ATV_REFERENCED:
236 asn1p_ref_free(v->value.reference);
237 break;
vlmdfbff8c2006-03-21 09:41:28 +0000238 case ATV_VALUESET:
239 asn1p_constraint_free(v->value.constraint);
240 break;
vlmc94e28f2004-09-15 11:59:51 +0000241 case ATV_CHOICE_IDENTIFIER:
242 free(v->value.choice_identifier.identifier);
243 asn1p_value_free(v->value.choice_identifier.value);
244 break;
vlmfa67ddc2004-06-03 03:38:44 +0000245 }
246 free(v);
247 }
248}
249