blob: e0a5619271d2be1dd131a83cdc1e538db44091be [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 *
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080010asn1p_constraint_new(int _lineno, asn1p_module_t *mod) {
Lev Walkinf15320b2004-06-03 03:38:44 +000011 asn1p_constraint_t *ct;
12
13 ct = calloc(1, sizeof(*ct));
14 if(ct) {
15 ct->_lineno = _lineno;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080016 ct->module = mod;
Lev Walkinf15320b2004-06-03 03:38:44 +000017 }
18
19 return ct;
20}
21
22
23void
24asn1p_constraint_free(asn1p_constraint_t *ct) {
25 if(ct) {
26
Markus Elfring671eb9a2016-03-14 17:07:26 +010027 asn1p_value_free(ct->containedSubtype);
28 asn1p_value_free(ct->value);
29 asn1p_value_free(ct->range_start);
30 asn1p_value_free(ct->range_stop);
Lev Walkinf15320b2004-06-03 03:38:44 +000031
32 if(ct->elements) {
33 while(ct->el_count--) {
34 asn1p_constraint_free(
35 ct->elements[ct->el_count]);
36 }
37 free(ct->elements);
38 }
39
40 free(ct);
41 }
42}
43
44asn1p_constraint_t *
45asn1p_constraint_clone(asn1p_constraint_t *src) {
Lev Walkina00d6b32006-03-21 03:40:38 +000046 return asn1p_constraint_clone_with_resolver(src, 0, 0);
47}
48
49asn1p_constraint_t *
50asn1p_constraint_clone_with_resolver(asn1p_constraint_t *src,
51 asn1p_value_t *(*vr)(asn1p_value_t *, void *varg), void *varg) {
Lev Walkinf15320b2004-06-03 03:38:44 +000052 asn1p_constraint_t *clone;
53
Lev Walkina00d6b32006-03-21 03:40:38 +000054#define CLONE(field, func) do { if(src->field) { \
55 clone->field = func(src->field, vr, varg); \
56 if(clone->field == NULL) { \
57 asn1p_constraint_free(clone); \
58 return NULL; \
59 } \
Lev Walkinf15320b2004-06-03 03:38:44 +000060 } } while(0)
61
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080062 clone = asn1p_constraint_new(src->_lineno, src->module);
Lev Walkinf15320b2004-06-03 03:38:44 +000063 if(clone) {
Lev Walkine972d932004-09-05 10:40:28 +000064 unsigned int i;
Lev Walkin26b6e042004-08-13 12:35:29 +000065
Lev Walkinf15320b2004-06-03 03:38:44 +000066 clone->type = src->type;
Lev Walkin26b6e042004-08-13 12:35:29 +000067 clone->presence = src->presence;
Lev Walkina00d6b32006-03-21 03:40:38 +000068 CLONE(containedSubtype, asn1p_value_clone_with_resolver);
69 CLONE(value, asn1p_value_clone_with_resolver);
70 CLONE(range_start, asn1p_value_clone_with_resolver);
71 CLONE(range_stop, asn1p_value_clone_with_resolver);
Lev Walkin26b6e042004-08-13 12:35:29 +000072
73 for(i = 0; i < src->el_count; i++) {
74 asn1p_constraint_t *t;
Lev Walkina00d6b32006-03-21 03:40:38 +000075 t = asn1p_constraint_clone_with_resolver(src->elements[i], vr, varg);
Lev Walkin26b6e042004-08-13 12:35:29 +000076 if(!t) {
77 asn1p_constraint_free(clone);
78 return NULL;
79 }
80 if(asn1p_constraint_insert(clone, t)) {
81 asn1p_constraint_free(clone);
82 asn1p_constraint_free(t);
83 return NULL;
84 }
85 }
86 assert(clone->el_count == src->el_count);
87 clone->_lineno = src->_lineno;
Lev Walkinf15320b2004-06-03 03:38:44 +000088 }
89
90 return clone;
91}
92
Lev Walkina00d6b32006-03-21 03:40:38 +000093/*
94 * Make sure there's enough space to add an element.
95 */
96static int
97asn1p_constraint_make_memory(asn1p_constraint_t *ct) {
98 if(ct->el_count == ct->el_size) {
99 unsigned int newsize = ct->el_size ? ct->el_size << 2 : 4;
100 void *p;
101 p = realloc(ct->elements, newsize * sizeof(ct->elements[0]));
102 if(p) {
103 ct->elements = p;
104 ct->el_size = newsize;
105 } else {
106 return -1;
107 }
108 }
109 return 0;
110}
111
Lev Walkinf15320b2004-06-03 03:38:44 +0000112int
113asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) {
114 assert(into);
115 assert(what);
116
Lev Walkina00d6b32006-03-21 03:40:38 +0000117 if(asn1p_constraint_make_memory(into))
118 return -1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000119
120 into->elements[into->el_count++] = what;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800121 what->parent_ct = into;
Lev Walkinf15320b2004-06-03 03:38:44 +0000122
123 return 0;
124}
Lev Walkinf59d0752004-08-18 04:59:12 +0000125
Lev Walkina00d6b32006-03-21 03:40:38 +0000126int
127asn1p_constraint_prepend(asn1p_constraint_t *before, asn1p_constraint_t *what) {
128 assert(before);
129 assert(what);
130
131 if(asn1p_constraint_make_memory(before))
132 return -1;
133
134 memmove(&before->elements[1], &before->elements[0],
135 before->el_count * sizeof(before->elements[0]));
136
137 before->elements[0] = what;
138 before->el_count++;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800139 what->parent_ct = before;
Lev Walkina00d6b32006-03-21 03:40:38 +0000140
141 return 0;
142}
143
Lev Walkinf59d0752004-08-18 04:59:12 +0000144
145char *
146asn1p_constraint_type2str(enum asn1p_constraint_type_e type) {
147 switch(type) {
148 case ACT_INVALID:
149 return "INVALID";
Lev Walkinff7dd142005-03-20 12:58:00 +0000150 case ACT_EL_TYPE:
151 return "ContainedSubtype";
Lev Walkinf59d0752004-08-18 04:59:12 +0000152 case ACT_EL_VALUE:
153 return "SingleValue";
154 case ACT_EL_RANGE:
155 case ACT_EL_LLRANGE:
156 case ACT_EL_RLRANGE:
157 case ACT_EL_ULRANGE:
158 return "ValueRange";
159 case ACT_EL_EXT:
160 return "...";
161 case ACT_CT_SIZE:
162 return "SizeConstraint";
163 case ACT_CT_FROM:
164 return "PermittedAlphabet";
165 case ACT_CT_WCOMP:
166 return "SingleTypeConstraint";
167 case ACT_CT_WCOMPS:
168 return "MultipleTypeConstraints";
Lev Walkin1893ddf2005-03-20 14:28:32 +0000169 case ACT_CT_CTDBY:
170 return "UserDefinedConstraint";
Lev Walkina9532f42006-09-17 04:52:50 +0000171 case ACT_CT_CTNG:
172 return "ContentsConstraint";
Lev Walkin5c541f12006-10-18 18:40:14 +0000173 case ACT_CT_PATTERN:
174 return "PatternConstraint";
Lev Walkinf59d0752004-08-18 04:59:12 +0000175 case ACT_CA_SET:
176 return "SET";
177 case ACT_CA_CRC:
178 return "ComponentRelationConstraint";
179 case ACT_CA_CSV:
180 return "CSV";
181 case ACT_CA_UNI:
182 return "UNION";
183 case ACT_CA_INT:
184 return "INTERSECTION";
185 case ACT_CA_EXC:
186 return "EXCEPT";
Lev Walkine4861a62005-03-24 14:29:35 +0000187 case ACT_CA_AEX:
188 return "ALL EXCEPT";
Lev Walkinf59d0752004-08-18 04:59:12 +0000189 }
190 return "UNKNOWN";
191}