diff options
Diffstat (limited to 'src/constr_SET.c')
-rw-r--r-- | src/constr_SET.c | 218 |
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; |