Commit 52d49b42 authored by Anton Gerasimov's avatar Anton Gerasimov

Add aper encoder for SET_OF

parent 8dbccbca
......@@ -349,7 +349,8 @@ SET_OF__encode_sorted_free(struct _el_buffer *el_buf, size_t count) {
enum SET_OF__encode_method {
SOES_DER, /* Distinguished Encoding Rules */
SOES_CUPER /* Canonical Unaligned Packed Encoding Rules */
SOES_CUPER, /* Canonical Unaligned Packed Encoding Rules */
SOES_CAPER /* Canonical Aligned Packed Encoding Rules */
};
static struct _el_buffer *
......@@ -393,6 +394,19 @@ SET_OF__encode_sorted(const asn_TYPE_member_t *elm,
encoding_el->bits_unused = (8 - extra_bits) & 0x7;
}
break;
case SOES_CAPER:
erval = aper_encode(elm->type,
elm->encoding_constraints.per_constraints,
memb_ptr, _el_addbytes, encoding_el);
if(erval.encoded != -1) {
size_t extra_bits = erval.encoded % 8;
assert(encoding_el->length == (size_t)(erval.encoded + 7) / 8);
encoding_el->bits_unused = (8 - extra_bits) & 0x7;
}
break;
default:
assert(!"Unreachable");
break;
......@@ -1097,6 +1111,87 @@ SET_OF_encode_uper(const asn_TYPE_descriptor_t *td,
}
}
asn_enc_rval_t
SET_OF_encode_aper(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints, const void *sptr,
asn_per_outp_t *po) {
const asn_anonymous_set_ *list;
const asn_per_constraint_t *ct;
const asn_TYPE_member_t *elm = td->elements;
struct _el_buffer *encoded_els;
asn_enc_rval_t er = {0,0,0};
int seq;
if(!sptr) ASN__ENCODE_FAILED;
list = _A_CSET_FROM_VOID(sptr);
er.encoded = 0;
ASN_DEBUG("Encoding %s as SET OF (%d)", td->name, list->count);
if(constraints) ct = &constraints->size;
else if(td->encoding_constraints.per_constraints)
ct = &td->encoding_constraints.per_constraints->size;
else ct = 0;
/* If extensible constraint, check if size is in root */
if(ct) {
int not_in_root =
(list->count < ct->lower_bound || list->count > ct->upper_bound);
ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound,
ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
if(ct->flags & APC_EXTENSIBLE) {
/* Declare whether size is in extension root */
if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED;
if(not_in_root) ct = 0;
} else if(not_in_root && ct->effective_bits >= 0) {
ASN__ENCODE_FAILED;
}
}
if(ct && ct->effective_bits >= 0) {
/* X.691, #19.5: No length determinant */
/*if(per_put_few_bits(po, list->count - ct->lower_bound,
ct->effective_bits))
ASN__ENCODE_FAILED;*/
if (aper_put_length(po, ct->upper_bound - ct->lower_bound + 1, list->count - ct->lower_bound) < 0) {
ASN__ENCODE_FAILED;
}
}
/*
* Canonical PER #22.1 mandates dynamic sorting of the SET OF elements
* according to their encodings. Build an array of the encoded elements.
*/
encoded_els = SET_OF__encode_sorted(elm, list, SOES_CAPER);
for(seq = 0; seq < list->count;) {
ssize_t may_encode;
if(ct && ct->effective_bits >= 0) {
may_encode = list->count;
} else {
may_encode =
aper_put_length(po, -1, list->count - seq);
if(may_encode < 0) ASN__ENCODE_FAILED;
}
while(may_encode--) {
const struct _el_buffer *el = &encoded_els[seq++];
if(asn_put_many_bits(po, el->buf,
(8 * el->length) - el->bits_unused) < 0) {
break;
}
}
}
SET_OF__encode_sorted_free(encoded_els, list->count);
ASN__ENCODED_OK(er);
}
asn_dec_rval_t
SET_OF_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *td,
......@@ -1293,7 +1388,7 @@ asn_TYPE_operation_t asn_OP_SET_OF = {
SET_OF_decode_uper,
SET_OF_encode_uper,
SET_OF_decode_aper,
0, /* SET_OF_encode_aper */
SET_OF_encode_aper,
#endif /* ASN_DISABLE_PER_SUPPORT */
SET_OF_random_fill,
0 /* Use generic outmost tag fetcher */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment