blob: 0b1e89217a7f15bb166eb723cea35cfe952d3e25 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
2#include <stdlib.h>
Lev Walkina00d6b32006-03-21 03:40:38 +00003#include <string.h>
Lev Walkinf15320b2004-06-03 03:38:44 +00004#include <errno.h>
5#include <assert.h>
6
7#include "asn1parser.h"
8
9asn1p_constraint_t *
10asn1p_constraint_new(int _lineno) {
11 asn1p_constraint_t *ct;
12
13 ct = calloc(1, sizeof(*ct));
14 if(ct) {
15 ct->_lineno = _lineno;
16 }
17
18 return ct;
19}
20
21
22void
23asn1p_constraint_free(asn1p_constraint_t *ct) {
24 if(ct) {
25
Lev Walkinff7dd142005-03-20 12:58:00 +000026 if(ct->containedSubtype)
27 asn1p_value_free(ct->containedSubtype);
Lev Walkinf15320b2004-06-03 03:38:44 +000028 if(ct->value)
29 asn1p_value_free(ct->value);
30 if(ct->range_start)
31 asn1p_value_free(ct->range_start);
32 if(ct->range_stop)
33 asn1p_value_free(ct->range_stop);
34
35 if(ct->elements) {
36 while(ct->el_count--) {
37 asn1p_constraint_free(
38 ct->elements[ct->el_count]);
39 }
40 free(ct->elements);
41 }
42
43 free(ct);
44 }
45}
46
47asn1p_constraint_t *
48asn1p_constraint_clone(asn1p_constraint_t *src) {
Lev Walkina00d6b32006-03-21 03:40:38 +000049 return asn1p_constraint_clone_with_resolver(src, 0, 0);
50}
51
52asn1p_constraint_t *
53asn1p_constraint_clone_with_resolver(asn1p_constraint_t *src,
54 asn1p_value_t *(*vr)(asn1p_value_t *, void *varg), void *varg) {
Lev Walkinf15320b2004-06-03 03:38:44 +000055 asn1p_constraint_t *clone;
56
Lev Walkina00d6b32006-03-21 03:40:38 +000057#define CLONE(field, func) do { if(src->field) { \
58 clone->field = func(src->field, vr, varg); \
59 if(clone->field == NULL) { \
60 asn1p_constraint_free(clone); \
61 return NULL; \
62 } \
Lev Walkinf15320b2004-06-03 03:38:44 +000063 } } while(0)
64
65 clone = asn1p_constraint_new(src->_lineno);
66 if(clone) {
Lev Walkine972d932004-09-05 10:40:28 +000067 unsigned int i;
Lev Walkin26b6e042004-08-13 12:35:29 +000068
Lev Walkinf15320b2004-06-03 03:38:44 +000069 clone->type = src->type;
Lev Walkin26b6e042004-08-13 12:35:29 +000070 clone->presence = src->presence;
Lev Walkina00d6b32006-03-21 03:40:38 +000071 CLONE(containedSubtype, asn1p_value_clone_with_resolver);
72 CLONE(value, asn1p_value_clone_with_resolver);
73 CLONE(range_start, asn1p_value_clone_with_resolver);
74 CLONE(range_stop, asn1p_value_clone_with_resolver);
Lev Walkin26b6e042004-08-13 12:35:29 +000075
76 for(i = 0; i < src->el_count; i++) {
77 asn1p_constraint_t *t;
Lev Walkina00d6b32006-03-21 03:40:38 +000078 t = asn1p_constraint_clone_with_resolver(src->elements[i], vr, varg);
Lev Walkin26b6e042004-08-13 12:35:29 +000079 if(!t) {
80 asn1p_constraint_free(clone);
81 return NULL;
82 }
83 if(asn1p_constraint_insert(clone, t)) {
84 asn1p_constraint_free(clone);
85 asn1p_constraint_free(t);
86 return NULL;
87 }
88 }
89 assert(clone->el_count == src->el_count);
90 clone->_lineno = src->_lineno;
Lev Walkinf15320b2004-06-03 03:38:44 +000091 }
92
93 return clone;
94}
95
Lev Walkina00d6b32006-03-21 03:40:38 +000096/*
97 * Make sure there's enough space to add an element.
98 */
99static int
100asn1p_constraint_make_memory(asn1p_constraint_t *ct) {
101 if(ct->el_count == ct->el_size) {
102 unsigned int newsize = ct->el_size ? ct->el_size << 2 : 4;
103 void *p;
104 p = realloc(ct->elements, newsize * sizeof(ct->elements[0]));
105 if(p) {
106 ct->elements = p;
107 ct->el_size = newsize;
108 } else {
109 return -1;
110 }
111 }
112 return 0;
113}
114
Lev Walkinf15320b2004-06-03 03:38:44 +0000115int
116asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) {
117 assert(into);
118 assert(what);
119
Lev Walkina00d6b32006-03-21 03:40:38 +0000120 if(asn1p_constraint_make_memory(into))
121 return -1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000122
123 into->elements[into->el_count++] = what;
124
125 return 0;
126}
Lev Walkinf59d0752004-08-18 04:59:12 +0000127
Lev Walkina00d6b32006-03-21 03:40:38 +0000128int
129asn1p_constraint_prepend(asn1p_constraint_t *before, asn1p_constraint_t *what) {
130 assert(before);
131 assert(what);
132
133 if(asn1p_constraint_make_memory(before))
134 return -1;
135
136 memmove(&before->elements[1], &before->elements[0],
137 before->el_count * sizeof(before->elements[0]));
138
139 before->elements[0] = what;
140 before->el_count++;
141
142 return 0;
143}
144
Lev Walkinf59d0752004-08-18 04:59:12 +0000145
146char *
147asn1p_constraint_type2str(enum asn1p_constraint_type_e type) {
148 switch(type) {
149 case ACT_INVALID:
150 return "INVALID";
Lev Walkinff7dd142005-03-20 12:58:00 +0000151 case ACT_EL_TYPE:
152 return "ContainedSubtype";
Lev Walkinf59d0752004-08-18 04:59:12 +0000153 case ACT_EL_VALUE:
154 return "SingleValue";
155 case ACT_EL_RANGE:
156 case ACT_EL_LLRANGE:
157 case ACT_EL_RLRANGE:
158 case ACT_EL_ULRANGE:
159 return "ValueRange";
160 case ACT_EL_EXT:
161 return "...";
162 case ACT_CT_SIZE:
163 return "SizeConstraint";
164 case ACT_CT_FROM:
165 return "PermittedAlphabet";
166 case ACT_CT_WCOMP:
167 return "SingleTypeConstraint";
168 case ACT_CT_WCOMPS:
169 return "MultipleTypeConstraints";
Lev Walkin1893ddf2005-03-20 14:28:32 +0000170 case ACT_CT_CTDBY:
171 return "UserDefinedConstraint";
Lev Walkina9532f42006-09-17 04:52:50 +0000172 case ACT_CT_CTNG:
173 return "ContentsConstraint";
Lev Walkin5c541f12006-10-18 18:40:14 +0000174 case ACT_CT_PATTERN:
175 return "PatternConstraint";
Lev Walkinf59d0752004-08-18 04:59:12 +0000176 case ACT_CA_SET:
177 return "SET";
178 case ACT_CA_CRC:
179 return "ComponentRelationConstraint";
180 case ACT_CA_CSV:
181 return "CSV";
182 case ACT_CA_UNI:
183 return "UNION";
184 case ACT_CA_INT:
185 return "INTERSECTION";
186 case ACT_CA_EXC:
187 return "EXCEPT";
Lev Walkine4861a62005-03-24 14:29:35 +0000188 case ACT_CA_AEX:
189 return "ALL EXCEPT";
Lev Walkinf59d0752004-08-18 04:59:12 +0000190 }
191 return "UNKNOWN";
192}