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_SEQUENCE.h>
9 #include <aper_opentype.h>
12 * Check whether we are inside the extensions group.
14 #define IN_EXTENSION_GROUP(specs, memb_idx) \
15 ((specs)->first_extension >= 0 \
16 && (unsigned)(specs)->first_extension <= (memb_idx))
19 SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
20 const asn_TYPE_descriptor_t *td,
21 const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
22 const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
23 void *st = *sptr; /* Target structure. */
24 int extpresent; /* Extension additions are present */
25 uint8_t *opres; /* Presence of optional root members */
32 if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
36 st = *sptr = CALLOC(1, specs->struct_size);
37 if(!st) ASN__DECODE_FAILED;
40 ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
42 /* Handle extensions */
43 if(specs->first_extension < 0) {
46 extpresent = per_get_few_bits(pd, 1);
47 if(extpresent < 0) ASN__DECODE_STARVED;
50 /* Prepare a place and read-in the presence bitmap */
51 memset(&opmd, 0, sizeof(opmd));
52 if(specs->roms_count) {
53 opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
54 if(!opres) ASN__DECODE_FAILED;
55 /* Get the presence map */
56 if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
61 opmd.nbits = specs->roms_count;
62 ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
63 td->name, specs->roms_count, *opres);
69 * Get the sequence ROOT elements.
71 for(edx = 0; edx < td->elements_count; edx++) {
72 asn_TYPE_member_t *elm = &td->elements[edx];
73 void *memb_ptr; /* Pointer to the member */
74 void **memb_ptr2; /* Pointer to that pointer */
79 if(IN_EXTENSION_GROUP(specs, edx))
82 /* Fetch the pointer to this member */
83 if(elm->flags & ATF_POINTER) {
84 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
86 memb_ptr = (char *)st + elm->memb_offset;
87 memb_ptr2 = &memb_ptr;
91 padding = (8 - (pd->moved % 8)) % 8;
93 ASN_DEBUG("For element %s,offset= %ld Padding bits = %d", td->name, pd->moved, padding);
94 #if 0 /* old way of removing padding */
95 per_get_few_bits(pd, padding);
96 #else /* Experimental fix proposed by @mhanna123 */
97 if(edx != (td->elements_count-1))
98 per_get_few_bits(pd, padding);
100 if(specs->roms_count && (padding > 0))
101 ASN_DEBUG(">>>>> not skipping padding of %d bits for element:%ld out of %d", padding, edx, td->elements_count);
103 per_get_few_bits(pd, padding);
105 #endif /* dealing with padding */
107 /* Deal with optionality */
109 int present = per_get_few_bits(&opmd, 1);
110 ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
111 td->name, elm->name, present,
112 (int)opmd.nboff, (int)opmd.nbits);
114 /* This element is not present */
115 if(elm->default_value_set) {
116 /* Fill-in DEFAULT */
117 if(elm->default_value_set(memb_ptr2)) {
121 ASN_DEBUG("Filled-in default");
123 /* The member is just not present */
129 /* Fetch the member from the stream */
130 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
132 if(elm->flags & ATF_OPEN_TYPE) {
133 if (OPEN_TYPE_aper_is_unknown_type(td, st, elm)) {
134 rv = OPEN_TYPE_aper_unknown_type_discard_bytes(pd);
138 rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
140 rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
141 elm->encoding_constraints.per_constraints,
144 if(rv.code != RC_OK) {
145 ASN_DEBUG("Failed decode %s in %s",
146 elm->name, td->name);
152 /* Optionality map is not needed anymore */
156 * Deal with extensions.
160 uint8_t *epres; /* Presence of extension members */
163 bmlength = aper_get_nslength(pd);
164 if(bmlength < 0) ASN__DECODE_STARVED;
166 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
168 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
169 if(!epres) ASN__DECODE_STARVED;
171 /* Get the extensions map */
172 if(per_get_many_bits(pd, epres, 0, bmlength))
175 memset(&epmd, 0, sizeof(epmd));
177 epmd.nbits = bmlength;
178 ASN_DEBUG("Read in extensions bitmap for %s of %zd bits (%x..)",
179 td->name, bmlength, *epres);
181 /* Deal with padding */
182 if (aper_get_align(pd) < 0)
185 /* Go over extensions and read them in */
186 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
187 asn_TYPE_member_t *elm = &td->elements[edx];
188 void *memb_ptr; /* Pointer to the member */
189 void **memb_ptr2; /* Pointer to that pointer */
192 if(!IN_EXTENSION_GROUP(specs, edx)) {
193 ASN_DEBUG("%zu is not extension", edx);
197 /* Fetch the pointer to this member */
198 if(elm->flags & ATF_POINTER) {
199 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
201 memb_ptr = (void *)((char *)st + elm->memb_offset);
202 memb_ptr2 = &memb_ptr;
205 present = per_get_few_bits(&epmd, 1);
207 if(present < 0) break; /* No more extensions */
211 ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
212 rv = aper_open_type_get(opt_codec_ctx, elm->type,
213 elm->encoding_constraints.per_constraints,
215 if(rv.code != RC_OK) {
221 /* Skip over overflow extensions which aren't present
222 * in this system's version of the protocol */
224 ASN_DEBUG("Getting overflow extensions");
225 switch(per_get_few_bits(&epmd, 1)) {
231 if(aper_open_type_skip(opt_codec_ctx, pd)) {
242 /* Fill DEFAULT members in extensions */
243 for(edx = specs->roms_count; edx < specs->roms_count
244 + specs->aoms_count; edx++) {
245 asn_TYPE_member_t *elm = &td->elements[edx];
246 void **memb_ptr2; /* Pointer to member pointer */
248 if(!elm->default_value_set) continue;
250 /* Fetch the pointer to this member */
251 if(elm->flags & ATF_POINTER) {
252 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
253 if(*memb_ptr2) continue;
255 continue; /* Extensions are all optionals */
258 /* Set default value */
259 if(elm->default_value_set(memb_ptr2)) {
270 SEQUENCE_handle_extensions_aper(const asn_TYPE_descriptor_t *td,
272 asn_per_outp_t *po1, asn_per_outp_t *po2) {
273 const asn_SEQUENCE_specifics_t *specs
274 = (const asn_SEQUENCE_specifics_t *)td->specifics;
275 int exts_present = 0;
279 if(specs->first_extension < 0) {
283 /* Find out which extensions are present */
284 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
285 asn_TYPE_member_t *elm = &td->elements[edx];
286 const void *memb_ptr; /* Pointer to the member */
287 const void * const *memb_ptr2; /* Pointer to that pointer */
290 if(!IN_EXTENSION_GROUP(specs, edx)) {
291 ASN_DEBUG("%s (@%zu) is not extension", elm->type->name, edx);
295 /* Fetch the pointer to this member */
296 if(elm->flags & ATF_POINTER) {
297 memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
298 present = (*memb_ptr2 != 0);
300 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
301 memb_ptr2 = &memb_ptr;
305 ASN_DEBUG("checking %s (@%zu) present => %d",
306 elm->type->name, edx, present);
308 exts_present += present;
310 /* Encode as presence marker */
311 if(po1 && per_put_few_bits(po1, present, 1))
313 /* Encode as open type field */
314 if(po2 && present && aper_open_type_put(elm->type,
315 elm->encoding_constraints.per_constraints,
321 return exts_present ? exts_count : 0;
325 SEQUENCE_encode_aper(const asn_TYPE_descriptor_t *td,
326 const asn_per_constraints_t *constraints,
327 const void *sptr, asn_per_outp_t *po) {
328 const asn_SEQUENCE_specifics_t *specs
329 = (const asn_SEQUENCE_specifics_t *)td->specifics;
330 asn_enc_rval_t er = {0,0,0};
342 ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name);
345 * X.691#18.1 Whether structure is extensible
346 * and whether to encode extensions
348 if(specs->first_extension < 0) {
349 n_extensions = 0; /* There are no extensions to encode */
351 n_extensions = SEQUENCE_handle_extensions_aper(td, sptr, 0, 0);
352 if(n_extensions < 0) ASN__ENCODE_FAILED;
353 if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
358 /* Encode a presence bitmap */
359 for(i = 0; i < specs->roms_count; i++) {
360 asn_TYPE_member_t *elm;
361 const void *memb_ptr; /* Pointer to the member */
362 const void * const *memb_ptr2; /* Pointer to that pointer */
366 elm = &td->elements[edx];
368 /* Fetch the pointer to this member */
369 if(elm->flags & ATF_POINTER) {
370 memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
371 present = (*memb_ptr2 != 0);
373 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
374 memb_ptr2 = &memb_ptr;
378 /* Eliminate default values */
379 if(present && elm->default_value_cmp
380 && elm->default_value_cmp(*memb_ptr2) == 0)
383 ASN_DEBUG("Element %s %s %s->%s is %s",
384 elm->flags & ATF_POINTER ? "ptr" : "inline",
385 elm->default_value_cmp ? "def" : "wtv",
386 td->name, elm->name, present ? "present" : "absent");
387 if(per_put_few_bits(po, present, 1))
392 * Encode the sequence ROOT elements.
394 ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
397 edx < ((specs->first_extension < 0) ? td->elements_count
398 : (size_t)specs->first_extension);
400 asn_TYPE_member_t *elm = &td->elements[edx];
401 const void *memb_ptr; /* Pointer to the member */
402 const void * const *memb_ptr2; /* Pointer to that pointer */
404 if(IN_EXTENSION_GROUP(specs, edx))
407 ASN_DEBUG("About to encode %s", elm->type->name);
409 /* Fetch the pointer to this member */
410 if(elm->flags & ATF_POINTER) {
411 memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
413 ASN_DEBUG("Element %s %zu not present",
417 /* Mandatory element is missing */
421 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
422 memb_ptr2 = &memb_ptr;
425 /* Eliminate default values */
426 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
429 ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
430 er = elm->type->op->aper_encoder(elm->type,
431 elm->encoding_constraints.per_constraints,
437 /* No extensions to encode */
438 if(!n_extensions) ASN__ENCODED_OK(er);
440 ASN_DEBUG("Length of %d bit-map", n_extensions);
441 /* #18.8. Write down the presence bit-map length. */
442 if(aper_put_nslength(po, n_extensions))
445 ASN_DEBUG("Bit-map of %d elements", n_extensions);
446 /* #18.7. Encoding the extensions presence bit-map. */
447 /* TODO: act upon NOTE in #18.7 for canonical PER */
448 if(SEQUENCE_handle_extensions_aper(td, sptr, po, 0) != n_extensions)
451 ASN_DEBUG("Writing %d extensions", n_extensions);
452 /* #18.9. Encode extensions as open type fields. */
453 if(SEQUENCE_handle_extensions_aper(td, sptr, 0, po) != n_extensions)