NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / libasn1parser / asn1p_value.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <assert.h>
5
6 #include "asn1parser.h"
7 #include "asn1p_expr.h"
8
9 void
10 asn1p_value_set_source(asn1p_value_t *value, asn1p_module_t *module,
11                        int lineno) {
12     if(value) {
13         switch(value->type) {
14         case ATV_TYPE:
15             asn1p_expr_set_source(value->value.v_type, module, lineno);
16             break;
17         case ATV_REFERENCED:
18             asn1p_ref_set_source(value->value.reference, module, lineno);
19             break;
20         case ATV_VALUESET:
21             asn1p_constraint_set_source(value->value.constraint, module,
22                                         lineno);
23             break;
24         default:
25             break;
26         }
27     }
28 }
29
30 int
31 asn1p_value_compare(const asn1p_value_t *a, const asn1p_value_t *b) {
32     if(a->type != b->type) {
33         return -1;
34     }
35
36     switch(a->type) {
37     case ATV_NULL:
38     case ATV_NOVALUE:
39     case ATV_MAX:
40     case ATV_MIN:
41     case ATV_FALSE:
42     case ATV_TRUE:
43         break;
44     case ATV_TYPE:
45         return asn1p_expr_compare(a->value.v_type, b->value.v_type);
46     case ATV_REAL:
47         return (a->value.v_double == b->value.v_double) ? 0 : -1;
48     case ATV_INTEGER:
49     case ATV_TUPLE:
50     case ATV_QUADRUPLE:
51         return (a->value.v_integer == b->value.v_integer) ? 0 : -1;
52     case ATV_STRING:
53     case ATV_UNPARSED:
54         if(a->value.string.size != b->value.string.size
55            || memcmp(a->value.string.buf, b->value.string.buf,
56                      a->value.string.size)
57                   != 0) {
58             return -1;
59         }
60         return 0;
61     case ATV_BITVECTOR:
62         if(a->value.binary_vector.size_in_bits
63                != b->value.binary_vector.size_in_bits
64            || memcmp(a->value.binary_vector.bits, b->value.binary_vector.bits,
65                      (a->value.binary_vector.size_in_bits+7) >> 3)
66                   != 0) {
67             return -1;
68         }
69         return 0;
70     case ATV_VALUESET:
71         return asn1p_constraint_compare(a->value.constraint,
72                                         b->value.constraint);
73     case ATV_REFERENCED:
74         return asn1p_ref_compare(a->value.reference, b->value.reference);
75     case ATV_CHOICE_IDENTIFIER:
76         if(strcmp(a->value.choice_identifier.identifier,
77                   b->value.choice_identifier.identifier)
78            != 0) {
79             return -1;
80         }
81         return asn1p_value_compare(a->value.choice_identifier.value,
82                                    b->value.choice_identifier.value);
83     }
84
85     return 0;
86 }
87
88 asn1p_value_t *
89 asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) {
90         if(ref) {
91                 asn1p_value_t *v = calloc(1, sizeof *v);
92                 if(v) {
93                         if(do_copy) {
94                                 v->value.reference = asn1p_ref_clone(ref);
95                                 if(v->value.reference == NULL) {
96                                         free(v);
97                                         return NULL;
98                                 }
99                         } else {
100                                 v->value.reference = ref;
101                         }
102                         v->type = ATV_REFERENCED;
103                 }
104                 return v;
105         } else {
106                 errno = EINVAL;
107                 return NULL;
108         }
109 }
110
111 asn1p_value_t *
112 asn1p_value_fromconstr(asn1p_constraint_t *ct, int do_copy) {
113         if(ct) {
114                 asn1p_value_t *v = calloc(1, sizeof *v);
115                 if(v) {
116                         if(do_copy) {
117                                 v->value.constraint
118                                         = asn1p_constraint_clone(ct);
119                                 if(v->value.constraint == NULL) {
120                                         free(v);
121                                         return NULL;
122                                 }
123                         } else {
124                                 v->value.constraint = ct;
125                         }
126                         v->type = ATV_VALUESET;
127                 }
128                 return v;
129         } else {
130                 errno = EINVAL;
131                 return NULL;
132         }
133 }
134
135 asn1p_value_t *
136 asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
137         if(bits) {
138                 asn1p_value_t *v = calloc(1, sizeof *v);
139                 assert(size_in_bits >= 0);
140                 if(v) {
141                         if(do_copy) {
142                                 int size = ((size_in_bits + 7) >> 3);
143                                 void *p;
144                                 p = malloc(size + 1);
145                                 if(p) {
146                                         memcpy(p, bits, size);
147                                         ((char *)p)[size] = '\0'; /* JIC */
148                                 } else {
149                                         free(v);
150                                         return NULL;
151                                 }
152                                 v->value.binary_vector.bits = p;
153                         } else {
154                                 v->value.binary_vector.bits = (void *)bits;
155                         }
156                         v->value.binary_vector.size_in_bits = size_in_bits;
157                         v->type = ATV_BITVECTOR;
158                 }
159                 return v;
160         } else {
161                 errno = EINVAL;
162                 return NULL;
163         }
164 }
165
166 asn1p_value_t *
167 asn1p_value_frombuf(char *buffer, int size, int do_copy) {
168         if(buffer) {
169                 asn1p_value_t *v = calloc(1, sizeof *v);
170                 assert(size >= 0);
171                 if(v) {
172                         if(do_copy) {
173                                 void *p = malloc(size + 1);
174                                 if(p) {
175                                         memcpy(p, buffer, size);
176                                         ((char *)p)[size] = '\0'; /* JIC */
177                                 } else {
178                                         free(v);
179                                         return NULL;
180                                 }
181                                 v->value.string.buf = p;
182                         } else {
183                                 v->value.string.buf = (uint8_t *)buffer;
184                         }
185                         v->value.string.size = size;
186                         v->type = ATV_STRING;
187                 }
188                 return v;
189         } else {
190                 errno = EINVAL;
191                 return NULL;
192         }
193 }
194
195 asn1p_value_t *
196 asn1p_value_fromdouble(double d) {
197         asn1p_value_t *v = calloc(1, sizeof *v);
198         if(v) {
199                 v->value.v_double = d;
200                 v->type = ATV_REAL;
201         }
202         return v;
203 }
204
205 asn1p_value_t *
206 asn1p_value_fromint(asn1c_integer_t i) {
207         asn1p_value_t *v = calloc(1, sizeof *v);
208         if(v) {
209                 v->value.v_integer = i;
210                 v->type = ATV_INTEGER;
211         }
212         return v;
213 }
214
215 asn1p_value_t *
216 asn1p_value_fromtype(asn1p_expr_t *expr) {
217         asn1p_value_t *v = calloc(1, sizeof *v);
218         if(v) {
219                 v->value.v_type = expr;
220                 v->type = ATV_TYPE;
221                 expr->ref_cnt++;
222         }
223         return v;
224 }
225
226 asn1p_value_t *
227 asn1p_value_clone(asn1p_value_t *v) {
228         return asn1p_value_clone_with_resolver(v, 0, 0);
229 }
230
231 asn1p_value_t *
232 asn1p_value_clone_with_resolver(asn1p_value_t *v,
233                 asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
234                 void *rarg) {
235         asn1p_value_t *clone = NULL;
236         if(v) {
237                 switch(v->type) {
238                 case ATV_NOVALUE:
239                 case ATV_NULL:
240                         return calloc(1, sizeof(*clone));
241                 case ATV_REAL:
242                         return asn1p_value_fromdouble(v->value.v_double);
243                 case ATV_TYPE:
244                         return asn1p_value_fromtype(v->value.v_type);
245                 case ATV_INTEGER:
246                 case ATV_MIN:
247                 case ATV_MAX:
248                 case ATV_FALSE:
249                 case ATV_TRUE:
250                 case ATV_TUPLE:
251                 case ATV_QUADRUPLE:
252                         clone = asn1p_value_fromint(v->value.v_integer);
253                         if(clone) clone->type = v->type;
254                         return clone;
255                 case ATV_STRING:
256                         clone = asn1p_value_frombuf((char *)v->value.string.buf,
257                                 v->value.string.size, 1);
258                         if(clone) clone->type = v->type;
259                         return clone;
260                 case ATV_UNPARSED:
261                         clone = asn1p_value_frombuf((char *)v->value.string.buf,
262                                 v->value.string.size, 1);
263                         if(clone) clone->type = ATV_UNPARSED;
264                         return clone;
265                 case ATV_BITVECTOR:
266                         return asn1p_value_frombits(v->value.binary_vector.bits,
267                                 v->value.binary_vector.size_in_bits, 1);
268                 case ATV_REFERENCED:
269                         if(resolver) {
270                                 clone = resolver(v, rarg);
271                                 if(clone) return clone;
272                                 else if(errno != ESRCH) return NULL;
273                         }
274                         return asn1p_value_fromref(v->value.reference, 1);
275                 case ATV_VALUESET:
276                         if(resolver) {
277                                 clone = resolver(v, rarg);
278                                 if(clone) return clone;
279                                 else if(errno != ESRCH) return NULL;
280                         }
281                         return asn1p_value_fromconstr(v->value.constraint, 1);
282                 case ATV_CHOICE_IDENTIFIER: {
283                         char *id = v->value.choice_identifier.identifier;
284                         clone = calloc(1, sizeof(*clone));
285                         if(!clone) return NULL;
286                         clone->type = v->type;
287                         id = strdup(id);
288                         if(!id) { asn1p_value_free(clone); return NULL; }
289                         clone->value.choice_identifier.identifier = id;
290                         v = asn1p_value_clone(v->value.choice_identifier.value);
291                         if(!v) { asn1p_value_free(clone); return NULL; }
292                         clone->value.choice_identifier.value = v;
293                         return clone;
294                     }
295                 }
296
297                 assert(!"UNREACHABLE");
298         }
299         return v;
300 }
301
302 void
303 asn1p_value_free(asn1p_value_t *v) {
304         if(v) {
305                 switch(v->type) {
306                 case ATV_NOVALUE:
307                 case ATV_NULL:
308                         break;
309                 case ATV_TYPE:
310                         asn1p_expr_free(v->value.v_type);
311                         break;
312                 case ATV_REAL:
313                 case ATV_INTEGER:
314                 case ATV_MIN:
315                 case ATV_MAX:
316                 case ATV_FALSE:
317                 case ATV_TRUE:
318                 case ATV_TUPLE:
319                 case ATV_QUADRUPLE:
320                         /* No freeing necessary */
321                         break;
322                 case ATV_STRING:
323                 case ATV_UNPARSED:
324                         assert(v->value.string.buf);
325                         free(v->value.string.buf);
326                         break;
327                 case ATV_BITVECTOR:
328                         assert(v->value.binary_vector.bits);
329                         free(v->value.binary_vector.bits);
330                         break;
331                 case ATV_REFERENCED:
332                         asn1p_ref_free(v->value.reference);
333                         break;
334                 case ATV_VALUESET:
335                         asn1p_constraint_free(v->value.constraint);
336                         break;
337                 case ATV_CHOICE_IDENTIFIER:
338                         free(v->value.choice_identifier.identifier);
339                         asn1p_value_free(v->value.choice_identifier.value);
340                         break;
341                 }
342                 memset(v, 0, sizeof(*v));
343                 free(v);
344         }
345 }
346