2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
7 #include <constr_SET_OF.h>
10 SET_OF_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
11 const asn_TYPE_descriptor_t *td,
12 const asn_per_constraints_t *constraints, void **sptr,
14 asn_dec_rval_t rv = {RC_OK, 0};
15 const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;
16 const asn_TYPE_member_t *elm = td->elements; /* Single one */
18 asn_anonymous_set_ *list;
19 const asn_per_constraint_t *ct;
23 if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
27 * Create the target structure if it is not present already.
30 st = *sptr = CALLOC(1, specs->struct_size);
31 if(!st) ASN__DECODE_FAILED;
33 list = _A_SET_FROM_VOID(st);
35 /* Figure out which constraints to use */
36 if(constraints) ct = &constraints->size;
37 else if(td->encoding_constraints.per_constraints)
38 ct = &td->encoding_constraints.per_constraints->size;
41 if(ct && ct->flags & APC_EXTENSIBLE) {
42 int value = per_get_few_bits(pd, 1);
43 if(value < 0) ASN__DECODE_STARVED;
44 if(value) ct = 0; /* Not restricted! */
47 if(ct && ct->effective_bits >= 0) {
48 /* X.691, #19.5: No length determinant */
49 nelems = per_get_few_bits(pd, ct->effective_bits);
50 ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
51 (long)nelems, ct->lower_bound, td->name);
52 if(nelems < 0) ASN__DECODE_STARVED;
53 nelems += ct->lower_bound;
61 nelems = uper_get_length(pd, -1, 0, &repeat);
62 ASN_DEBUG("Got to decode %" ASN_PRI_SSIZE " elements (eff %d)",
63 nelems, (int)(ct ? ct->effective_bits : -1));
64 if(nelems < 0) ASN__DECODE_STARVED;
67 for(i = 0; i < nelems; i++) {
69 ASN_DEBUG("SET OF %s decoding", elm->type->name);
70 rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
71 elm->encoding_constraints.per_constraints,
73 ASN_DEBUG("%s SET OF %s decoded %d, %p",
74 td->name, elm->type->name, rv.code, ptr);
75 if(rv.code == RC_OK) {
76 if(ASN_SET_ADD(list, ptr) == 0) {
77 if(rv.consumed == 0 && nelems > 200) {
78 /* Protect from SET OF NULL compression bombs. */
83 ASN_DEBUG("Failed to add element into %s",
88 ASN_DEBUG("Failed decoding %s of %s (SET OF)",
89 elm->type->name, td->name);
91 if(ptr) ASN_STRUCT_FREE(*elm->type, ptr);
95 nelems = -1; /* Allow uper_get_length() */
98 ASN_DEBUG("Decoded %s as SET OF", td->name);
106 SET_OF_encode_uper(const asn_TYPE_descriptor_t *td,
107 const asn_per_constraints_t *constraints, const void *sptr,
108 asn_per_outp_t *po) {
109 const asn_anonymous_set_ *list;
110 const asn_per_constraint_t *ct;
111 const asn_TYPE_member_t *elm = td->elements;
112 struct _el_buffer *encoded_els;
113 asn_enc_rval_t er = {0,0,0};
116 if(!sptr) ASN__ENCODE_FAILED;
118 list = _A_CSET_FROM_VOID(sptr);
122 ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);
124 if(constraints) ct = &constraints->size;
125 else if(td->encoding_constraints.per_constraints)
126 ct = &td->encoding_constraints.per_constraints->size;
129 /* If extensible constraint, check if size is in root */
132 (list->count < ct->lower_bound || list->count > ct->upper_bound);
133 ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound,
134 ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
135 if(ct->flags & APC_EXTENSIBLE) {
136 /* Declare whether size is in extension root */
137 if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED;
138 if(not_in_root) ct = 0;
139 } else if(not_in_root && ct->effective_bits >= 0) {
145 if(ct && ct->effective_bits >= 0) {
146 /* X.691, #19.5: No length determinant */
147 if(per_put_few_bits(po, list->count - ct->lower_bound,
150 } else if(list->count == 0) {
151 /* When the list is empty add only the length determinant
152 * X.691, #20.6 and #11.9.4.1
154 if (uper_put_length(po, 0, 0)) {
162 * Canonical UPER #22.1 mandates dynamic sorting of the SET OF elements
163 * according to their encodings. Build an array of the encoded elements.
165 encoded_els = SET_OF__encode_sorted(elm, list, SOES_CUPER);
167 for(encoded_edx = 0; (ssize_t)encoded_edx < list->count;) {
172 if(ct && ct->effective_bits >= 0) {
173 may_encode = list->count;
176 uper_put_length(po, list->count - encoded_edx, &need_eom);
177 if(may_encode < 0) ASN__ENCODE_FAILED;
180 for(edx = encoded_edx; edx < encoded_edx + may_encode; edx++) {
181 const struct _el_buffer *el = &encoded_els[edx];
182 if(asn_put_many_bits(po, el->buf,
183 (8 * el->length) - el->bits_unused) < 0) {
188 if(need_eom && uper_put_length(po, 0, 0))
189 ASN__ENCODE_FAILED; /* End of Message length */
191 encoded_edx += may_encode;
194 SET_OF__encode_sorted_free(encoded_els, list->count);
196 if((ssize_t)encoded_edx == list->count) {