constr_SEQUENCE_aper.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
10 
11 /*
12  * Check whether we are inside the extensions group.
13  */
14 #define IN_EXTENSION_GROUP(specs, memb_idx) \
15  ((specs)->first_extension >= 0 \
16  && (unsigned)(specs)->first_extension <= (memb_idx))
17 
20  const asn_TYPE_descriptor_t *td,
21  const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
23  void *st = *sptr; /* Target structure. */
24  int extpresent; /* Extension additions are present */
25  uint8_t *opres; /* Presence of optional root members */
26  asn_per_data_t opmd;
27  asn_dec_rval_t rv;
28  size_t edx;
29 
30  (void)constraints;
31 
32  if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
34 
35  if(!st) {
36  st = *sptr = CALLOC(1, specs->struct_size);
37  if(!st) ASN__DECODE_FAILED;
38  }
39 
40  ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
41 
42  /* Handle extensions */
43  if(specs->first_extension < 0) {
44  extpresent = 0;
45  } else {
46  extpresent = per_get_few_bits(pd, 1);
47  if(extpresent < 0) ASN__DECODE_STARVED;
48  }
49 
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)) {
57  FREEMEM(opres);
59  }
60  opmd.buffer = opres;
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);
64  } else {
65  opres = 0;
66  }
67 
68  /*
69  * Get the sequence ROOT elements.
70  */
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 */
75 #if 0
76  int padding;
77 #endif
78 
79  if(IN_EXTENSION_GROUP(specs, edx))
80  continue;
81 
82  /* Fetch the pointer to this member */
83  if(elm->flags & ATF_POINTER) {
84  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
85  } else {
86  memb_ptr = (char *)st + elm->memb_offset;
87  memb_ptr2 = &memb_ptr;
88  }
89 #if 0
90  /* Get Padding */
91  padding = (8 - (pd->moved % 8)) % 8;
92  if(padding > 0)
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);
99  else {
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);
102  else
103  per_get_few_bits(pd, padding);
104  }
105 #endif /* dealing with padding */
106 #endif
107  /* Deal with optionality */
108  if(elm->optional) {
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);
113  if(present == 0) {
114  /* This element is not present */
115  if(elm->default_value_set) {
116  /* Fill-in DEFAULT */
117  if(elm->default_value_set(memb_ptr2)) {
118  FREEMEM(opres);
120  }
121  ASN_DEBUG("Filled-in default");
122  }
123  /* The member is just not present */
124  continue;
125  }
126  /* Fall through */
127  }
128 
129  /* Fetch the member from the stream */
130  ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
131 
132  if(elm->flags & ATF_OPEN_TYPE) {
133  if (OPEN_TYPE_aper_is_unknown_type(td, st, elm)) {
135  FREEMEM(opres);
136  return rv;
137  }
138  rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
139  } else {
140  rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
142  memb_ptr2, pd);
143  }
144  if(rv.code != RC_OK) {
145  ASN_DEBUG("Failed decode %s in %s",
146  elm->name, td->name);
147  FREEMEM(opres);
148  return rv;
149  }
150  }
151 
152  /* Optionality map is not needed anymore */
153  FREEMEM(opres);
154 
155  /*
156  * Deal with extensions.
157  */
158  if(extpresent) {
159  ssize_t bmlength;
160  uint8_t *epres; /* Presence of extension members */
161  asn_per_data_t epmd;
162 
163  bmlength = aper_get_nslength(pd);
164  if(bmlength < 0) ASN__DECODE_STARVED;
165 
166  ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
167 
168  epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
169  if(!epres) ASN__DECODE_STARVED;
170 
171  /* Get the extensions map */
172  if(per_get_many_bits(pd, epres, 0, bmlength))
174 
175  memset(&epmd, 0, sizeof(epmd));
176  epmd.buffer = epres;
177  epmd.nbits = bmlength;
178  ASN_DEBUG("Read in extensions bitmap for %s of %zd bits (%x..)",
179  td->name, bmlength, *epres);
180 
181  /* Deal with padding */
182  if (aper_get_align(pd) < 0)
184 
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 */
190  int present;
191 
192  if(!IN_EXTENSION_GROUP(specs, edx)) {
193  ASN_DEBUG("%zu is not extension", edx);
194  continue;
195  }
196 
197  /* Fetch the pointer to this member */
198  if(elm->flags & ATF_POINTER) {
199  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
200  } else {
201  memb_ptr = (void *)((char *)st + elm->memb_offset);
202  memb_ptr2 = &memb_ptr;
203  }
204 
205  present = per_get_few_bits(&epmd, 1);
206  if(present <= 0) {
207  if(present < 0) break; /* No more extensions */
208  continue;
209  }
210 
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,
214  memb_ptr2, pd);
215  if(rv.code != RC_OK) {
216  FREEMEM(epres);
217  return rv;
218  }
219  }
220 
221  /* Skip over overflow extensions which aren't present
222  * in this system's version of the protocol */
223  for(;;) {
224  ASN_DEBUG("Getting overflow extensions");
225  switch(per_get_few_bits(&epmd, 1)) {
226  case -1:
227  break;
228  case 0:
229  continue;
230  default:
231  if(aper_open_type_skip(opt_codec_ctx, pd)) {
232  FREEMEM(epres);
234  }
235  }
236  break;
237  }
238 
239  FREEMEM(epres);
240  }
241 
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 */
247 
248  if(!elm->default_value_set) continue;
249 
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;
254  } else {
255  continue; /* Extensions are all optionals */
256  }
257 
258  /* Set default value */
259  if(elm->default_value_set(memb_ptr2)) {
261  }
262  }
263 
264  rv.consumed = 0;
265  rv.code = RC_OK;
266  return rv;
267 }
268 
269 static int
271  const void *sptr,
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;
276  int exts_count = 0;
277  size_t edx;
278 
279  if(specs->first_extension < 0) {
280  return 0;
281  }
282 
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 */
288  int present;
289 
290  if(!IN_EXTENSION_GROUP(specs, edx)) {
291  ASN_DEBUG("%s (@%zu) is not extension", elm->type->name, edx);
292  continue;
293  }
294 
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);
299  } else {
300  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
301  memb_ptr2 = &memb_ptr;
302  present = 1;
303  }
304 
305  ASN_DEBUG("checking %s (@%zu) present => %d",
306  elm->type->name, edx, present);
307  exts_count++;
308  exts_present += present;
309 
310  /* Encode as presence marker */
311  if(po1 && per_put_few_bits(po1, present, 1))
312  return -1;
313  /* Encode as open type field */
314  if(po2 && present && aper_open_type_put(elm->type,
316  *memb_ptr2, po2))
317  return -1;
318 
319  }
320 
321  return exts_present ? exts_count : 0;
322 }
323 
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};
331  int n_extensions;
332  size_t edx;
333  size_t i;
334 
335  (void)constraints;
336 
337  if(!sptr)
339 
340  er.encoded = 0;
341 
342  ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name);
343 
344  /*
345  * X.691#18.1 Whether structure is extensible
346  * and whether to encode extensions
347  */
348  if(specs->first_extension < 0) {
349  n_extensions = 0; /* There are no extensions to encode */
350  } else {
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)) {
355  }
356  }
357 
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 */
363  int present;
364 
365  edx = specs->oms[i];
366  elm = &td->elements[edx];
367 
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);
372  } else {
373  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
374  memb_ptr2 = &memb_ptr;
375  present = 1;
376  }
377 
378  /* Eliminate default values */
379  if(present && elm->default_value_cmp
380  && elm->default_value_cmp(*memb_ptr2) == 0)
381  present = 0;
382 
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))
389  }
390 
391  /*
392  * Encode the sequence ROOT elements.
393  */
394  ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
395  td->elements_count);
396  for(edx = 0;
397  edx < ((specs->first_extension < 0) ? td->elements_count
398  : (size_t)specs->first_extension);
399  edx++) {
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 */
403 
404  if(IN_EXTENSION_GROUP(specs, edx))
405  continue;
406 
407  ASN_DEBUG("About to encode %s", elm->type->name);
408 
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);
412  if(!*memb_ptr2) {
413  ASN_DEBUG("Element %s %zu not present",
414  elm->name, edx);
415  if(elm->optional)
416  continue;
417  /* Mandatory element is missing */
419  }
420  } else {
421  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
422  memb_ptr2 = &memb_ptr;
423  }
424 
425  /* Eliminate default values */
426  if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
427  continue;
428 
429  ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
430  er = elm->type->op->aper_encoder(elm->type,
432  *memb_ptr2, po);
433  if(er.encoded == -1)
434  return er;
435  }
436 
437  /* No extensions to encode */
438  if(!n_extensions) ASN__ENCODED_OK(er);
439 
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))
444 
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)
450 
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)
455 
456  ASN__ENCODED_OK(er);
457 }
aper_put_nslength
int aper_put_nslength(asn_per_outp_t *po, size_t length)
Definition: aper_support.c:234
asn_bit_outp_s
Definition: asn_bit_data.h:56
aper_open_type_skip
int aper_open_type_skip(const asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd)
Definition: aper_opentype.c:134
asn_TYPE_member_s::memb_offset
unsigned memb_offset
Definition: constr_TYPE.h:275
asn_bit_data_s::buffer
const uint8_t * buffer
Definition: asn_bit_data.h:18
asn_TYPE_operation_s::aper_encoder
per_type_encoder_f * aper_encoder
Definition: constr_TYPE.h:200
SEQUENCE_handle_extensions_aper
static int SEQUENCE_handle_extensions_aper(const asn_TYPE_descriptor_t *td, const void *sptr, asn_per_outp_t *po1, asn_per_outp_t *po2)
Definition: constr_SEQUENCE_aper.c:270
aper_open_type_get
asn_dec_rval_t aper_open_type_get(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
Definition: aper_opentype.c:125
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
asn_SEQUENCE_specifics_s::struct_size
unsigned struct_size
Definition: constr_SEQUENCE.h:18
asn_TYPE_descriptor_s::elements_count
unsigned elements_count
Definition: constr_TYPE.h:253
OPEN_TYPE.h
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
asn_enc_rval_s
Definition: asn_codecs.h:41
asn_SEQUENCE_specifics_s::roms_count
unsigned roms_count
Definition: constr_SEQUENCE.h:32
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
IN_EXTENSION_GROUP
#define IN_EXTENSION_GROUP(specs, memb_idx)
Definition: constr_SEQUENCE_aper.c:14
per_get_few_bits
#define per_get_few_bits(data, bits)
Definition: per_support.h:39
SEQUENCE_decode_aper
asn_dec_rval_t SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
Definition: constr_SEQUENCE_aper.c:19
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
aper_get_nslength
ssize_t aper_get_nslength(asn_per_data_t *pd)
Definition: aper_support.c:53
asn_bit_data_s
Definition: asn_bit_data.h:17
ATF_POINTER
@ ATF_POINTER
Definition: constr_TYPE.h:268
ASN__ENCODE_FAILED
#define ASN__ENCODE_FAILED
Definition: asn_codecs.h:59
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
asn_TYPE_member_s::type
asn_TYPE_descriptor_t * type
Definition: constr_TYPE.h:278
SEQUENCE_encode_aper
asn_enc_rval_t SEQUENCE_encode_aper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: constr_SEQUENCE_aper.c:325
aper_get_align
int32_t aper_get_align(asn_per_data_t *pd)
Definition: aper_support.c:10
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
ATF_OPEN_TYPE
@ ATF_OPEN_TYPE
Definition: constr_TYPE.h:269
OPEN_TYPE_aper_is_unknown_type
int OPEN_TYPE_aper_is_unknown_type(const asn_TYPE_descriptor_t *td, void *sptr, const asn_TYPE_member_t *elm)
Definition: OPEN_TYPE_aper.c:123
asn_TYPE_member_s::name
const char * name
Definition: constr_TYPE.h:283
RC_OK
@ RC_OK
Definition: asn_codecs.h:82
asn_TYPE_descriptor_s::op
asn_TYPE_operation_t * op
Definition: constr_TYPE.h:232
asn_SEQUENCE_specifics_s::first_extension
signed first_extension
Definition: constr_SEQUENCE.h:40
asn_TYPE_operation_s::aper_decoder
per_type_decoder_f * aper_decoder
Definition: constr_TYPE.h:199
OPEN_TYPE_aper_get
asn_dec_rval_t OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *parent_type, void *parent_structure, const asn_TYPE_member_t *element, asn_per_data_t *pd)
Definition: OPEN_TYPE_aper.c:12
aper_open_type_put
int aper_open_type_put(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: aper_opentype.c:89
ASN__STACK_OVERFLOW_CHECK
static int CC_NOTUSED ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx)
Definition: asn_internal.h:165
OPEN_TYPE_aper_unknown_type_discard_bytes
asn_dec_rval_t OPEN_TYPE_aper_unknown_type_discard_bytes(asn_per_data_t *pd)
Definition: OPEN_TYPE_aper.c:139
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
ASN__DECODE_STARVED
#define ASN__DECODE_STARVED
Definition: asn_codecs.h:97
per_get_many_bits
#define per_get_many_bits(data, dst, align, bits)
Definition: per_support.h:41
asn_encoding_constraints_s::per_constraints
const struct asn_per_constraints_s * per_constraints
Definition: constr_TYPE.h:213
ASN_PRI_SSIZE
#define ASN_PRI_SSIZE
Definition: asn_system.h:173
asn_SEQUENCE_specifics_s
Definition: constr_SEQUENCE.h:14
asn_internal.h
asn_bit_data_s::nbits
size_t nbits
Definition: asn_bit_data.h:20
asn_bit_data_s::moved
size_t moved
Definition: asn_bit_data.h:21
asn_codec_ctx_s
Definition: asn_codecs.h:23
asn_TYPE_descriptor_s::elements
struct asn_TYPE_member_s * elements
Definition: constr_TYPE.h:252
asn_dec_rval_s
Definition: asn_codecs.h:86
ASN__DECODE_FAILED
#define ASN__DECODE_FAILED
Definition: asn_codecs.h:90
aper_opentype.h
constr_SEQUENCE.h
asn_per_constraints_s
Definition: per_support.h:30
asn_SEQUENCE_specifics_s::aoms_count
unsigned aoms_count
Definition: constr_SEQUENCE.h:33
asn_TYPE_member_s
Definition: constr_TYPE.h:272
asn_TYPE_member_s::flags
enum asn_TYPE_flags_e flags
Definition: constr_TYPE.h:273
asn_TYPE_member_s::default_value_cmp
int(* default_value_cmp)(const void *sptr)
Definition: constr_TYPE.h:281
per_put_few_bits
#define per_put_few_bits(out, bits, obits)
Definition: per_support.h:46
asn_TYPE_member_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:280
asn_TYPE_member_s::optional
unsigned optional
Definition: constr_TYPE.h:274
asn_TYPE_member_s::default_value_set
int(* default_value_set)(void **sptr)
Definition: constr_TYPE.h:282


etsi_its_cam_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:21:23