2004-06-03 03:38:44 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2006-03-21 03:40:38 +00:00
|
|
|
#include <string.h>
|
2004-06-03 03:38:44 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "asn1parser.h"
|
|
|
|
|
|
|
|
asn1p_constraint_t *
|
|
|
|
asn1p_constraint_new(int _lineno) {
|
|
|
|
asn1p_constraint_t *ct;
|
|
|
|
|
|
|
|
ct = calloc(1, sizeof(*ct));
|
|
|
|
if(ct) {
|
|
|
|
ct->_lineno = _lineno;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ct;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
asn1p_constraint_free(asn1p_constraint_t *ct) {
|
|
|
|
if(ct) {
|
|
|
|
|
2005-03-20 12:58:00 +00:00
|
|
|
if(ct->containedSubtype)
|
|
|
|
asn1p_value_free(ct->containedSubtype);
|
2004-06-03 03:38:44 +00:00
|
|
|
if(ct->value)
|
|
|
|
asn1p_value_free(ct->value);
|
|
|
|
if(ct->range_start)
|
|
|
|
asn1p_value_free(ct->range_start);
|
|
|
|
if(ct->range_stop)
|
|
|
|
asn1p_value_free(ct->range_stop);
|
|
|
|
|
|
|
|
if(ct->elements) {
|
|
|
|
while(ct->el_count--) {
|
|
|
|
asn1p_constraint_free(
|
|
|
|
ct->elements[ct->el_count]);
|
|
|
|
}
|
|
|
|
free(ct->elements);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(ct);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
asn1p_constraint_t *
|
|
|
|
asn1p_constraint_clone(asn1p_constraint_t *src) {
|
2006-03-21 03:40:38 +00:00
|
|
|
return asn1p_constraint_clone_with_resolver(src, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
asn1p_constraint_t *
|
|
|
|
asn1p_constraint_clone_with_resolver(asn1p_constraint_t *src,
|
|
|
|
asn1p_value_t *(*vr)(asn1p_value_t *, void *varg), void *varg) {
|
2004-06-03 03:38:44 +00:00
|
|
|
asn1p_constraint_t *clone;
|
|
|
|
|
2006-03-21 03:40:38 +00:00
|
|
|
#define CLONE(field, func) do { if(src->field) { \
|
|
|
|
clone->field = func(src->field, vr, varg); \
|
|
|
|
if(clone->field == NULL) { \
|
|
|
|
asn1p_constraint_free(clone); \
|
|
|
|
return NULL; \
|
|
|
|
} \
|
2004-06-03 03:38:44 +00:00
|
|
|
} } while(0)
|
|
|
|
|
|
|
|
clone = asn1p_constraint_new(src->_lineno);
|
|
|
|
if(clone) {
|
2004-09-05 10:40:28 +00:00
|
|
|
unsigned int i;
|
2004-08-13 12:35:29 +00:00
|
|
|
|
2004-06-03 03:38:44 +00:00
|
|
|
clone->type = src->type;
|
2004-08-13 12:35:29 +00:00
|
|
|
clone->presence = src->presence;
|
2006-03-21 03:40:38 +00:00
|
|
|
CLONE(containedSubtype, asn1p_value_clone_with_resolver);
|
|
|
|
CLONE(value, asn1p_value_clone_with_resolver);
|
|
|
|
CLONE(range_start, asn1p_value_clone_with_resolver);
|
|
|
|
CLONE(range_stop, asn1p_value_clone_with_resolver);
|
2004-08-13 12:35:29 +00:00
|
|
|
|
|
|
|
for(i = 0; i < src->el_count; i++) {
|
|
|
|
asn1p_constraint_t *t;
|
2006-03-21 03:40:38 +00:00
|
|
|
t = asn1p_constraint_clone_with_resolver(src->elements[i], vr, varg);
|
2004-08-13 12:35:29 +00:00
|
|
|
if(!t) {
|
|
|
|
asn1p_constraint_free(clone);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if(asn1p_constraint_insert(clone, t)) {
|
|
|
|
asn1p_constraint_free(clone);
|
|
|
|
asn1p_constraint_free(t);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(clone->el_count == src->el_count);
|
|
|
|
clone->_lineno = src->_lineno;
|
2004-06-03 03:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return clone;
|
|
|
|
}
|
|
|
|
|
2006-03-21 03:40:38 +00:00
|
|
|
/*
|
|
|
|
* Make sure there's enough space to add an element.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
asn1p_constraint_make_memory(asn1p_constraint_t *ct) {
|
|
|
|
if(ct->el_count == ct->el_size) {
|
|
|
|
unsigned int newsize = ct->el_size ? ct->el_size << 2 : 4;
|
2004-06-03 03:38:44 +00:00
|
|
|
void *p;
|
2006-03-21 03:40:38 +00:00
|
|
|
p = realloc(ct->elements, newsize * sizeof(ct->elements[0]));
|
2004-06-03 03:38:44 +00:00
|
|
|
if(p) {
|
2006-03-21 03:40:38 +00:00
|
|
|
ct->elements = p;
|
|
|
|
ct->el_size = newsize;
|
2004-06-03 03:38:44 +00:00
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2006-03-21 03:40:38 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) {
|
|
|
|
assert(into);
|
|
|
|
assert(what);
|
|
|
|
|
|
|
|
if(asn1p_constraint_make_memory(into))
|
|
|
|
return -1;
|
2004-06-03 03:38:44 +00:00
|
|
|
|
|
|
|
into->elements[into->el_count++] = what;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2004-08-18 04:59:12 +00:00
|
|
|
|
2006-03-21 03:40:38 +00:00
|
|
|
int
|
|
|
|
asn1p_constraint_prepend(asn1p_constraint_t *before, asn1p_constraint_t *what) {
|
|
|
|
assert(before);
|
|
|
|
assert(what);
|
|
|
|
|
|
|
|
if(asn1p_constraint_make_memory(before))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
memmove(&before->elements[1], &before->elements[0],
|
|
|
|
before->el_count * sizeof(before->elements[0]));
|
|
|
|
|
|
|
|
before->elements[0] = what;
|
|
|
|
before->el_count++;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-08-18 04:59:12 +00:00
|
|
|
|
|
|
|
char *
|
|
|
|
asn1p_constraint_type2str(enum asn1p_constraint_type_e type) {
|
|
|
|
switch(type) {
|
|
|
|
case ACT_INVALID:
|
|
|
|
return "INVALID";
|
2005-03-20 12:58:00 +00:00
|
|
|
case ACT_EL_TYPE:
|
|
|
|
return "ContainedSubtype";
|
2004-08-18 04:59:12 +00:00
|
|
|
case ACT_EL_VALUE:
|
|
|
|
return "SingleValue";
|
|
|
|
case ACT_EL_RANGE:
|
|
|
|
case ACT_EL_LLRANGE:
|
|
|
|
case ACT_EL_RLRANGE:
|
|
|
|
case ACT_EL_ULRANGE:
|
|
|
|
return "ValueRange";
|
|
|
|
case ACT_EL_EXT:
|
|
|
|
return "...";
|
|
|
|
case ACT_CT_SIZE:
|
|
|
|
return "SizeConstraint";
|
|
|
|
case ACT_CT_FROM:
|
|
|
|
return "PermittedAlphabet";
|
|
|
|
case ACT_CT_WCOMP:
|
|
|
|
return "SingleTypeConstraint";
|
|
|
|
case ACT_CT_WCOMPS:
|
|
|
|
return "MultipleTypeConstraints";
|
2005-03-20 14:28:32 +00:00
|
|
|
case ACT_CT_CTDBY:
|
|
|
|
return "UserDefinedConstraint";
|
2006-09-17 04:52:50 +00:00
|
|
|
case ACT_CT_CTNG:
|
|
|
|
return "ContentsConstraint";
|
2006-10-18 18:40:14 +00:00
|
|
|
case ACT_CT_PATTERN:
|
|
|
|
return "PatternConstraint";
|
2004-08-18 04:59:12 +00:00
|
|
|
case ACT_CA_SET:
|
|
|
|
return "SET";
|
|
|
|
case ACT_CA_CRC:
|
|
|
|
return "ComponentRelationConstraint";
|
|
|
|
case ACT_CA_CSV:
|
|
|
|
return "CSV";
|
|
|
|
case ACT_CA_UNI:
|
|
|
|
return "UNION";
|
|
|
|
case ACT_CA_INT:
|
|
|
|
return "INTERSECTION";
|
|
|
|
case ACT_CA_EXC:
|
|
|
|
return "EXCEPT";
|
2005-03-24 14:29:35 +00:00
|
|
|
case ACT_CA_AEX:
|
|
|
|
return "ALL EXCEPT";
|
2004-08-18 04:59:12 +00:00
|
|
|
}
|
|
|
|
return "UNKNOWN";
|
|
|
|
}
|