2 * Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
7 #include <constr_SEQUENCE_OF.h>
8 #include <asn_SEQUENCE_OF.h>
11 * The DER encoder of the SEQUENCE OF type.
14 SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t
*td
, void *ptr
,
15 int tag_mode
, ber_tlv_tag_t tag
,
16 asn_app_consume_bytes_f
*cb
, void *app_key
) {
17 asn_TYPE_member_t
*elm
= td
->elements
;
18 asn_anonymous_sequence_
*list
= _A_SEQUENCE_FROM_VOID(ptr
);
19 size_t computed_size
= 0;
20 ssize_t encoding_size
= 0;
24 ASN_DEBUG("Estimating size of SEQUENCE OF %s", td
->name
);
27 * Gather the length of the underlying members sequence.
29 for(edx
= 0; edx
< list
->count
; edx
++) {
30 void *memb_ptr
= list
->array
[edx
];
31 if(!memb_ptr
) continue;
32 erval
= elm
->type
->der_encoder(elm
->type
, memb_ptr
,
35 if(erval
.encoded
== -1)
37 computed_size
+= erval
.encoded
;
41 * Encode the TLV for the sequence itself.
43 encoding_size
= der_write_tags(td
, computed_size
, tag_mode
, 1, tag
,
45 if(encoding_size
== -1) {
47 erval
.failed_type
= td
;
48 erval
.structure_ptr
= ptr
;
52 computed_size
+= encoding_size
;
54 erval
.encoded
= computed_size
;
55 _ASN_ENCODED_OK(erval
);
58 ASN_DEBUG("Encoding members of SEQUENCE OF %s", td
->name
);
63 for(edx
= 0; edx
< list
->count
; edx
++) {
64 void *memb_ptr
= list
->array
[edx
];
65 if(!memb_ptr
) continue;
66 erval
= elm
->type
->der_encoder(elm
->type
, memb_ptr
,
69 if(erval
.encoded
== -1)
71 encoding_size
+= erval
.encoded
;
74 if(computed_size
!= (size_t)encoding_size
) {
76 * Encoded size is not equal to the computed size.
79 erval
.failed_type
= td
;
80 erval
.structure_ptr
= ptr
;
82 erval
.encoded
= computed_size
;
83 erval
.structure_ptr
= 0;
84 erval
.failed_type
= 0;
91 SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t
*td
, void *sptr
,
92 int ilevel
, enum xer_encoder_flags_e flags
,
93 asn_app_consume_bytes_f
*cb
, void *app_key
) {
95 asn_SET_OF_specifics_t
*specs
= (asn_SET_OF_specifics_t
*)td
->specifics
;
96 asn_TYPE_member_t
*elm
= td
->elements
;
97 asn_anonymous_sequence_
*list
= _A_SEQUENCE_FROM_VOID(sptr
);
98 const char *mname
= specs
->as_XMLValueList
99 ? 0 : ((*elm
->name
) ? elm
->name
: elm
->type
->xml_tag
);
100 unsigned int mlen
= mname
? strlen(mname
) : 0;
101 int xcan
= (flags
& XER_F_CANONICAL
);
104 if(!sptr
) _ASN_ENCODE_FAILED
;
108 for(i
= 0; i
< list
->count
; i
++) {
109 asn_enc_rval_t tmper
;
110 void *memb_ptr
= list
->array
[i
];
111 if(!memb_ptr
) continue;
114 if(!xcan
) _i_ASN_TEXT_INDENT(1, ilevel
);
115 _ASN_CALLBACK3("<", 1, mname
, mlen
, ">", 1);
118 tmper
= elm
->type
->xer_encoder(elm
->type
, memb_ptr
,
119 ilevel
+ 1, flags
, cb
, app_key
);
120 if(tmper
.encoded
== -1) return tmper
;
121 if(tmper
.encoded
== 0 && specs
->as_XMLValueList
) {
122 const char *name
= elm
->type
->xml_tag
;
123 size_t len
= strlen(name
);
124 if(!xcan
) _i_ASN_TEXT_INDENT(1, ilevel
+ 1);
125 _ASN_CALLBACK3("<", 1, name
, len
, "/>", 2);
129 _ASN_CALLBACK3("</", 2, mname
, mlen
, ">", 1);
133 er
.encoded
+= (2 * mlen
) + tmper
.encoded
;
136 if(!xcan
) _i_ASN_TEXT_INDENT(1, ilevel
- 1);
144 SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t
*td
,
145 asn_per_constraints_t
*constraints
, void *sptr
, asn_per_outp_t
*po
) {
146 asn_anonymous_sequence_
*list
;
147 asn_per_constraint_t
*ct
;
149 asn_TYPE_member_t
*elm
= td
->elements
;
152 if(!sptr
) _ASN_ENCODE_FAILED
;
153 list
= _A_SEQUENCE_FROM_VOID(sptr
);
157 ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td
->name
, list
->count
);
159 if(constraints
) ct
= &constraints
->size
;
160 else if(td
->per_constraints
) ct
= &td
->per_constraints
->size
;
163 /* If extensible constraint, check if size is in root */
165 int not_in_root
= (list
->count
< ct
->lower_bound
166 || list
->count
> ct
->upper_bound
);
167 ASN_DEBUG("lb %ld ub %ld %s",
168 ct
->lower_bound
, ct
->upper_bound
,
169 ct
->flags
& APC_EXTENSIBLE
? "ext" : "fix");
170 if(ct
->flags
& APC_EXTENSIBLE
) {
171 /* Declare whether size is in extension root */
172 if(per_put_few_bits(po
, not_in_root
, 1))
174 if(not_in_root
) ct
= 0;
175 } else if(not_in_root
&& ct
->effective_bits
>= 0)
179 if(ct
&& ct
->effective_bits
>= 0) {
180 /* X.691, #19.5: No length determinant */
181 if(per_put_few_bits(po
, list
->count
- ct
->lower_bound
,
186 for(seq
= -1; seq
< list
->count
;) {
189 if(ct
&& ct
->effective_bits
>= 0) {
190 mayEncode
= list
->count
;
192 mayEncode
= uper_put_length(po
, list
->count
- seq
);
193 if(mayEncode
< 0) _ASN_ENCODE_FAILED
;
197 void *memb_ptr
= list
->array
[seq
++];
198 if(!memb_ptr
) _ASN_ENCODE_FAILED
;
199 er
= elm
->type
->uper_encoder(elm
->type
,
200 elm
->per_constraints
, memb_ptr
, po
);