blob: d6d30077602aaeb98d74580c2538d212ab2df045 [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 *
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 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:
Lev Walkin1e448d32005-03-24 14:26:38 +0000126 case ATV_TUPLE:
127 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000128 clone = asn1p_value_fromint(v->value.v_integer);
129 if(clone) clone->type = v->type;
130 return clone;
131 case ATV_STRING:
132 clone = asn1p_value_frombuf(v->value.string.buf,
133 v->value.string.size, 1);
134 if(clone) clone->type = v->type;
135 return clone;
136 case ATV_UNPARSED:
137 clone = asn1p_value_frombuf(v->value.string.buf,
138 v->value.string.size, 1);
139 if(clone) clone->type = ATV_UNPARSED;
140 return clone;
141 case ATV_BITVECTOR:
Lev Walkin774ee7e2005-04-13 12:47:35 +0000142 return asn1p_value_frombits(v->value.binary_vector.bits,
Lev Walkinf15320b2004-06-03 03:38:44 +0000143 v->value.binary_vector.size_in_bits, 1);
Lev Walkin9c974182004-09-15 11:59:51 +0000144 case ATV_REFERENCED:
145 return asn1p_value_fromref(v->value.reference, 1);
146 case ATV_CHOICE_IDENTIFIER: {
147 char *id = v->value.choice_identifier.identifier;
148 clone = calloc(1, sizeof(*clone));
149 if(!clone) return NULL;
150 clone->type = v->type;
151 id = strdup(id);
152 if(!id) { asn1p_value_free(clone); return NULL; }
153 clone->value.choice_identifier.identifier = id;
154 v = asn1p_value_clone(v->value.choice_identifier.value);
155 if(!v) { asn1p_value_free(clone); return NULL; }
156 clone->value.choice_identifier.value = v;
157 return clone;
158 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000159 }
Lev Walkin9c974182004-09-15 11:59:51 +0000160
161 assert(!"UNREACHABLE");
Lev Walkinf15320b2004-06-03 03:38:44 +0000162 }
163 return v;
164}
165
166void
167asn1p_value_free(asn1p_value_t *v) {
168 if(v) {
169 switch(v->type) {
170 case ATV_NOVALUE:
Lev Walkin9c974182004-09-15 11:59:51 +0000171 case ATV_NULL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000172 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000173 case ATV_REAL:
Lev Walkinf15320b2004-06-03 03:38:44 +0000174 case ATV_INTEGER:
175 case ATV_MIN:
176 case ATV_MAX:
177 case ATV_FALSE:
178 case ATV_TRUE:
Lev Walkin1e448d32005-03-24 14:26:38 +0000179 case ATV_TUPLE:
180 case ATV_QUADRUPLE:
Lev Walkinf15320b2004-06-03 03:38:44 +0000181 /* No freeing necessary */
182 break;
183 case ATV_STRING:
184 case ATV_UNPARSED:
185 assert(v->value.string.buf);
186 free(v->value.string.buf);
187 break;
188 case ATV_BITVECTOR:
189 assert(v->value.binary_vector.bits);
190 free(v->value.binary_vector.bits);
191 break;
Lev Walkin9c974182004-09-15 11:59:51 +0000192 case ATV_REFERENCED:
193 asn1p_ref_free(v->value.reference);
194 break;
195 case ATV_CHOICE_IDENTIFIER:
196 free(v->value.choice_identifier.identifier);
197 asn1p_value_free(v->value.choice_identifier.value);
198 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000199 }
200 free(v);
201 }
202}
203