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 <uper_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_uper(const asn_codec_ctx_t *opt_codec_ctx,
20 const asn_TYPE_descriptor_t *td,
21 const asn_per_constraints_t *constraints, void **sptr,
23 const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
24 void *st = *sptr; /* Target structure. */
25 int extpresent; /* Extension additions are present */
26 uint8_t *opres; /* Presence of optional root members */
33 if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
37 st = *sptr = CALLOC(1, specs->struct_size);
38 if(!st) ASN__DECODE_FAILED;
41 ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
43 /* Handle extensions */
44 if(specs->first_extension < 0) {
47 extpresent = per_get_few_bits(pd, 1);
48 if(extpresent < 0) ASN__DECODE_STARVED;
51 /* Prepare a place and read-in the presence bitmap */
52 memset(&opmd, 0, sizeof(opmd));
53 if(specs->roms_count) {
54 opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
55 if(!opres) ASN__DECODE_FAILED;
56 /* Get the presence map */
57 if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
62 opmd.nbits = specs->roms_count;
63 ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
64 td->name, specs->roms_count, *opres);
70 * Get the sequence ROOT elements.
73 edx < (specs->first_extension < 0 ? td->elements_count
74 : (size_t)specs->first_extension);
76 asn_TYPE_member_t *elm = &td->elements[edx];
77 void *memb_ptr; /* Pointer to the member */
78 void **memb_ptr2; /* Pointer to that pointer */
80 assert(!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;
90 /* Deal with optionality */
92 int present = per_get_few_bits(&opmd, 1);
93 ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
94 td->name, elm->name, present,
95 (int)opmd.nboff, (int)opmd.nbits);
97 /* This element is not present */
98 if(elm->default_value_set) {
100 if(elm->default_value_set(memb_ptr2)) {
104 ASN_DEBUG("Filled-in default");
106 /* The member is just not present */
112 /* Fetch the member from the stream */
113 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
115 if(elm->flags & ATF_OPEN_TYPE) {
116 rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
118 rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
119 elm->encoding_constraints.per_constraints,
122 if(rv.code != RC_OK) {
123 ASN_DEBUG("Failed decode %s in %s",
124 elm->name, td->name);
130 /* Optionality map is not needed anymore */
134 * Deal with extensions.
138 uint8_t *epres; /* Presence of extension members */
141 bmlength = uper_get_nslength(pd);
142 if(bmlength < 0) ASN__DECODE_STARVED;
144 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
146 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
147 if(!epres) ASN__DECODE_STARVED;
149 /* Get the extensions map */
150 if(per_get_many_bits(pd, epres, 0, bmlength)) {
155 memset(&epmd, 0, sizeof(epmd));
157 epmd.nbits = bmlength;
158 ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
159 td->name, (long)bmlength, *epres);
161 /* Go over extensions and read them in */
162 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
163 asn_TYPE_member_t *elm = &td->elements[edx];
164 void *memb_ptr; /* Pointer to the member */
165 void **memb_ptr2; /* Pointer to that pointer */
168 /* Fetch the pointer to this member */
169 if(elm->flags & ATF_POINTER) {
170 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
172 memb_ptr = (void *)((char *)st + elm->memb_offset);
173 memb_ptr2 = &memb_ptr;
176 present = per_get_few_bits(&epmd, 1);
178 if(present < 0) break; /* No more extensions */
182 ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
184 rv = uper_open_type_get(opt_codec_ctx, elm->type,
185 elm->encoding_constraints.per_constraints,
187 if(rv.code != RC_OK) {
193 /* Skip over overflow extensions which aren't present
194 * in this system's version of the protocol */
196 ASN_DEBUG("Getting overflow extensions");
197 switch(per_get_few_bits(&epmd, 1)) {
201 if(uper_open_type_skip(opt_codec_ctx, pd)) {
205 ASN_DEBUG("Skipped overflow extension");
214 if(specs->first_extension >= 0) {
216 /* Fill DEFAULT members in extensions */
217 for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
219 asn_TYPE_member_t *elm;
220 void **memb_ptr2; /* Pointer to member pointer */
223 elm = &td->elements[edx];
225 if(!elm->default_value_set) continue;
227 /* Fetch the pointer to this member */
228 if(elm->flags & ATF_POINTER) {
229 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
230 if(*memb_ptr2) continue;
232 continue; /* Extensions are all optionals */
235 /* Set default value */
236 if(elm->default_value_set(memb_ptr2)) {
248 SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
249 asn_per_outp_t *po1, asn_per_outp_t *po2) {
250 const asn_SEQUENCE_specifics_t *specs =
251 (const asn_SEQUENCE_specifics_t *)td->specifics;
252 int exts_present = 0;
256 if(specs->first_extension < 0) {
260 /* Find out which extensions are present */
261 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
262 asn_TYPE_member_t *elm = &td->elements[edx];
263 const void *memb_ptr; /* Pointer to the member */
264 const void *const *memb_ptr2; /* Pointer to that pointer */
267 /* Fetch the pointer to this member */
268 if(elm->flags & ATF_POINTER) {
270 (const void *const *)((const char *)sptr + elm->memb_offset);
271 present = (*memb_ptr2 != 0);
273 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
274 memb_ptr2 = &memb_ptr;
278 ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name,
279 elm->type->name, edx, present);
281 exts_present += present;
283 /* Encode as presence marker */
284 if(po1 && per_put_few_bits(po1, present, 1)) {
287 /* Encode as open type field */
289 && uper_open_type_put(elm->type,
290 elm->encoding_constraints.per_constraints,
295 return exts_present ? exts_count : 0;
299 SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
300 const asn_per_constraints_t *constraints, const void *sptr,
301 asn_per_outp_t *po) {
302 const asn_SEQUENCE_specifics_t *specs
303 = (const asn_SEQUENCE_specifics_t *)td->specifics;
304 asn_enc_rval_t er = {0,0,0};
316 ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
319 * X.691#18.1 Whether structure is extensible
320 * and whether to encode extensions
322 if(specs->first_extension < 0) {
323 n_extensions = 0; /* There are no extensions to encode */
325 n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
326 if(n_extensions < 0) ASN__ENCODE_FAILED;
327 if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
332 /* Encode a presence bitmap */
333 for(i = 0; i < specs->roms_count; i++) {
334 asn_TYPE_member_t *elm;
335 const void *memb_ptr; /* Pointer to the member */
336 const void *const *memb_ptr2; /* Pointer to that pointer */
340 elm = &td->elements[edx];
342 /* Fetch the pointer to this member */
343 if(elm->flags & ATF_POINTER) {
345 (const void *const *)((const char *)sptr + elm->memb_offset);
346 present = (*memb_ptr2 != 0);
348 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
349 memb_ptr2 = &memb_ptr;
353 /* Eliminate default values */
354 if(present && elm->default_value_cmp
355 && elm->default_value_cmp(*memb_ptr2) == 0)
358 ASN_DEBUG("Element %s %s %s->%s is %s",
359 elm->flags & ATF_POINTER ? "ptr" : "inline",
360 elm->default_value_cmp ? "def" : "wtv",
361 td->name, elm->name, present ? "present" : "absent");
362 if(per_put_few_bits(po, present, 1))
367 * Encode the sequence ROOT elements.
369 ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
372 edx < ((specs->first_extension < 0) ? td->elements_count
373 : (size_t)specs->first_extension);
375 asn_TYPE_member_t *elm = &td->elements[edx];
376 const void *memb_ptr; /* Pointer to the member */
377 const void *const *memb_ptr2; /* Pointer to that pointer */
379 ASN_DEBUG("About to encode %s", elm->type->name);
381 /* Fetch the pointer to this member */
382 if(elm->flags & ATF_POINTER) {
384 (const void *const *)((const char *)sptr + elm->memb_offset);
386 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
390 /* Mandatory element is missing */
394 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
395 memb_ptr2 = &memb_ptr;
398 /* Eliminate default values */
399 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
402 ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name);
403 er = elm->type->op->uper_encoder(
404 elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2,
406 if(er.encoded == -1) return er;
409 /* No extensions to encode */
410 if(!n_extensions) ASN__ENCODED_OK(er);
412 ASN_DEBUG("Length of extensions %d bit-map", n_extensions);
413 /* #18.8. Write down the presence bit-map length. */
414 if(uper_put_nslength(po, n_extensions))
417 ASN_DEBUG("Bit-map of %d elements", n_extensions);
418 /* #18.7. Encoding the extensions presence bit-map. */
419 /* TODO: act upon NOTE in #18.7 for canonical PER */
420 if(SEQUENCE__handle_extensions(td, sptr, po, 0) != n_extensions)
423 ASN_DEBUG("Writing %d extensions", n_extensions);
424 /* #18.9. Encode extensions as open type fields. */
425 if(SEQUENCE__handle_extensions(td, sptr, 0, po) != n_extensions)