aboutsummaryrefslogtreecommitdiffstats
path: root/src/constr_SET.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/constr_SET.c')
-rw-r--r--src/constr_SET.c218
1 files changed, 200 insertions, 18 deletions
diff --git a/src/constr_SET.c b/src/constr_SET.c
index ecf5661..8a124c0 100644
--- a/src/constr_SET.c
+++ b/src/constr_SET.c
@@ -175,7 +175,7 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
* for optimization.
*/
for(;; ctx->step = 0) {
- asn_TYPE_tag2member_t *t2m;
+ const asn_TYPE_tag2member_t *t2m;
asn_TYPE_tag2member_t key;
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
@@ -225,7 +225,7 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
}
key.el_tag = tlv_tag;
- t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
+ t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
specs->tag2el, specs->tag2el_count,
sizeof(specs->tag2el[0]), _t2e_cmp);
if(t2m) {
@@ -404,7 +404,7 @@ _SET_is_populated(asn_TYPE_descriptor_t *td, void *st) {
unsigned int midx, pres, must;
midx = edx/(8 * sizeof(specs->_mandatory_elements[0]));
- pres = ((unsigned int *)((char *)st+specs->pres_offset))[midx];
+ pres = ((unsigned int *)((char *)st + specs->pres_offset))[midx];
must = sys_ntohl(specs->_mandatory_elements[midx]);
if((pres & must) == must) {
@@ -439,7 +439,8 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
size_t computed_size = 0;
asn_enc_rval_t er;
int t2m_build_own = (specs->tag2el_count != td->elements_count);
- asn_TYPE_tag2member_t *t2m;
+ const asn_TYPE_tag2member_t *t2m;
+ asn_TYPE_tag2member_t *t2m_build;
int t2m_count;
ssize_t ret;
int edx;
@@ -448,17 +449,16 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
* Use existing, or build our own tags map.
*/
if(t2m_build_own) {
- t2m = (asn_TYPE_tag2member_t *)alloca(
- td->elements_count * sizeof(t2m[0]));
- if(!t2m) _ASN_ENCODE_FAILED; /* There are such platforms */
+ t2m_build = (asn_TYPE_tag2member_t *)alloca(
+ td->elements_count * sizeof(t2m_build[0]));
+ if(!t2m_build) _ASN_ENCODE_FAILED; /* There are such platforms */
t2m_count = 0;
} else {
+ t2m_build = NULL;
/*
* There is no untagged CHOICE in this SET.
* Employ existing table.
*/
- t2m = specs->tag2el;
- t2m_count = specs->tag2el_count;
}
/*
@@ -479,8 +479,8 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
/* Mandatory elements missing */
_ASN_ENCODE_FAILED;
if(t2m_build_own) {
- t2m[t2m_count].el_no = edx;
- t2m[t2m_count].el_tag = 0;
+ t2m_build[t2m_count].el_no = edx;
+ t2m_build[t2m_count].el_tag = 0;
t2m_count++;
}
continue;
@@ -499,8 +499,8 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
* Remember the outmost tag of this member.
*/
if(t2m_build_own) {
- t2m[t2m_count].el_no = edx;
- t2m[t2m_count].el_tag = asn_TYPE_outmost_tag(
+ t2m_build[t2m_count].el_no = edx;
+ t2m_build[t2m_count].el_tag = asn_TYPE_outmost_tag(
elm->type, memb_ptr, elm->tag_mode, elm->tag);
t2m_count++;
} else {
@@ -513,18 +513,21 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
/*
* Finalize order of the components.
*/
- assert(t2m_count == td->elements_count);
if(t2m_build_own) {
/*
* Sort the underlying members according to their
* canonical tags order. DER encoding mandates it.
*/
- qsort(t2m, t2m_count, sizeof(specs->tag2el[0]), _t2e_cmp);
+ qsort(t2m_build, t2m_count, sizeof(specs->tag2el[0]), _t2e_cmp);
+ t2m = t2m_build;
} else {
/*
* Tags are already sorted by the compiler.
*/
+ t2m = specs->tag2el;
+ t2m_count = specs->tag2el_count;
}
+ assert(t2m_count == td->elements_count);
/*
* Encode the TLV for the sequence itself.
@@ -570,6 +573,186 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
_ASN_ENCODED_OK(er);
}
+asn_enc_rval_t
+SET_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints,
+ void *sptr,
+ asn_per_outp_t *po) {
+ _ASN_ENCODE_FAILED;
+}
+
+asn_dec_rval_t
+SET_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ _ASN_DECODE_FAILED;
+}
+
+asn_enc_rval_t
+SET_encode_aper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints,
+ void *sptr,
+ asn_per_outp_t *po) {
+ asn_SET_specifics_t *specs = (asn_SET_specifics_t *)td->specifics;
+ asn_enc_rval_t er;
+ int edx;
+ int t2m_build_own = (specs->tag2el_count != td->elements_count);
+ const asn_TYPE_tag2member_t *t2m;
+ asn_TYPE_tag2member_t *t2m_build;
+ int t2m_count;
+
+ (void)constraints;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ ASN_DEBUG("Encoding %s as SET (APER) map %d", td->name, specs->_mandatory_elements[0]);
+
+ /*
+ * Use existing, or build our own tags map.
+ */
+ if(t2m_build_own) {
+ t2m_build = (asn_TYPE_tag2member_t *)alloca(
+ td->elements_count * sizeof(t2m[0]));
+ if(!t2m_build) _ASN_ENCODE_FAILED; /* There are such platforms */
+ t2m_count = 0;
+ } else {
+ t2m_build = NULL;
+ /*
+ * There is no untagged CHOICE in this SET.
+ * Employ existing table.
+ */
+ }
+
+ /*
+ * Gather the length of the underlying members sequence.
+ */
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr;
+
+ /*
+ * Compute the length of the encoding of this member.
+ */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) {
+ if(!elm->optional)
+ /* Mandatory elements missing */
+ _ASN_ENCODE_FAILED;
+ if(t2m_build_own) {
+ t2m_build[t2m_count].el_no = edx;
+ t2m_build[t2m_count].el_tag = 0;
+ t2m_count++;
+ }
+ continue;
+ }
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ /*
+ * Remember the outmost tag of this member.
+ */
+ if(t2m_build_own) {
+ t2m_build[t2m_count].el_no = edx;
+ t2m_build[t2m_count].el_tag = asn_TYPE_outmost_tag(
+ elm->type, memb_ptr, elm->tag_mode, elm->tag);
+ t2m_count++;
+ } else {
+ /*
+ * No dynamic sorting is necessary.
+ */
+ }
+ }
+
+ /*
+ * Finalize order of the components.
+ */
+ assert(t2m_count == td->elements_count);
+ if(t2m_build_own) {
+ /*
+ * Sort the underlying members according to their
+ * canonical tags order. DER encoding mandates it.
+ */
+ qsort(t2m_build, t2m_count, sizeof(specs->tag2el[0]), _t2e_cmp);
+ t2m = t2m_build;
+ } else {
+ /*
+ * Tags are already sorted by the compiler.
+ */
+ t2m = specs->tag2el;
+ t2m_count = specs->tag2el_count;
+ }
+ assert(t2m_count == td->elements_count);
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[t2m[edx].el_no];
+// asn_enc_rval_t tmper;
+// void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ int present;
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+ present = (*memb_ptr2 != 0);
+ } else {
+// memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+// memb_ptr2 = &memb_ptr;
+ present = 1;
+ continue;
+ }
+
+// /* Eliminate default values */
+// if(present && elm->default_value
+// && elm->default_value(0, memb_ptr2) == 1)
+// present = 0;
+
+ ASN_DEBUG("Element %s %s %s->%s is %s",
+ elm->flags & ATF_POINTER ? "ptr" : "inline",
+ elm->default_value ? "def" : "wtv",
+ td->name, elm->name, present ? "present" : "absent");
+ if(per_put_few_bits(po, present << 7, 8))
+ _ASN_ENCODE_FAILED;
+ }
+
+ /*
+ * Encode all members.
+ */
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ asn_enc_rval_t tmper;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ /* Encode according to the tag order */
+// elm = &td->elements[t2m[edx].el_no];
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+ if(!*memb_ptr2) {
+ ASN_DEBUG("Element %s %d not present",
+ elm->name, edx);
+ if(elm->optional)
+ continue;
+ /* Mandatory element is missing */
+ _ASN_ENCODE_FAILED;
+ }
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ memb_ptr2 = &memb_ptr;
+ }
+ tmper = elm->type->aper_encoder(elm->type, elm->per_constraints,
+ *memb_ptr2, po);
+ if(tmper.encoded == -1)
+ return tmper;
+ }
+
+ _ASN_ENCODED_OK(er);
+}
+
#undef XER_ADVANCE
#define XER_ADVANCE(num_bytes) do { \
size_t num = num_bytes; \
@@ -648,8 +831,7 @@ SET_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
if(elm->flags & ATF_POINTER) {
/* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st
- + elm->memb_offset);
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
} else {
memb_ptr = (char *)st + elm->memb_offset;
memb_ptr2 = &memb_ptr;
@@ -804,7 +986,7 @@ SET_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
asn_SET_specifics_t *specs = (asn_SET_specifics_t *)td->specifics;
asn_enc_rval_t er;
int xcan = (flags & XER_F_CANONICAL);
- asn_TYPE_tag2member_t *t2m = specs->tag2el_cxer;
+ const asn_TYPE_tag2member_t *t2m = specs->tag2el_cxer;
int t2m_count = specs->tag2el_cxer_count;
int edx;