constr_SEQUENCE_uper.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,
22  asn_per_data_t *pd) {
24  void *st = *sptr; /* Target structure. */
25  int extpresent; /* Extension additions are present */
26  uint8_t *opres; /* Presence of optional root members */
27  asn_per_data_t opmd;
28  asn_dec_rval_t rv;
29  size_t edx;
30 
31  (void)constraints;
32 
33  if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
35 
36  if(!st) {
37  st = *sptr = CALLOC(1, specs->struct_size);
38  if(!st) ASN__DECODE_FAILED;
39  }
40 
41  ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
42 
43  /* Handle extensions */
44  if(specs->first_extension < 0) {
45  extpresent = 0;
46  } else {
47  extpresent = per_get_few_bits(pd, 1);
48  if(extpresent < 0) ASN__DECODE_STARVED;
49  }
50 
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)) {
58  FREEMEM(opres);
60  }
61  opmd.buffer = opres;
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);
65  } else {
66  opres = 0;
67  }
68 
69  /*
70  * Get the sequence ROOT elements.
71  */
72  for(edx = 0;
73  edx < (specs->first_extension < 0 ? td->elements_count
74  : (size_t)specs->first_extension);
75  edx++) {
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 */
79 
80  assert(!IN_EXTENSION_GROUP(specs, edx));
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 
90  /* Deal with optionality */
91  if(elm->optional) {
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);
96  if(present == 0) {
97  /* This element is not present */
98  if(elm->default_value_set) {
99  /* Fill-in DEFAULT */
100  if(elm->default_value_set(memb_ptr2)) {
101  FREEMEM(opres);
103  }
104  ASN_DEBUG("Filled-in default");
105  }
106  /* The member is just not present */
107  continue;
108  }
109  /* Fall through */
110  }
111 
112  /* Fetch the member from the stream */
113  ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
114 
115  if(elm->flags & ATF_OPEN_TYPE) {
116  rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
117  } else {
118  rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
120  memb_ptr2, pd);
121  }
122  if(rv.code != RC_OK) {
123  ASN_DEBUG("Failed decode %s in %s",
124  elm->name, td->name);
125  FREEMEM(opres);
126  return rv;
127  }
128  }
129 
130  /* Optionality map is not needed anymore */
131  FREEMEM(opres);
132 
133  /*
134  * Deal with extensions.
135  */
136  if(extpresent) {
137  ssize_t bmlength;
138  uint8_t *epres; /* Presence of extension members */
139  asn_per_data_t epmd;
140 
141  bmlength = uper_get_nslength(pd);
142  if(bmlength < 0) ASN__DECODE_STARVED;
143 
144  ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
145 
146  epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
147  if(!epres) ASN__DECODE_STARVED;
148 
149  /* Get the extensions map */
150  if(per_get_many_bits(pd, epres, 0, bmlength)) {
151  FREEMEM(epres);
153  }
154 
155  memset(&epmd, 0, sizeof(epmd));
156  epmd.buffer = epres;
157  epmd.nbits = bmlength;
158  ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
159  td->name, (long)bmlength, *epres);
160 
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 */
166  int present;
167 
168  /* Fetch the pointer to this member */
169  if(elm->flags & ATF_POINTER) {
170  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
171  } else {
172  memb_ptr = (void *)((char *)st + elm->memb_offset);
173  memb_ptr2 = &memb_ptr;
174  }
175 
176  present = per_get_few_bits(&epmd, 1);
177  if(present <= 0) {
178  if(present < 0) break; /* No more extensions */
179  continue;
180  }
181 
182  ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
183  *memb_ptr2);
184  rv = uper_open_type_get(opt_codec_ctx, elm->type,
186  memb_ptr2, pd);
187  if(rv.code != RC_OK) {
188  FREEMEM(epres);
189  return rv;
190  }
191  }
192 
193  /* Skip over overflow extensions which aren't present
194  * in this system's version of the protocol */
195  for(;;) {
196  ASN_DEBUG("Getting overflow extensions");
197  switch(per_get_few_bits(&epmd, 1)) {
198  case -1: break;
199  case 0: continue;
200  default:
201  if(uper_open_type_skip(opt_codec_ctx, pd)) {
202  FREEMEM(epres);
204  }
205  ASN_DEBUG("Skipped overflow extension");
206  continue;
207  }
208  break;
209  }
210 
211  FREEMEM(epres);
212  }
213 
214  if(specs->first_extension >= 0) {
215  unsigned i;
216  /* Fill DEFAULT members in extensions */
217  for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
218  i++) {
219  asn_TYPE_member_t *elm;
220  void **memb_ptr2; /* Pointer to member pointer */
221 
222  edx = specs->oms[i];
223  elm = &td->elements[edx];
224 
225  if(!elm->default_value_set) continue;
226 
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;
231  } else {
232  continue; /* Extensions are all optionals */
233  }
234 
235  /* Set default value */
236  if(elm->default_value_set(memb_ptr2)) {
238  }
239  }
240  }
241 
242  rv.consumed = 0;
243  rv.code = RC_OK;
244  return rv;
245 }
246 
247 static int
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;
253  int exts_count = 0;
254  size_t edx;
255 
256  if(specs->first_extension < 0) {
257  return 0;
258  }
259 
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 */
265  int present;
266 
267  /* Fetch the pointer to this member */
268  if(elm->flags & ATF_POINTER) {
269  memb_ptr2 =
270  (const void *const *)((const char *)sptr + elm->memb_offset);
271  present = (*memb_ptr2 != 0);
272  } else {
273  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
274  memb_ptr2 = &memb_ptr;
275  present = 1;
276  }
277 
278  ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name,
279  elm->type->name, edx, present);
280  exts_count++;
281  exts_present += present;
282 
283  /* Encode as presence marker */
284  if(po1 && per_put_few_bits(po1, present, 1)) {
285  return -1;
286  }
287  /* Encode as open type field */
288  if(po2 && present
289  && uper_open_type_put(elm->type,
291  *memb_ptr2, po2))
292  return -1;
293  }
294 
295  return exts_present ? exts_count : 0;
296 }
297 
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};
305  int n_extensions;
306  size_t edx;
307  size_t i;
308 
309  (void)constraints;
310 
311  if(!sptr)
313 
314  er.encoded = 0;
315 
316  ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
317 
318  /*
319  * X.691#18.1 Whether structure is extensible
320  * and whether to encode extensions
321  */
322  if(specs->first_extension < 0) {
323  n_extensions = 0; /* There are no extensions to encode */
324  } else {
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)) {
329  }
330  }
331 
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 */
337  int present;
338 
339  edx = specs->oms[i];
340  elm = &td->elements[edx];
341 
342  /* Fetch the pointer to this member */
343  if(elm->flags & ATF_POINTER) {
344  memb_ptr2 =
345  (const void *const *)((const char *)sptr + elm->memb_offset);
346  present = (*memb_ptr2 != 0);
347  } else {
348  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
349  memb_ptr2 = &memb_ptr;
350  present = 1;
351  }
352 
353  /* Eliminate default values */
354  if(present && elm->default_value_cmp
355  && elm->default_value_cmp(*memb_ptr2) == 0)
356  present = 0;
357 
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))
364  }
365 
366  /*
367  * Encode the sequence ROOT elements.
368  */
369  ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
370  td->elements_count);
371  for(edx = 0;
372  edx < ((specs->first_extension < 0) ? td->elements_count
373  : (size_t)specs->first_extension);
374  edx++) {
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 */
378 
379  ASN_DEBUG("About to encode %s", elm->type->name);
380 
381  /* Fetch the pointer to this member */
382  if(elm->flags & ATF_POINTER) {
383  memb_ptr2 =
384  (const void *const *)((const char *)sptr + elm->memb_offset);
385  if(!*memb_ptr2) {
386  ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
387  elm->name, edx);
388  if(elm->optional)
389  continue;
390  /* Mandatory element is missing */
392  }
393  } else {
394  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
395  memb_ptr2 = &memb_ptr;
396  }
397 
398  /* Eliminate default values */
399  if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
400  continue;
401 
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,
405  po);
406  if(er.encoded == -1) return er;
407  }
408 
409  /* No extensions to encode */
410  if(!n_extensions) ASN__ENCODED_OK(er);
411 
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))
416 
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)
422 
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)
427 
428  ASN__ENCODED_OK(er);
429 }
asn_bit_outp_s
Definition: asn_bit_data.h:56
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__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
uper_open_type_put
int uper_open_type_put(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: uper_opentype.c:25
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
per_get_few_bits
#define per_get_few_bits(data, bits)
Definition: per_support.h:39
SEQUENCE__handle_extensions
static int SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr, asn_per_outp_t *po1, asn_per_outp_t *po2)
Definition: constr_SEQUENCE_uper.c:248
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
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
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
SEQUENCE_encode_uper
asn_enc_rval_t SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: constr_SEQUENCE_uper.c:299
ATF_OPEN_TYPE
@ ATF_OPEN_TYPE
Definition: constr_TYPE.h:269
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_PRI_SIZE
#define ASN_PRI_SIZE
Definition: asn_system.h:172
ASN__STACK_OVERFLOW_CHECK
static int CC_NOTUSED ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx)
Definition: asn_internal.h:165
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
size_t
static void ssize_t size_t
Definition: asn_internal.h:96
SEQUENCE_decode_uper
asn_dec_rval_t SEQUENCE_decode_uper(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_uper.c:19
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_SEQUENCE_specifics_s::oms
const int * oms
Definition: constr_SEQUENCE.h:31
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_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
uper_get_nslength
ssize_t uper_get_nslength(asn_per_data_t *pd)
Definition: uper_support.c:52
ASN__DECODE_FAILED
#define ASN__DECODE_FAILED
Definition: asn_codecs.h:90
asn_TYPE_operation_s::uper_encoder
per_type_encoder_f * uper_encoder
Definition: constr_TYPE.h:198
asn_TYPE_operation_s::uper_decoder
per_type_decoder_f * uper_decoder
Definition: constr_TYPE.h:197
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
IN_EXTENSION_GROUP
#define IN_EXTENSION_GROUP(specs, memb_idx)
Definition: constr_SEQUENCE_uper.c:14
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
uper_opentype.h
OPEN_TYPE_uper_get
asn_dec_rval_t OPEN_TYPE_uper_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_uper.c:12
uper_put_nslength
int uper_put_nslength(asn_per_outp_t *po, size_t length)
Definition: uper_support.c:201
uper_open_type_skip
int uper_open_type_skip(const asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd)
Definition: uper_opentype.c:262
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
uper_open_type_get
asn_dec_rval_t uper_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: uper_opentype.c:255
asn_TYPE_member_s::default_value_set
int(* default_value_set)(void **sptr)
Definition: constr_TYPE.h:282


etsi_its_spatem_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:29:28