2 * Copyright (c) 2003, 2004, 2005 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>
8 #include <asn_SET_OF.h>
11 * Number of bytes left for this structure.
12 * (ctx->left) indicates the number of bytes _transferred_ for the structure.
13 * (size) contains the number of bytes in the buffer passed.
15 #define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
18 * If the subprocessor function returns with an indication that it wants
19 * more data, it may well be a fatal decoding problem, because the
20 * size is constrained by the <TLV>'s L, even if the buffer size allows
22 * For example, consider the buffer containing the following TLVs:
23 * <T:5><L:1><V> <T:6>...
24 * The TLV length clearly indicates that one byte is expected in V, but
25 * if the V processor returns with "want more data" even if the buffer
26 * contains way more data than the V processor have seen.
28 #define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
31 * This macro "eats" the part of the buffer which is definitely "consumed",
32 * i.e. was correctly converted into local representation or rightfully skipped.
35 #define ADVANCE(num_bytes) do { \
36 size_t num = num_bytes; \
37 ptr = ((const char *)ptr) + num;\
41 consumed_myself += num; \
45 * Switch to the next phase of parsing.
49 #define NEXT_PHASE(ctx) do { \
53 #define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
56 * Return a standardized complex structure.
59 #define RETURN(_code) do { \
61 rval.consumed = consumed_myself;\
66 * The decoder of the SET OF type.
69 SET_OF_decode_ber(asn_codec_ctx_t
*opt_codec_ctx
, asn_TYPE_descriptor_t
*td
,
70 void **struct_ptr
, const void *ptr
, size_t size
, int tag_mode
) {
72 * Bring closer parts of structure description.
74 asn_SET_OF_specifics_t
*specs
= (asn_SET_OF_specifics_t
*)td
->specifics
;
75 asn_TYPE_member_t
*elm
= td
->elements
; /* Single one */
78 * Parts of the structure being constructed.
80 void *st
= *struct_ptr
; /* Target structure. */
81 asn_struct_ctx_t
*ctx
; /* Decoder context */
83 ber_tlv_tag_t tlv_tag
; /* T from TLV */
84 asn_dec_rval_t rval
; /* Return code from subparsers */
86 ssize_t consumed_myself
= 0; /* Consumed bytes from ptr */
88 ASN_DEBUG("Decoding %s as SET OF", td
->name
);
91 * Create the target structure if it is not present already.
94 st
= *struct_ptr
= CALLOC(1, specs
->struct_size
);
101 * Restore parsing context.
103 ctx
= (asn_struct_ctx_t
*)((char *)st
+ specs
->ctx_offset
);
106 * Start to parse where left previously
112 * Check that the set of tags associated with given structure
113 * perfectly fits our expectations.
116 rval
= ber_check_tags(opt_codec_ctx
, td
, ctx
, ptr
, size
,
117 tag_mode
, 1, &ctx
->left
, 0);
118 if(rval
.code
!= RC_OK
) {
119 ASN_DEBUG("%s tagging check failed: %d",
120 td
->name
, rval
.code
);
125 ctx
->left
+= rval
.consumed
; /* ?Substracted below! */
126 ADVANCE(rval
.consumed
);
128 ASN_DEBUG("Structure consumes %ld bytes, "
129 "buffer %ld", (long)ctx
->left
, (long)size
);
136 * From the place where we've left it previously,
137 * try to decode the next item.
139 for(;; ctx
->step
= 0) {
140 ssize_t tag_len
; /* Length of TLV's T */
146 * MICROPHASE 1: Synchronize decoding.
150 ASN_DEBUG("End of SET OF %s", td
->name
);
152 * No more things to decode.
160 * Fetch the T from TLV.
162 tag_len
= ber_fetch_tag(ptr
, LEFT
, &tlv_tag
);
164 case 0: if(!SIZE_VIOLATION
) RETURN(RC_WMORE
);
166 case -1: RETURN(RC_FAIL
);
169 if(ctx
->left
< 0 && ((const uint8_t *)ptr
)[0] == 0) {
175 } else if(((const uint8_t *)ptr
)[1] == 0) {
177 * Found the terminator of the
178 * indefinite length structure.
184 /* Outmost tag may be unknown and cannot be fetched/compared */
185 if(elm
->tag
!= (ber_tlv_tag_t
)-1) {
186 if(BER_TAGS_EQUAL(tlv_tag
, elm
->tag
)) {
188 * The new list member of expected type has arrived.
191 ASN_DEBUG("Unexpected tag %s fixed SET OF %s",
192 ber_tlv_tag_string(tlv_tag
), td
->name
);
193 ASN_DEBUG("%s SET OF has tag %s",
194 td
->name
, ber_tlv_tag_string(elm
->tag
));
200 * MICROPHASE 2: Invoke the member-specific decoder.
202 ctx
->step
|= 1; /* Confirm entering next microphase */
206 * Invoke the member fetch routine according to member's type
208 rval
= elm
->type
->ber_decoder(opt_codec_ctx
,
209 elm
->type
, &ctx
->ptr
, ptr
, LEFT
, 0);
210 ASN_DEBUG("In %s SET OF %s code %d consumed %d",
211 td
->name
, elm
->type
->name
,
212 rval
.code
, (int)rval
.consumed
);
216 asn_anonymous_set_
*list
= _A_SET_FROM_VOID(st
);
217 if(ASN_SET_ADD(list
, ctx
->ptr
) != 0)
223 case RC_WMORE
: /* More data expected */
224 if(!SIZE_VIOLATION
) {
225 ADVANCE(rval
.consumed
);
229 case RC_FAIL
: /* Fatal error */
230 ASN_STRUCT_FREE(*elm
->type
, ctx
->ptr
);
235 ADVANCE(rval
.consumed
);
236 } /* for(all list members) */
241 * Read in all "end of content" TLVs.
243 while(ctx
->left
< 0) {
245 if(LEFT
> 0 && ((const char *)ptr
)[0] != 0) {
252 if(((const char *)ptr
)[0] == 0
253 && ((const char *)ptr
)[1] == 0) {
268 * Internally visible buffer holding a single encoded element.
275 /* Append bytes to the above structure */
276 static int _el_addbytes(const void *buffer
, size_t size
, void *el_buf_ptr
) {
277 struct _el_buffer
*el_buf
= (struct _el_buffer
*)el_buf_ptr
;
279 if(el_buf
->length
+ size
> el_buf
->size
)
282 memcpy(el_buf
->buf
+ el_buf
->length
, buffer
, size
);
284 el_buf
->length
+= size
;
287 static int _el_buf_cmp(const void *ap
, const void *bp
) {
288 const struct _el_buffer
*a
= (const struct _el_buffer
*)ap
;
289 const struct _el_buffer
*b
= (const struct _el_buffer
*)bp
;
293 if(a
->length
< b
->length
)
294 common_len
= a
->length
;
296 common_len
= b
->length
;
298 ret
= memcmp(a
->buf
, b
->buf
, common_len
);
300 if(a
->length
< b
->length
)
302 else if(a
->length
> b
->length
)
310 * The DER encoder of the SET OF type.
313 SET_OF_encode_der(asn_TYPE_descriptor_t
*td
, void *ptr
,
314 int tag_mode
, ber_tlv_tag_t tag
,
315 asn_app_consume_bytes_f
*cb
, void *app_key
) {
316 asn_TYPE_member_t
*elm
= td
->elements
;
317 asn_TYPE_descriptor_t
*elm_type
= elm
->type
;
318 der_type_encoder_f
*der_encoder
= elm_type
->der_encoder
;
319 asn_anonymous_set_
*list
= _A_SET_FROM_VOID(ptr
);
320 size_t computed_size
= 0;
321 ssize_t encoding_size
= 0;
322 struct _el_buffer
*encoded_els
;
323 ssize_t eels_count
= 0;
324 size_t max_encoded_len
= 1;
325 asn_enc_rval_t erval
;
329 ASN_DEBUG("Estimating size for SET OF %s", td
->name
);
332 * Gather the length of the underlying members sequence.
334 for(edx
= 0; edx
< list
->count
; edx
++) {
335 void *memb_ptr
= list
->array
[edx
];
336 if(!memb_ptr
) continue;
337 erval
= der_encoder(elm_type
, memb_ptr
, 0, elm
->tag
, 0, 0);
338 if(erval
.encoded
== -1)
340 computed_size
+= erval
.encoded
;
342 /* Compute maximum encoding's size */
343 if(max_encoded_len
< (size_t)erval
.encoded
)
344 max_encoded_len
= erval
.encoded
;
348 * Encode the TLV for the sequence itself.
350 encoding_size
= der_write_tags(td
, computed_size
, tag_mode
, 1, tag
,
352 if(encoding_size
== -1) {
354 erval
.failed_type
= td
;
355 erval
.structure_ptr
= ptr
;
358 computed_size
+= encoding_size
;
360 if(!cb
|| list
->count
== 0) {
361 erval
.encoded
= computed_size
;
362 _ASN_ENCODED_OK(erval
);
366 * DER mandates dynamic sorting of the SET OF elements
367 * according to their encodings. Build an array of the
370 encoded_els
= (struct _el_buffer
*)MALLOC(
371 list
->count
* sizeof(encoded_els
[0]));
372 if(encoded_els
== NULL
) {
374 erval
.failed_type
= td
;
375 erval
.structure_ptr
= ptr
;
379 ASN_DEBUG("Encoding members of %s SET OF", td
->name
);
382 * Encode all members.
384 for(edx
= 0; edx
< list
->count
; edx
++) {
385 void *memb_ptr
= list
->array
[edx
];
386 struct _el_buffer
*encoded_el
= &encoded_els
[eels_count
];
388 if(!memb_ptr
) continue;
391 * Prepare space for encoding.
393 encoded_el
->buf
= (uint8_t *)MALLOC(max_encoded_len
);
394 if(encoded_el
->buf
) {
395 encoded_el
->length
= 0;
396 encoded_el
->size
= max_encoded_len
;
398 for(edx
--; edx
>= 0; edx
--)
399 FREEMEM(encoded_els
[edx
].buf
);
400 FREEMEM(encoded_els
);
402 erval
.failed_type
= td
;
403 erval
.structure_ptr
= ptr
;
408 * Encode the member into the prepared space.
410 erval
= der_encoder(elm_type
, memb_ptr
, 0, elm
->tag
,
411 _el_addbytes
, encoded_el
);
412 if(erval
.encoded
== -1) {
413 for(; edx
>= 0; edx
--)
414 FREEMEM(encoded_els
[edx
].buf
);
415 FREEMEM(encoded_els
);
418 encoding_size
+= erval
.encoded
;
423 * Sort the encoded elements according to their encoding.
425 qsort(encoded_els
, eels_count
, sizeof(encoded_els
[0]), _el_buf_cmp
);
428 * Report encoded elements to the application.
429 * Dispose of temporary sorted members table.
432 for(edx
= 0; edx
< eels_count
; edx
++) {
433 struct _el_buffer
*encoded_el
= &encoded_els
[edx
];
434 /* Report encoded chunks to the application */
436 && cb(encoded_el
->buf
, encoded_el
->length
, app_key
) < 0)
438 FREEMEM(encoded_el
->buf
);
440 FREEMEM(encoded_els
);
442 if(ret
|| computed_size
!= (size_t)encoding_size
) {
444 * Standard callback failed, or
445 * encoded size is not equal to the computed size.
448 erval
.failed_type
= td
;
449 erval
.structure_ptr
= ptr
;
451 erval
.encoded
= computed_size
;
454 _ASN_ENCODED_OK(erval
);
458 #define XER_ADVANCE(num_bytes) do { \
459 size_t num = num_bytes; \
460 buf_ptr = ((const char *)buf_ptr) + num;\
462 consumed_myself += num; \
466 * Decode the XER (XML) data.
469 SET_OF_decode_xer(asn_codec_ctx_t
*opt_codec_ctx
, asn_TYPE_descriptor_t
*td
,
470 void **struct_ptr
, const char *opt_mname
,
471 const void *buf_ptr
, size_t size
) {
473 * Bring closer parts of structure description.
475 asn_SET_OF_specifics_t
*specs
= (asn_SET_OF_specifics_t
*)td
->specifics
;
476 asn_TYPE_member_t
*element
= td
->elements
;
478 const char *xml_tag
= opt_mname
? opt_mname
: td
->xml_tag
;
481 * ... and parts of the structure being constructed.
483 void *st
= *struct_ptr
; /* Target structure. */
484 asn_struct_ctx_t
*ctx
; /* Decoder context */
486 asn_dec_rval_t rval
; /* Return value from a decoder */
487 ssize_t consumed_myself
= 0; /* Consumed bytes from ptr */
490 * Create the target structure if it is not present already.
493 st
= *struct_ptr
= CALLOC(1, specs
->struct_size
);
494 if(st
== 0) RETURN(RC_FAIL
);
497 /* Which tag is expected for the downstream */
498 if(specs
->as_XMLValueList
) {
499 elm_tag
= (specs
->as_XMLValueList
== 1) ? 0 : "";
501 elm_tag
= (*element
->name
)
502 ? element
->name
: element
->type
->xml_tag
;
506 * Restore parsing context.
508 ctx
= (asn_struct_ctx_t
*)((char *)st
+ specs
->ctx_offset
);
511 * Phases of XER/XML processing:
512 * Phase 0: Check that the opening tag matches our expectations.
513 * Phase 1: Processing body and reacting on closing tag.
514 * Phase 2: Processing inner type.
516 for(; ctx
->phase
<= 2;) {
517 pxer_chunk_type_e ch_type
; /* XER chunk type */
518 ssize_t ch_size
; /* Chunk size */
519 xer_check_tag_e tcv
; /* Tag check value */
522 * Go inside the inner member of a set.
524 if(ctx
->phase
== 2) {
525 asn_dec_rval_t tmprval
;
527 /* Invoke the inner type decoder, m.b. multiple times */
528 ASN_DEBUG("XER/SET OF element [%s]", elm_tag
);
529 tmprval
= element
->type
->xer_decoder(opt_codec_ctx
,
530 element
->type
, &ctx
->ptr
, elm_tag
,
532 if(tmprval
.code
== RC_OK
) {
533 asn_anonymous_set_
*list
= _A_SET_FROM_VOID(st
);
534 if(ASN_SET_ADD(list
, ctx
->ptr
) != 0)
537 XER_ADVANCE(tmprval
.consumed
);
539 XER_ADVANCE(tmprval
.consumed
);
540 RETURN(tmprval
.code
);
542 ctx
->phase
= 1; /* Back to body processing */
543 ASN_DEBUG("XER/SET OF phase => %d", ctx
->phase
);
548 * Get the next part of the XML stream.
550 ch_size
= xer_next_token(&ctx
->context
,
551 buf_ptr
, size
, &ch_type
);
553 case -1: RETURN(RC_FAIL
);
554 case 0: RETURN(RC_WMORE
);
557 case PXER_COMMENT
: /* Got XML comment */
558 case PXER_TEXT
: /* Ignore free-standing text */
559 XER_ADVANCE(ch_size
); /* Skip silently */
562 break; /* Check the rest down there */
566 tcv
= xer_check_tag(buf_ptr
, ch_size
, xml_tag
);
567 ASN_DEBUG("XER/SET OF: tcv = %d, ph=%d t=%s",
568 tcv
, ctx
->phase
, xml_tag
);
571 if(ctx
->phase
== 0) break;
575 if(ctx
->phase
== 0) {
576 /* No more things to decode */
577 XER_ADVANCE(ch_size
);
578 ctx
->phase
= 3; /* Phase out */
583 if(ctx
->phase
== 0) {
584 XER_ADVANCE(ch_size
);
585 ctx
->phase
= 1; /* Processing body phase */
592 ASN_DEBUG("XER/SET OF: tcv=%d, ph=%d", tcv
, ctx
->phase
);
593 if(ctx
->phase
== 1) {
595 * Process a single possible member.
605 ASN_DEBUG("Unexpected XML tag in SET OF");
609 ctx
->phase
= 3; /* "Phase out" on hard failure */
615 typedef struct xer_tmp_enc_s
{
621 SET_OF_encode_xer_callback(const void *buffer
, size_t size
, void *key
) {
622 xer_tmp_enc_t
*t
= (xer_tmp_enc_t
*)key
;
623 if(t
->offset
+ size
>= t
->size
) {
624 size_t newsize
= (t
->size
<< 2) + size
;
625 void *p
= REALLOC(t
->buffer
, newsize
);
630 memcpy((char *)t
->buffer
+ t
->offset
, buffer
, size
);
635 SET_OF_xer_order(const void *aptr
, const void *bptr
) {
636 const xer_tmp_enc_t
*a
= (const xer_tmp_enc_t
*)aptr
;
637 const xer_tmp_enc_t
*b
= (const xer_tmp_enc_t
*)bptr
;
638 size_t minlen
= a
->offset
;
640 if(b
->offset
< minlen
) minlen
= b
->offset
;
641 /* Well-formed UTF-8 has this nice lexicographical property... */
642 ret
= memcmp(a
->buffer
, b
->buffer
, minlen
);
643 if(ret
!= 0) return ret
;
644 if(a
->offset
== b
->offset
)
646 if(a
->offset
== minlen
)
653 SET_OF_encode_xer(asn_TYPE_descriptor_t
*td
, void *sptr
,
654 int ilevel
, enum xer_encoder_flags_e flags
,
655 asn_app_consume_bytes_f
*cb
, void *app_key
) {
657 asn_SET_OF_specifics_t
*specs
= (asn_SET_OF_specifics_t
*)td
->specifics
;
658 asn_TYPE_member_t
*elm
= td
->elements
;
659 asn_anonymous_set_
*list
= _A_SET_FROM_VOID(sptr
);
660 const char *mname
= specs
->as_XMLValueList
661 ? 0 : ((*elm
->name
) ? elm
->name
: elm
->type
->xml_tag
);
662 size_t mlen
= mname
? strlen(mname
) : 0;
663 int xcan
= (flags
& XER_F_CANONICAL
);
664 xer_tmp_enc_t
*encs
= 0;
665 size_t encs_count
= 0;
666 void *original_app_key
= app_key
;
667 asn_app_consume_bytes_f
*original_cb
= cb
;
670 if(!sptr
) _ASN_ENCODE_FAILED
;
673 encs
= (xer_tmp_enc_t
*)MALLOC(list
->count
* sizeof(encs
[0]));
674 if(!encs
) _ASN_ENCODE_FAILED
;
675 cb
= SET_OF_encode_xer_callback
;
680 for(i
= 0; i
< list
->count
; i
++) {
681 asn_enc_rval_t tmper
;
683 void *memb_ptr
= list
->array
[i
];
684 if(!memb_ptr
) continue;
687 memset(&encs
[encs_count
], 0, sizeof(encs
[0]));
688 app_key
= &encs
[encs_count
];
693 if(!xcan
) _i_ASN_TEXT_INDENT(1, ilevel
);
694 _ASN_CALLBACK3("<", 1, mname
, mlen
, ">", 1);
697 if(!xcan
&& specs
->as_XMLValueList
== 1)
698 _i_ASN_TEXT_INDENT(1, ilevel
+ 1);
699 tmper
= elm
->type
->xer_encoder(elm
->type
, memb_ptr
,
700 ilevel
+ (specs
->as_XMLValueList
!= 2),
702 if(tmper
.encoded
== -1) {
703 td
= tmper
.failed_type
;
704 sptr
= tmper
.structure_ptr
;
707 if(tmper
.encoded
== 0 && specs
->as_XMLValueList
) {
708 const char *name
= elm
->type
->xml_tag
;
709 size_t len
= strlen(name
);
710 _ASN_CALLBACK3("<", 1, name
, len
, "/>", 2);
714 _ASN_CALLBACK3("</", 2, mname
, mlen
, ">", 1);
718 er
.encoded
+= (2 * mlen
) + tmper
.encoded
;
721 if(!xcan
) _i_ASN_TEXT_INDENT(1, ilevel
- 1);
724 xer_tmp_enc_t
*enc
= encs
;
725 xer_tmp_enc_t
*end
= encs
+ encs_count
;
726 ssize_t control_size
= 0;
729 app_key
= original_app_key
;
730 qsort(encs
, encs_count
, sizeof(encs
[0]), SET_OF_xer_order
);
732 for(; enc
< end
; enc
++) {
733 _ASN_CALLBACK(enc
->buffer
, enc
->offset
);
734 FREEMEM(enc
->buffer
);
736 control_size
+= enc
->offset
;
738 assert(control_size
== er
.encoded
);
745 er
.structure_ptr
= sptr
;
748 while(encs_count
-- > 0) {
749 if(encs
[encs_count
].buffer
)
750 FREEMEM(encs
[encs_count
].buffer
);
758 SET_OF_print(asn_TYPE_descriptor_t
*td
, const void *sptr
, int ilevel
,
759 asn_app_consume_bytes_f
*cb
, void *app_key
) {
760 asn_TYPE_member_t
*elm
= td
->elements
;
761 const asn_anonymous_set_
*list
= _A_CSET_FROM_VOID(sptr
);
765 if(!sptr
) return (cb("<absent>", 8, app_key
) < 0) ? -1 : 0;
768 if(cb(td
->name
, strlen(td
->name
), app_key
) < 0
769 || cb(" ::= {", 6, app_key
) < 0)
772 for(i
= 0; i
< list
->count
; i
++) {
773 const void *memb_ptr
= list
->array
[i
];
774 if(!memb_ptr
) continue;
778 ret
= elm
->type
->print_struct(elm
->type
, memb_ptr
,
779 ilevel
+ 1, cb
, app_key
);
786 return (cb("}", 1, app_key
) < 0) ? -1 : 0;
790 SET_OF_free(asn_TYPE_descriptor_t
*td
, void *ptr
, int contents_only
) {
792 asn_SET_OF_specifics_t
*specs
;
793 asn_TYPE_member_t
*elm
= td
->elements
;
794 asn_anonymous_set_
*list
= _A_SET_FROM_VOID(ptr
);
795 asn_struct_ctx_t
*ctx
; /* Decoder context */
799 * Could not use set_of_empty() because of (*free)
802 for(i
= 0; i
< list
->count
; i
++) {
803 void *memb_ptr
= list
->array
[i
];
805 ASN_STRUCT_FREE(*elm
->type
, memb_ptr
);
807 list
->count
= 0; /* No meaningful elements left */
809 asn_set_empty(list
); /* Remove (list->array) */
811 specs
= (asn_SET_OF_specifics_t
*)td
->specifics
;
812 ctx
= (asn_struct_ctx_t
*)((char *)ptr
+ specs
->ctx_offset
);
814 ASN_STRUCT_FREE(*elm
->type
, ctx
->ptr
);
825 SET_OF_constraint(asn_TYPE_descriptor_t
*td
, const void *sptr
,
826 asn_app_constraint_failed_f
*ctfailcb
, void *app_key
) {
827 asn_TYPE_member_t
*elm
= td
->elements
;
828 asn_constr_check_f
*constr
;
829 const asn_anonymous_set_
*list
= _A_CSET_FROM_VOID(sptr
);
833 _ASN_CTFAIL(app_key
, td
, sptr
,
834 "%s: value not given (%s:%d)",
835 td
->name
, __FILE__
, __LINE__
);
839 constr
= elm
->memb_constraints
;
840 if(!constr
) constr
= elm
->type
->check_constraints
;
843 * Iterate over the members of an array.
844 * Validate each in turn, until one fails.
846 for(i
= 0; i
< list
->count
; i
++) {
847 const void *memb_ptr
= list
->array
[i
];
850 if(!memb_ptr
) continue;
852 ret
= constr(elm
->type
, memb_ptr
, ctfailcb
, app_key
);
857 * Cannot inherit it eralier:
858 * need to make sure we get the updated version.
860 if(!elm
->memb_constraints
)
861 elm
->memb_constraints
= elm
->type
->check_constraints
;
867 SET_OF_decode_uper(asn_codec_ctx_t
*opt_codec_ctx
, asn_TYPE_descriptor_t
*td
,
868 asn_per_constraints_t
*constraints
, void **sptr
, asn_per_data_t
*pd
) {
870 asn_SET_OF_specifics_t
*specs
= (asn_SET_OF_specifics_t
*)td
->specifics
;
871 asn_TYPE_member_t
*elm
= td
->elements
; /* Single one */
873 asn_anonymous_set_
*list
;
874 asn_per_constraint_t
*ct
;
878 if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx
))
882 * Create the target structure if it is not present already.
885 st
= *sptr
= CALLOC(1, specs
->struct_size
);
886 if(!st
) _ASN_DECODE_FAILED
;
888 list
= _A_SET_FROM_VOID(st
);
890 /* Figure out which constraints to use */
891 if(constraints
) ct
= &constraints
->size
;
892 else if(td
->per_constraints
) ct
= &td
->per_constraints
->size
;
895 if(ct
&& ct
->flags
& APC_EXTENSIBLE
) {
896 int value
= per_get_few_bits(pd
, 1);
897 if(value
< 0) _ASN_DECODE_STARVED
;
898 if(value
) ct
= 0; /* Not restricted! */
901 if(ct
&& ct
->effective_bits
>= 0) {
902 /* X.691, #19.5: No length determinant */
903 nelems
= per_get_few_bits(pd
, ct
->effective_bits
);
904 ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
905 (long)nelems
, ct
->lower_bound
, td
->name
);
906 if(nelems
< 0) _ASN_DECODE_STARVED
;
907 nelems
+= ct
->lower_bound
;
915 nelems
= uper_get_length(pd
,
916 ct
? ct
->effective_bits
: -1, &repeat
);
917 ASN_DEBUG("Got to decode %d elements (eff %d)",
918 (int)nelems
, (int)(ct
? ct
->effective_bits
: -1));
919 if(nelems
< 0) _ASN_DECODE_STARVED
;
922 for(i
= 0; i
< nelems
; i
++) {
924 ASN_DEBUG("SET OF %s decoding", elm
->type
->name
);
925 rv
= elm
->type
->uper_decoder(opt_codec_ctx
, elm
->type
,
926 elm
->per_constraints
, &ptr
, pd
);
927 ASN_DEBUG("%s SET OF %s decoded %d, %p",
928 td
->name
, elm
->type
->name
, rv
.code
, ptr
);
929 if(rv
.code
== RC_OK
) {
930 if(ASN_SET_ADD(list
, ptr
) == 0)
932 ASN_DEBUG("Failed to add element into %s",
937 ASN_DEBUG("Failed decoding %s of %s (SET OF)",
938 elm
->type
->name
, td
->name
);
940 if(ptr
) ASN_STRUCT_FREE(*elm
->type
, ptr
);
944 nelems
= -1; /* Allow uper_get_length() */
947 ASN_DEBUG("Decoded %s as SET OF", td
->name
);