blob: 6686e497962df592074a6b4fbf4b94baab54882e [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 *
33asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
34 if(bits) {
35 asn1p_value_t *v = calloc(1, sizeof *v);
36 assert(size_in_bits >= 0);
37 if(v) {
38 if(do_copy) {
39 int size = ((size_in_bits + 7) >> 3);
40 void *p;
41 p = malloc(size + 1);
42 if(p) {
43 memcpy(p, bits, size);
44 ((char *)p)[size] = '\0'; /* JIC */
45 } else {
46 free(v);
47 return NULL;
48 }
49 v->value.binary_vector.bits = p;
50 } else {
51 v->value.binary_vector.bits = (void *)bits;
52 }
53 v->value.binary_vector.size_in_bits = size_in_bits;
54 v->type = ATV_BITVECTOR;
55 }
56 return v;
57 } else {
58 errno = EINVAL;
59 return NULL;
60 }
61}
62asn1p_value_t *
63asn1p_value_frombuf(char *buffer, int size, int do_copy) {
64 if(buffer) {
65 asn1p_value_t *v = calloc(1, sizeof *v);
66 assert(size >= 0);
67 if(v) {
68 if(do_copy) {
69 void *p = malloc(size + 1);
70 if(p) {
71 memcpy(p, buffer, size);
72 ((char *)p)[size] = '\0'; /* JIC */
73 } else {
74 free(v);
75 return NULL;
76 }
77 v->value.string.buf = p;
78 } else {
Lev Walkin84fbd722005-06-15 18:41:50 +000079 v->value.string.buf = (uint8_t *)buffer;
Lev Walkinf15320b2004-06-03 03:38:44 +000080 }
81 v->value.string.size = size;
82 v->type = ATV_STRING;
83 }
84 return v;
85 } else {
86 errno = EINVAL;
87 return NULL;
88 }
89}
90
91asn1p_value_t *
92asn1p_value_fromdouble(double d) {
93 asn1p_value_t *v = calloc(1, sizeof *v);
94 if(v) {
95 v->value.v_double = d;
96 v->type = ATV_REAL;
97 }
98 return v;
99}
100
101asn1p_value_t *
Lev Walkind21c5052004-09-29 13:18:09 +0000102asn1p_value_fromint(asn1c_integer_t i) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000103 asn1p_value_t *v = calloc(1, sizeof *v);
104 if(v) {
105 v->value.v_integer = i;
106 v->type = ATV_INTEGER;
107 }
108 return v;
109}
110
111asn1p_value_t *
112asn1p_value_clone(asn1p_value_t *v) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000113 return asn1p_value_clone_with_resolver(v, 0, 0);
114}
115
116asn1p_value_t *
117asn1p_value_clone_with_resolver(asn1p_value_t *v,
118 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
119 void *rarg) {
Lev Walkin9c974182004-09-15 11:59:51 +0000120 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000121 if(v) {
122 switch(v->type) {
123 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000124 case ATV_NULL:
125 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000126 case ATV_REAL:
127 return asn1p_value_fromdouble(v->value.v_double);
128 case ATV_INTEGER:
129 case ATV_MIN:
130 case ATV_MAX:
131 case ATV_FALSE:
132 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000133 case ATV_TUPLE:
134 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000135 clone = asn1p_value_fromint(v->value.v_integer);
136 if(clone) clone->type = v->type;
137 return clone;
138 case ATV_STRING:
Lev Walkin84fbd722005-06-15 18:41:50 +0000139 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000140 v->value.string.size, 1);
141 if(clone) clone->type = v->type;
142 return clone;
143 case ATV_UNPARSED:
Lev Walkin84fbd722005-06-15 18:41:50 +0000144 clone = asn1p_value_frombuf((char *)v->value.string.buf,
Lev Walkinf15320b2004-06-03 03:38:44 +0000145 v->value.string.size, 1);
146 if(clone) clone->type = ATV_UNPARSED;
147 return clone;
148 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000149 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000150 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000151 case ATV_REFERENCED:
Lev Walkina00d6b32006-03-21 03:40:38 +0000152 if(resolver) {
153 clone = resolver(v, rarg);
154 if(clone) return clone;
155 else if(errno != ESRCH) return NULL;
156 }
Lev Walkin9c974182004-09-15 11:59:51 +0000157 return asn1p_value_fromref(v->value.reference, 1);
158 case ATV_CHOICE_IDENTIFIER: {
159 char *id = v->value.choice_identifier.identifier;
160 clone = calloc(1, sizeof(*clone));
161 if(!clone) return NULL;
162 clone->type = v->type;
163 id = strdup(id);
164 if(!id) { asn1p_value_free(clone); return NULL; }
165 clone->value.choice_identifier.identifier = id;
166 v = asn1p_value_clone(v->value.choice_identifier.value);
167 if(!v) { asn1p_value_free(clone); return NULL; }
168 clone->value.choice_identifier.value = v;
169 return clone;
170 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000171 }
Lev Walkin9c974182004-09-15 11:59:51 +0000172
173 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000174 }
175 return v;
176}
177
178void
179asn1p_value_free(asn1p_value_t *v) {
180 if(v) {
181 switch(v->type) {
182 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000183 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000184 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000185 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000186 case ATV_INTEGER:
187 case ATV_MIN:
188 case ATV_MAX:
189 case ATV_FALSE:
190 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000191 case ATV_TUPLE:
192 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000193 /* No freeing necessary */
194 break;
195 case ATV_STRING:
196 case ATV_UNPARSED:
197 assert(v->value.string.buf);
198 free(v->value.string.buf);
199 break;
200 case ATV_BITVECTOR:
201 assert(v->value.binary_vector.bits);
202 free(v->value.binary_vector.bits);
203 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000204 case ATV_REFERENCED:
205 asn1p_ref_free(v->value.reference);
206 break;
207 case ATV_CHOICE_IDENTIFIER:
208 free(v->value.choice_identifier.identifier);
209 asn1p_value_free(v->value.choice_identifier.value);
210 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000211 }
212 free(v);
213 }
214}
215