blob: 008ad40065ac05d864ad3d121bd480a8ae50eecb [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
Markus Elfring671eb9a2016-03-14 17:07:26 +010026 asn1p_value_free(ct->containedSubtype);
27 asn1p_value_free(ct->value);
28 asn1p_value_free(ct->range_start);
29 asn1p_value_free(ct->range_stop);
Lev Walkinf15320b2004-06-03 03:38:44 +000030
31 if(ct->elements) {
32 while(ct->el_count--) {
33 asn1p_constraint_free(
34 ct->elements[ct->el_count]);
35 }
36 free(ct->elements);
37 }
38
39 free(ct);
40 }
41}
42
43asn1p_constraint_t *
44asn1p_constraint_clone(asn1p_constraint_t *src) {
Lev Walkina00d6b32006-03-21 03:40:38 +000045 return asn1p_constraint_clone_with_resolver(src, 0, 0);
46}
47
48asn1p_constraint_t *
49asn1p_constraint_clone_with_resolver(asn1p_constraint_t *src,
50 asn1p_value_t *(*vr)(asn1p_value_t *, void *varg), void *varg) {
Lev Walkinf15320b2004-06-03 03:38:44 +000051 asn1p_constraint_t *clone;
52
Lev Walkina00d6b32006-03-21 03:40:38 +000053#define CLONE(field, func) do { if(src->field) { \
54 clone->field = func(src->field, vr, varg); \
55 if(clone->field == NULL) { \
56 asn1p_constraint_free(clone); \
57 return NULL; \
58 } \
Lev Walkinf15320b2004-06-03 03:38:44 +000059 } } while(0)
60
61 clone = asn1p_constraint_new(src->_lineno);
62 if(clone) {
Lev Walkine972d932004-09-05 10:40:28 +000063 unsigned int i;
Lev Walkin26b6e042004-08-13 12:35:29 +000064
Lev Walkinf15320b2004-06-03 03:38:44 +000065 clone->type = src->type;
Lev Walkin26b6e042004-08-13 12:35:29 +000066 clone->presence = src->presence;
Lev Walkina00d6b32006-03-21 03:40:38 +000067 CLONE(containedSubtype, asn1p_value_clone_with_resolver);
68 CLONE(value, asn1p_value_clone_with_resolver);
69 CLONE(range_start, asn1p_value_clone_with_resolver);
70 CLONE(range_stop, asn1p_value_clone_with_resolver);
Lev Walkin26b6e042004-08-13 12:35:29 +000071
72 for(i = 0; i < src->el_count; i++) {
73 asn1p_constraint_t *t;
Lev Walkina00d6b32006-03-21 03:40:38 +000074 t = asn1p_constraint_clone_with_resolver(src->elements[i], vr, varg);
Lev Walkin26b6e042004-08-13 12:35:29 +000075 if(!t) {
76 asn1p_constraint_free(clone);
77 return NULL;
78 }
79 if(asn1p_constraint_insert(clone, t)) {
80 asn1p_constraint_free(clone);
81 asn1p_constraint_free(t);
82 return NULL;
83 }
84 }
85 assert(clone->el_count == src->el_count);
86 clone->_lineno = src->_lineno;
Lev Walkinf15320b2004-06-03 03:38:44 +000087 }
88
89 return clone;
90}
91
Lev Walkina00d6b32006-03-21 03:40:38 +000092/*
93 * Make sure there's enough space to add an element.
94 */
95static int
96asn1p_constraint_make_memory(asn1p_constraint_t *ct) {
97 if(ct->el_count == ct->el_size) {
98 unsigned int newsize = ct->el_size ? ct->el_size << 2 : 4;
99 void *p;
100 p = realloc(ct->elements, newsize * sizeof(ct->elements[0]));
101 if(p) {
102 ct->elements = p;
103 ct->el_size = newsize;
104 } else {
105 return -1;
106 }
107 }
108 return 0;
109}
110
Lev Walkinf15320b2004-06-03 03:38:44 +0000111int
112asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) {
113 assert(into);
114 assert(what);
115
Lev Walkina00d6b32006-03-21 03:40:38 +0000116 if(asn1p_constraint_make_memory(into))
117 return -1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000118
119 into->elements[into->el_count++] = what;
120
121 return 0;
122}
Lev Walkinf59d0752004-08-18 04:59:12 +0000123
Lev Walkina00d6b32006-03-21 03:40:38 +0000124int
125asn1p_constraint_prepend(asn1p_constraint_t *before, asn1p_constraint_t *what) {
126 assert(before);
127 assert(what);
128
129 if(asn1p_constraint_make_memory(before))
130 return -1;
131
132 memmove(&before->elements[1], &before->elements[0],
133 before->el_count * sizeof(before->elements[0]));
134
135 before->elements[0] = what;
136 before->el_count++;
137
138 return 0;
139}
140
Lev Walkinf59d0752004-08-18 04:59:12 +0000141
142char *
143asn1p_constraint_type2str(enum asn1p_constraint_type_e type) {
144 switch(type) {
145 case ACT_INVALID:
146 return "INVALID";
Lev Walkinff7dd142005-03-20 12:58:00 +0000147 case ACT_EL_TYPE:
148 return "ContainedSubtype";
Lev Walkinf59d0752004-08-18 04:59:12 +0000149 case ACT_EL_VALUE:
150 return "SingleValue";
151 case ACT_EL_RANGE:
152 case ACT_EL_LLRANGE:
153 case ACT_EL_RLRANGE:
154 case ACT_EL_ULRANGE:
155 return "ValueRange";
156 case ACT_EL_EXT:
157 return "...";
158 case ACT_CT_SIZE:
159 return "SizeConstraint";
160 case ACT_CT_FROM:
161 return "PermittedAlphabet";
162 case ACT_CT_WCOMP:
163 return "SingleTypeConstraint";
164 case ACT_CT_WCOMPS:
165 return "MultipleTypeConstraints";
Lev Walkin1893ddf2005-03-20 14:28:32 +0000166 case ACT_CT_CTDBY:
167 return "UserDefinedConstraint";
Lev Walkina9532f42006-09-17 04:52:50 +0000168 case ACT_CT_CTNG:
169 return "ContentsConstraint";
Lev Walkin5c541f12006-10-18 18:40:14 +0000170 case ACT_CT_PATTERN:
171 return "PatternConstraint";
Lev Walkinf59d0752004-08-18 04:59:12 +0000172 case ACT_CA_SET:
173 return "SET";
174 case ACT_CA_CRC:
175 return "ComponentRelationConstraint";
176 case ACT_CA_CSV:
177 return "CSV";
178 case ACT_CA_UNI:
179 return "UNION";
180 case ACT_CA_INT:
181 return "INTERSECTION";
182 case ACT_CA_EXC:
183 return "EXCEPT";
Lev Walkine4861a62005-03-24 14:29:35 +0000184 case ACT_CA_AEX:
185 return "ALL EXCEPT";
Lev Walkinf59d0752004-08-18 04:59:12 +0000186 }
187 return "UNKNOWN";
188}