blob: b38240977d22b71fa0c9d6c78bd62e91cbb498c2 [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 {
79 v->value.string.buf = buffer;
80 }
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 *
102asn1p_value_fromint(asn1_integer_t i) {
103 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 Walkin9c974182004-09-15 11:59:51 +0000113 asn1p_value_t *clone = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000114 if(v) {
115 switch(v->type) {
116 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000117 case ATV_NULL:
118 return calloc(1, sizeof(*clone));
Lev Walkinf15320b2004-06-03 03:38:44 +0000119 case ATV_REAL:
120 return asn1p_value_fromdouble(v->value.v_double);
121 case ATV_INTEGER:
122 case ATV_MIN:
123 case ATV_MAX:
124 case ATV_FALSE:
125 case ATV_TRUE:
126 clone = asn1p_value_fromint(v->value.v_integer);
127 if(clone) clone->type = v->type;
128 return clone;
129 case ATV_STRING:
130 clone = asn1p_value_frombuf(v->value.string.buf,
131 v->value.string.size, 1);
132 if(clone) clone->type = v->type;
133 return clone;
134 case ATV_UNPARSED:
135 clone = asn1p_value_frombuf(v->value.string.buf,
136 v->value.string.size, 1);
137 if(clone) clone->type = ATV_UNPARSED;
138 return clone;
139 case ATV_BITVECTOR:
140 return asn1p_value_frombuf(v->value.binary_vector.bits,
141 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000142 case ATV_REFERENCED:
143 return asn1p_value_fromref(v->value.reference, 1);
144 case ATV_CHOICE_IDENTIFIER: {
145 char *id = v->value.choice_identifier.identifier;
146 clone = calloc(1, sizeof(*clone));
147 if(!clone) return NULL;
148 clone->type = v->type;
149 id = strdup(id);
150 if(!id) { asn1p_value_free(clone); return NULL; }
151 clone->value.choice_identifier.identifier = id;
152 v = asn1p_value_clone(v->value.choice_identifier.value);
153 if(!v) { asn1p_value_free(clone); return NULL; }
154 clone->value.choice_identifier.value = v;
155 return clone;
156 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000157 }
Lev Walkin9c974182004-09-15 11:59:51 +0000158
159 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000160 }
161 return v;
162}
163
164void
165asn1p_value_free(asn1p_value_t *v) {
166 if(v) {
167 switch(v->type) {
168 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000169 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000170 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000171 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000172 case ATV_INTEGER:
173 case ATV_MIN:
174 case ATV_MAX:
175 case ATV_FALSE:
176 case ATV_TRUE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000177 /* No freeing necessary */
178 break;
179 case ATV_STRING:
180 case ATV_UNPARSED:
181 assert(v->value.string.buf);
182 free(v->value.string.buf);
183 break;
184 case ATV_BITVECTOR:
185 assert(v->value.binary_vector.bits);
186 free(v->value.binary_vector.bits);
187 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000188 case ATV_REFERENCED:
189 asn1p_ref_free(v->value.reference);
190 break;
191 case ATV_CHOICE_IDENTIFIER:
192 free(v->value.choice_identifier.identifier);
193 asn1p_value_free(v->value.choice_identifier.value);
194 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000195 }
196 free(v);
197 }
198}
199