ITS
constr_SEQUENCE.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
6 #include <asn_internal.h>
7 #include <constr_SEQUENCE.h>
8 #include <per_opentype.h>
9 
10 /*
11  * Number of bytes left for this structure.
12  * (ctx->left) indicates the number of bytes _transferred_ for the structure.
13  * (size) contains the number of bytes in the buffer passed.
14  */
15 #define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
16 
17 /*
18  * If the subprocessor function returns with an indication that it wants
19  * more data, it may well be a fatal decoding problem, because the
20  * size is constrained by the <TLV>'s L, even if the buffer size allows
21  * reading more data.
22  * For example, consider the buffer containing the following TLVs:
23  * <T:5><L:1><V> <T:6>...
24  * The TLV length clearly indicates that one byte is expected in V, but
25  * if the V processor returns with "want more data" even if the buffer
26  * contains way more data than the V processor have seen.
27  */
28 #define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
29 
30 /*
31  * This macro "eats" the part of the buffer which is definitely "consumed",
32  * i.e. was correctly converted into local representation or rightfully skipped.
33  */
34 #undef ADVANCE
35 #define ADVANCE(num_bytes) do { \
36  size_t num = num_bytes; \
37  ptr = ((const char *)ptr) + num; \
38  size -= num; \
39  if(ctx->left >= 0) \
40  ctx->left -= num; \
41  consumed_myself += num; \
42  } while(0)
43 
44 /*
45  * Switch to the next phase of parsing.
46  */
47 #undef NEXT_PHASE
48 #undef PHASE_OUT
49 #define NEXT_PHASE(ctx) do { \
50  ctx->phase++; \
51  ctx->step = 0; \
52  } while(0)
53 #define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
54 
55 /*
56  * Return a standardized complex structure.
57  */
58 #undef RETURN
59 #define RETURN(_code) do { \
60  rval.code = _code; \
61  rval.consumed = consumed_myself;\
62  return rval; \
63  } while(0)
64 
65 /*
66  * Check whether we are inside the extensions group.
67  */
68 #define IN_EXTENSION_GROUP(specs, memb_idx) \
69  ( ((memb_idx) > (specs)->ext_after) \
70  &&((memb_idx) < (specs)->ext_before))
71 
72 
73 /*
74  * Tags are canonically sorted in the tag2element map.
75  */
76 static int
77 _t2e_cmp(const void *ap, const void *bp) {
78  const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
79  const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
80 
81  int a_class = BER_TAG_CLASS(a->el_tag);
82  int b_class = BER_TAG_CLASS(b->el_tag);
83 
84  if(a_class == b_class) {
85  ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
86  ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
87 
88  if(a_value == b_value) {
89  if(a->el_no > b->el_no)
90  return 1;
91  /*
92  * Important: we do not check
93  * for a->el_no <= b->el_no!
94  */
95  return 0;
96  } else if(a_value < b_value)
97  return -1;
98  else
99  return 1;
100  } else if(a_class < b_class) {
101  return -1;
102  } else {
103  return 1;
104  }
105 }
106 
107 
108 /*
109  * The decoder of the SEQUENCE type.
110  */
113  void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
114  /*
115  * Bring closer parts of structure description.
116  */
118  asn_TYPE_member_t *elements = td->elements;
119 
120  /*
121  * Parts of the structure being constructed.
122  */
123  void *st = *struct_ptr; /* Target structure. */
124  asn_struct_ctx_t *ctx; /* Decoder context */
125 
126  ber_tlv_tag_t tlv_tag; /* T from TLV */
127  asn_dec_rval_t rval; /* Return code from subparsers */
128 
129  ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
130  int edx; /* SEQUENCE element's index */
131 
132  ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
133 
134  /*
135  * Create the target structure if it is not present already.
136  */
137  if(st == 0) {
138  st = *struct_ptr = CALLOC(1, specs->struct_size);
139  if(st == 0) {
140  RETURN(RC_FAIL);
141  }
142  }
143 
144  /*
145  * Restore parsing context.
146  */
147  ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
148 
149  /*
150  * Start to parse where left previously
151  */
152  switch(ctx->phase) {
153  case 0:
154  /*
155  * PHASE 0.
156  * Check that the set of tags associated with given structure
157  * perfectly fits our expectations.
158  */
159 
160  rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
161  tag_mode, 1, &ctx->left, 0);
162  if(rval.code != RC_OK) {
163  ASN_DEBUG("%s tagging check failed: %d",
164  td->name, rval.code);
165  return rval;
166  }
167 
168  if(ctx->left >= 0)
169  ctx->left += rval.consumed; /* ?Substracted below! */
170  ADVANCE(rval.consumed);
171 
172  NEXT_PHASE(ctx);
173 
174  ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
175  (long)ctx->left, (long)size);
176 
177  /* Fall through */
178  case 1:
179  /*
180  * PHASE 1.
181  * From the place where we've left it previously,
182  * try to decode the next member from the list of
183  * this structure's elements.
184  * (ctx->step) stores the member being processed
185  * between invocations and the microphase {0,1} of parsing
186  * that member:
187  * step = (<member_number> * 2 + <microphase>).
188  */
189  for(edx = (ctx->step >> 1); edx < td->elements_count;
190  edx++, ctx->step = (ctx->step & ~1) + 2) {
191  void *memb_ptr; /* Pointer to the member */
192  void **memb_ptr2; /* Pointer to that pointer */
193  ssize_t tag_len; /* Length of TLV's T */
194  int opt_edx_end; /* Next non-optional element */
195  int use_bsearch;
196  int n;
197 
198  if(ctx->step & 1)
199  goto microphase2;
200 
201  /*
202  * MICROPHASE 1: Synchronize decoding.
203  */
204  ASN_DEBUG("In %s SEQUENCE left %d, edx=%d flags=%d"
205  " opt=%d ec=%d",
206  td->name, (int)ctx->left, edx,
207  elements[edx].flags, elements[edx].optional,
208  td->elements_count);
209 
210  if(ctx->left == 0 /* No more stuff is expected */
211  && (
212  /* Explicit OPTIONAL specification reaches the end */
213  (edx + elements[edx].optional
214  == td->elements_count)
215  ||
216  /* All extensions are optional */
217  (IN_EXTENSION_GROUP(specs, edx)
218  && specs->ext_before > td->elements_count)
219  )
220  ) {
221  ASN_DEBUG("End of SEQUENCE %s", td->name);
222  /*
223  * Found the legitimate end of the structure.
224  */
225  PHASE_OUT(ctx);
226  RETURN(RC_OK);
227  }
228 
229  /*
230  * Fetch the T from TLV.
231  */
232  tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
233  ASN_DEBUG("Current tag in %s SEQUENCE for element %d "
234  "(%s) is %s encoded in %d bytes, of frame %ld",
235  td->name, edx, elements[edx].name,
236  ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
237  switch(tag_len) {
238  case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
239  /* Fall through */
240  case -1: RETURN(RC_FAIL);
241  }
242 
243  if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
244  if(LEFT < 2) {
245  if(SIZE_VIOLATION)
246  RETURN(RC_FAIL);
247  else
248  RETURN(RC_WMORE);
249  } else if(((const uint8_t *)ptr)[1] == 0) {
250  ASN_DEBUG("edx = %d, opt = %d, ec=%d",
251  edx, elements[edx].optional,
252  td->elements_count);
253  if((edx + elements[edx].optional
254  == td->elements_count)
255  || (IN_EXTENSION_GROUP(specs, edx)
256  && specs->ext_before
257  > td->elements_count)) {
258  /*
259  * Yeah, baby! Found the terminator
260  * of the indefinite length structure.
261  */
262  /*
263  * Proceed to the canonical
264  * finalization function.
265  * No advancing is necessary.
266  */
267  goto phase3;
268  }
269  }
270  }
271 
272  /*
273  * Find the next available type with this tag.
274  */
275  use_bsearch = 0;
276  opt_edx_end = edx + elements[edx].optional + 1;
277  if(opt_edx_end > td->elements_count)
278  opt_edx_end = td->elements_count; /* Cap */
279  else if(opt_edx_end - edx > 8) {
280  /* Limit the scope of linear search... */
281  opt_edx_end = edx + 8;
282  use_bsearch = 1;
283  /* ... and resort to bsearch() */
284  }
285  for(n = edx; n < opt_edx_end; n++) {
286  if(BER_TAGS_EQUAL(tlv_tag, elements[n].tag)) {
287  /*
288  * Found element corresponding to the tag
289  * being looked at.
290  * Reposition over the right element.
291  */
292  edx = n;
293  ctx->step = 1 + 2 * edx; /* Remember! */
294  goto microphase2;
295  } else if(elements[n].flags & ATF_OPEN_TYPE) {
296  /*
297  * This is the ANY type, which may bear
298  * any flag whatsoever.
299  */
300  edx = n;
301  ctx->step = 1 + 2 * edx; /* Remember! */
302  goto microphase2;
303  } else if(elements[n].tag == (ber_tlv_tag_t)-1) {
304  use_bsearch = 1;
305  break;
306  }
307  }
308  if(use_bsearch) {
309  /*
310  * Resort to a binary search over
311  * sorted array of tags.
312  */
315  key.el_tag = tlv_tag;
316  key.el_no = edx;
317  t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
318  specs->tag2el, specs->tag2el_count,
319  sizeof(specs->tag2el[0]), _t2e_cmp);
320  if(t2m) {
321  asn_TYPE_tag2member_t *best = 0;
322  asn_TYPE_tag2member_t *t2m_f, *t2m_l;
323  int edx_max = edx + elements[edx].optional;
324  /*
325  * Rewind to the first element with that tag,
326  * `cause bsearch() does not guarantee order.
327  */
328  t2m_f = t2m + t2m->toff_first;
329  t2m_l = t2m + t2m->toff_last;
330  for(t2m = t2m_f; t2m <= t2m_l; t2m++) {
331  if(t2m->el_no > edx_max) break;
332  if(t2m->el_no < edx) continue;
333  best = t2m;
334  }
335  if(best) {
336  edx = best->el_no;
337  ctx->step = 1 + 2 * edx;
338  goto microphase2;
339  }
340  }
341  n = opt_edx_end;
342  }
343  if(n == opt_edx_end) {
344  /*
345  * If tag is unknown, it may be either
346  * an unknown (thus, incorrect) tag,
347  * or an extension (...),
348  * or an end of the indefinite-length structure.
349  */
350  if(!IN_EXTENSION_GROUP(specs,
351  edx + elements[edx].optional)) {
352  ASN_DEBUG("Unexpected tag %s (at %d)",
353  ber_tlv_tag_string(tlv_tag), edx);
354  ASN_DEBUG("Expected tag %s (%s)%s",
355  ber_tlv_tag_string(elements[edx].tag),
356  elements[edx].name,
357  elements[edx].optional
358  ?" or alternatives":"");
359  RETURN(RC_FAIL);
360  } else {
361  /* Skip this tag */
362  ssize_t skip;
363  edx += elements[edx].optional;
364 
365  ASN_DEBUG("Skipping unexpected %s (at %d)",
366  ber_tlv_tag_string(tlv_tag), edx);
367  skip = ber_skip_length(opt_codec_ctx,
368  BER_TLV_CONSTRUCTED(ptr),
369  (const char *)ptr + tag_len,
370  LEFT - tag_len);
371  ASN_DEBUG("Skip length %d in %s",
372  (int)skip, td->name);
373  switch(skip) {
374  case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
375  /* Fall through */
376  case -1: RETURN(RC_FAIL);
377  }
378 
379  ADVANCE(skip + tag_len);
380  ctx->step -= 2;
381  edx--;
382  continue; /* Try again with the next tag */
383  }
384  }
385 
386  /*
387  * MICROPHASE 2: Invoke the member-specific decoder.
388  */
389  ctx->step |= 1; /* Confirm entering next microphase */
390  microphase2:
391  ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
392 
393  /*
394  * Compute the position of the member inside a structure,
395  * and also a type of containment (it may be contained
396  * as pointer or using inline inclusion).
397  */
398  if(elements[edx].flags & ATF_POINTER) {
399  /* Member is a pointer to another structure */
400  memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
401  } else {
402  /*
403  * A pointer to a pointer
404  * holding the start of the structure
405  */
406  memb_ptr = (char *)st + elements[edx].memb_offset;
407  memb_ptr2 = &memb_ptr;
408  }
409  /*
410  * Invoke the member fetch routine according to member's type
411  */
412  rval = elements[edx].type->ber_decoder(opt_codec_ctx,
413  elements[edx].type,
414  memb_ptr2, ptr, LEFT,
415  elements[edx].tag_mode);
416  ASN_DEBUG("In %s SEQUENCE decoded %d %s of %d "
417  "in %d bytes rval.code %d, size=%d",
418  td->name, edx, elements[edx].type->name,
419  (int)LEFT, (int)rval.consumed, rval.code, (int)size);
420  switch(rval.code) {
421  case RC_OK:
422  break;
423  case RC_WMORE: /* More data expected */
424  if(!SIZE_VIOLATION) {
425  ADVANCE(rval.consumed);
426  RETURN(RC_WMORE);
427  }
428  ASN_DEBUG("Size violation (c->l=%ld <= s=%ld)",
429  (long)ctx->left, (long)size);
430  /* Fall through */
431  case RC_FAIL: /* Fatal error */
432  RETURN(RC_FAIL);
433  } /* switch(rval) */
434 
435  ADVANCE(rval.consumed);
436  } /* for(all structure members) */
437 
438  phase3:
439  ctx->phase = 3;
440  case 3: /* 00 and other tags expected */
441  case 4: /* only 00's expected */
442 
443  ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
444  td->name, (long)ctx->left, (long)size);
445 
446  /*
447  * Skip everything until the end of the SEQUENCE.
448  */
449  while(ctx->left) {
450  ssize_t tl, ll;
451 
452  tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
453  switch(tl) {
454  case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
455  /* Fall through */
456  case -1: RETURN(RC_FAIL);
457  }
458 
459  /*
460  * If expected <0><0>...
461  */
462  if(ctx->left < 0
463  && ((const uint8_t *)ptr)[0] == 0) {
464  if(LEFT < 2) {
465  if(SIZE_VIOLATION)
466  RETURN(RC_FAIL);
467  else
468  RETURN(RC_WMORE);
469  } else if(((const uint8_t *)ptr)[1] == 0) {
470  /*
471  * Correctly finished with <0><0>.
472  */
473  ADVANCE(2);
474  ctx->left++;
475  ctx->phase = 4;
476  continue;
477  }
478  }
479 
480  if(!IN_EXTENSION_GROUP(specs, td->elements_count)
481  || ctx->phase == 4) {
482  ASN_DEBUG("Unexpected continuation "
483  "of a non-extensible type "
484  "%s (SEQUENCE): %s",
485  td->name,
486  ber_tlv_tag_string(tlv_tag));
487  RETURN(RC_FAIL);
488  }
489 
490  ll = ber_skip_length(opt_codec_ctx,
491  BER_TLV_CONSTRUCTED(ptr),
492  (const char *)ptr + tl, LEFT - tl);
493  switch(ll) {
494  case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
495  /* Fall through */
496  case -1: RETURN(RC_FAIL);
497  }
498 
499  ADVANCE(tl + ll);
500  }
501 
502  PHASE_OUT(ctx);
503  }
504 
505  RETURN(RC_OK);
506 }
507 
508 
509 /*
510  * The DER encoder of the SEQUENCE type.
511  */
514  void *sptr, int tag_mode, ber_tlv_tag_t tag,
515  asn_app_consume_bytes_f *cb, void *app_key) {
516  size_t computed_size = 0;
517  asn_enc_rval_t erval;
518  ssize_t ret;
519  int edx;
520 
521  ASN_DEBUG("%s %s as SEQUENCE",
522  cb?"Encoding":"Estimating", td->name);
523 
524  /*
525  * Gather the length of the underlying members sequence.
526  */
527  for(edx = 0; edx < td->elements_count; edx++) {
528  asn_TYPE_member_t *elm = &td->elements[edx];
529  void *memb_ptr;
530  if(elm->flags & ATF_POINTER) {
531  memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
532  if(!memb_ptr) {
533  if(elm->optional) continue;
534  /* Mandatory element is missing */
536  }
537  } else {
538  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
539  }
540  erval = elm->type->der_encoder(elm->type, memb_ptr,
541  elm->tag_mode, elm->tag,
542  0, 0);
543  if(erval.encoded == -1)
544  return erval;
545  computed_size += erval.encoded;
546  ASN_DEBUG("Member %d %s estimated %ld bytes",
547  edx, elm->name, (long)erval.encoded);
548  }
549 
550  /*
551  * Encode the TLV for the sequence itself.
552  */
553  ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
554  ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
555  if(ret == -1)
557  erval.encoded = computed_size + ret;
558 
559  if(!cb) _ASN_ENCODED_OK(erval);
560 
561  /*
562  * Encode all members.
563  */
564  for(edx = 0; edx < td->elements_count; edx++) {
565  asn_TYPE_member_t *elm = &td->elements[edx];
566  asn_enc_rval_t tmperval;
567  void *memb_ptr;
568 
569  if(elm->flags & ATF_POINTER) {
570  memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
571  if(!memb_ptr) continue;
572  } else {
573  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
574  }
575  tmperval = elm->type->der_encoder(elm->type, memb_ptr,
576  elm->tag_mode, elm->tag,
577  cb, app_key);
578  if(tmperval.encoded == -1)
579  return tmperval;
580  computed_size -= tmperval.encoded;
581  ASN_DEBUG("Member %d %s of SEQUENCE %s encoded in %ld bytes",
582  edx, elm->name, td->name, (long)tmperval.encoded);
583  }
584 
585  if(computed_size != 0)
586  /*
587  * Encoded size is not equal to the computed size.
588  */
590 
591  _ASN_ENCODED_OK(erval);
592 }
593 
594 
595 #undef XER_ADVANCE
596 #define XER_ADVANCE(num_bytes) do { \
597  size_t num = num_bytes; \
598  buf_ptr = ((const char *)buf_ptr) + num;\
599  size -= num; \
600  consumed_myself += num; \
601  } while(0)
602 
603 /*
604  * Decode the XER (XML) data.
605  */
608  void **struct_ptr, const char *opt_mname,
609  const void *buf_ptr, size_t size) {
610  /*
611  * Bring closer parts of structure description.
612  */
615  asn_TYPE_member_t *elements = td->elements;
616  const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
617 
618  /*
619  * ... and parts of the structure being constructed.
620  */
621  void *st = *struct_ptr; /* Target structure. */
622  asn_struct_ctx_t *ctx; /* Decoder context */
623 
624  asn_dec_rval_t rval; /* Return value from a decoder */
625  ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
626  int edx; /* Element index */
627  int edx_end;
628 
629  /*
630  * Create the target structure if it is not present already.
631  */
632  if(st == 0) {
633  st = *struct_ptr = CALLOC(1, specs->struct_size);
634  if(st == 0) RETURN(RC_FAIL);
635  }
636 
637  /*
638  * Restore parsing context.
639  */
640  ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
641 
642 
643  /*
644  * Phases of XER/XML processing:
645  * Phase 0: Check that the opening tag matches our expectations.
646  * Phase 1: Processing body and reacting on closing tag.
647  * Phase 2: Processing inner type.
648  * Phase 3: Skipping unknown extensions.
649  * Phase 4: PHASED OUT
650  */
651  for(edx = ctx->step; ctx->phase <= 3;) {
652  pxer_chunk_type_e ch_type; /* XER chunk type */
653  ssize_t ch_size; /* Chunk size */
654  xer_check_tag_e tcv; /* Tag check value */
655  asn_TYPE_member_t *elm;
656  int n;
657 
658  /*
659  * Go inside the inner member of a sequence.
660  */
661  if(ctx->phase == 2) {
662  asn_dec_rval_t tmprval;
663  void *memb_ptr; /* Pointer to the member */
664  void **memb_ptr2; /* Pointer to that pointer */
665 
666  elm = &td->elements[edx];
667 
668  if(elm->flags & ATF_POINTER) {
669  /* Member is a pointer to another structure */
670  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
671  } else {
672  memb_ptr = (char *)st + elm->memb_offset;
673  memb_ptr2 = &memb_ptr;
674  }
675 
676  /* Invoke the inner type decoder, m.b. multiple times */
677  tmprval = elm->type->xer_decoder(opt_codec_ctx,
678  elm->type, memb_ptr2, elm->name,
679  buf_ptr, size);
680  XER_ADVANCE(tmprval.consumed);
681  if(tmprval.code != RC_OK)
682  RETURN(tmprval.code);
683  ctx->phase = 1; /* Back to body processing */
684  ctx->step = ++edx;
685  ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
686  ctx->phase, ctx->step);
687  /* Fall through */
688  }
689 
690  /*
691  * Get the next part of the XML stream.
692  */
693  ch_size = xer_next_token(&ctx->context, buf_ptr, size,
694  &ch_type);
695  switch(ch_size) {
696  case -1: RETURN(RC_FAIL);
697  case 0: RETURN(RC_WMORE);
698  default:
699  switch(ch_type) {
700  case PXER_COMMENT: /* Got XML comment */
701  case PXER_TEXT: /* Ignore free-standing text */
702  XER_ADVANCE(ch_size); /* Skip silently */
703  continue;
704  case PXER_TAG:
705  break; /* Check the rest down there */
706  }
707  }
708 
709  tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
710  ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
711  tcv, ctx->phase, xml_tag);
712 
713  /* Skip the extensions section */
714  if(ctx->phase == 3) {
715  switch(xer_skip_unknown(tcv, &ctx->left)) {
716  case -1:
717  ctx->phase = 4;
718  RETURN(RC_FAIL);
719  case 0:
720  XER_ADVANCE(ch_size);
721  continue;
722  case 1:
723  XER_ADVANCE(ch_size);
724  ctx->phase = 1;
725  continue;
726  case 2:
727  ctx->phase = 1;
728  break;
729  }
730  }
731 
732  switch(tcv) {
733  case XCT_CLOSING:
734  if(ctx->phase == 0) break;
735  ctx->phase = 0;
736  /* Fall through */
737  case XCT_BOTH:
738  if(ctx->phase == 0) {
739  if(edx >= td->elements_count
740  ||
741  /* Explicit OPTIONAL specs reaches the end */
742  (edx + elements[edx].optional
743  == td->elements_count)
744  ||
745  /* All extensions are optional */
746  (IN_EXTENSION_GROUP(specs, edx)
747  && specs->ext_before
748  > td->elements_count)
749  ) {
750  XER_ADVANCE(ch_size);
751  ctx->phase = 4; /* Phase out */
752  RETURN(RC_OK);
753  } else {
754  ASN_DEBUG("Premature end of XER SEQUENCE");
755  RETURN(RC_FAIL);
756  }
757  }
758  /* Fall through */
759  case XCT_OPENING:
760  if(ctx->phase == 0) {
761  XER_ADVANCE(ch_size);
762  ctx->phase = 1; /* Processing body phase */
763  continue;
764  }
765  /* Fall through */
766  case XCT_UNKNOWN_OP:
767  case XCT_UNKNOWN_BO:
768 
769  ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%d",
770  tcv, ctx->phase, edx);
771  if(ctx->phase != 1) {
772  break; /* Really unexpected */
773  }
774 
775  if(edx < td->elements_count) {
776  /*
777  * Search which member corresponds to this tag.
778  */
779  edx_end = edx + elements[edx].optional + 1;
780  if(edx_end > td->elements_count)
781  edx_end = td->elements_count;
782  for(n = edx; n < edx_end; n++) {
783  elm = &td->elements[n];
784  tcv = xer_check_tag(buf_ptr,
785  ch_size, elm->name);
786  switch(tcv) {
787  case XCT_BOTH:
788  case XCT_OPENING:
789  /*
790  * Process this member.
791  */
792  ctx->step = edx = n;
793  ctx->phase = 2;
794  break;
795  case XCT_UNKNOWN_OP:
796  case XCT_UNKNOWN_BO:
797  continue;
798  default:
799  n = edx_end;
800  break; /* Phase out */
801  }
802  break;
803  }
804  if(n != edx_end)
805  continue;
806  } else {
807  ASN_DEBUG("Out of defined members: %d/%d",
808  edx, td->elements_count);
809  }
810 
811  /* It is expected extension */
812  if(IN_EXTENSION_GROUP(specs,
813  edx + (edx < td->elements_count
814  ? elements[edx].optional : 0))) {
815  ASN_DEBUG("Got anticipated extension at %d",
816  edx);
817  /*
818  * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
819  * By using a mask. Only record a pure
820  * <opening> tags.
821  */
822  if(tcv & XCT_CLOSING) {
823  /* Found </extension> without body */
824  } else {
825  ctx->left = 1;
826  ctx->phase = 3; /* Skip ...'s */
827  }
828  XER_ADVANCE(ch_size);
829  continue;
830  }
831 
832  /* Fall through */
833  default:
834  break;
835  }
836 
837  ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
838  size>0?((const char *)buf_ptr)[0]:'.',
839  size>1?((const char *)buf_ptr)[1]:'.',
840  size>2?((const char *)buf_ptr)[2]:'.',
841  size>3?((const char *)buf_ptr)[3]:'.',
842  size>4?((const char *)buf_ptr)[4]:'.',
843  size>5?((const char *)buf_ptr)[5]:'.');
844  break;
845  }
846 
847  ctx->phase = 4; /* "Phase out" on hard failure */
848  RETURN(RC_FAIL);
849 }
850 
853  int ilevel, enum xer_encoder_flags_e flags,
854  asn_app_consume_bytes_f *cb, void *app_key) {
855  asn_enc_rval_t er;
856  int xcan = (flags & XER_F_CANONICAL);
857  int edx;
858 
859  if(!sptr)
861 
862  er.encoded = 0;
863 
864  for(edx = 0; edx < td->elements_count; edx++) {
865  asn_enc_rval_t tmper;
866  asn_TYPE_member_t *elm = &td->elements[edx];
867  void *memb_ptr;
868  const char *mname = elm->name;
869  unsigned int mlen = strlen(mname);
870 
871  if(elm->flags & ATF_POINTER) {
872  memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
873  if(!memb_ptr) {
874  if(elm->optional)
875  continue;
876  /* Mandatory element is missing */
878  }
879  } else {
880  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
881  }
882 
883  if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
884  _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
885 
886  /* Print the member itself */
887  tmper = elm->type->xer_encoder(elm->type, memb_ptr,
888  ilevel + 1, flags, cb, app_key);
889  if(tmper.encoded == -1) return tmper;
890 
891  _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
892  er.encoded += 5 + (2 * mlen) + tmper.encoded;
893  }
894 
895  if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
896 
897  _ASN_ENCODED_OK(er);
898 cb_failed:
900 }
901 
902 int
903 SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
904  asn_app_consume_bytes_f *cb, void *app_key) {
905  int edx;
906  int ret;
907 
908  if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
909 
910  /* Dump preamble */
911  if(cb(td->name, strlen(td->name), app_key) < 0
912  || cb(" ::= {", 6, app_key) < 0)
913  return -1;
914 
915  for(edx = 0; edx < td->elements_count; edx++) {
916  asn_TYPE_member_t *elm = &td->elements[edx];
917  const void *memb_ptr;
918 
919  if(elm->flags & ATF_POINTER) {
920  memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
921  if(!memb_ptr) {
922  if(elm->optional) continue;
923  /* Print <absent> line */
924  /* Fall through */
925  }
926  } else {
927  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
928  }
929 
930  /* Indentation */
931  _i_INDENT(1);
932 
933  /* Print the member's name and stuff */
934  if(cb(elm->name, strlen(elm->name), app_key) < 0
935  || cb(": ", 2, app_key) < 0)
936  return -1;
937 
938  /* Print the member itself */
939  ret = elm->type->print_struct(elm->type, memb_ptr, ilevel + 1,
940  cb, app_key);
941  if(ret) return ret;
942  }
943 
944  ilevel--;
945  _i_INDENT(1);
946 
947  return (cb("}", 1, app_key) < 0) ? -1 : 0;
948 }
949 
950 void
951 SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
952  int edx;
953 
954  if(!td || !sptr)
955  return;
956 
957  ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
958 
959  for(edx = 0; edx < td->elements_count; edx++) {
960  asn_TYPE_member_t *elm = &td->elements[edx];
961  void *memb_ptr;
962  if(elm->flags & ATF_POINTER) {
963  memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
964  if(memb_ptr)
965  ASN_STRUCT_FREE(*elm->type, memb_ptr);
966  } else {
967  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
968  ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
969  }
970  }
971 
972  if(!contents_only) {
973  FREEMEM(sptr);
974  }
975 }
976 
977 int
979  asn_app_constraint_failed_f *ctfailcb, void *app_key) {
980  int edx;
981 
982  if(!sptr) {
983  _ASN_CTFAIL(app_key, td, sptr,
984  "%s: value not given (%s:%d)",
985  td->name, __FILE__, __LINE__);
986  return -1;
987  }
988 
989  /*
990  * Iterate over structure members and check their validity.
991  */
992  for(edx = 0; edx < td->elements_count; edx++) {
993  asn_TYPE_member_t *elm = &td->elements[edx];
994  const void *memb_ptr;
995 
996  if(elm->flags & ATF_POINTER) {
997  memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
998  if(!memb_ptr) {
999  if(elm->optional)
1000  continue;
1001  _ASN_CTFAIL(app_key, td, sptr,
1002  "%s: mandatory element %s absent (%s:%d)",
1003  td->name, elm->name, __FILE__, __LINE__);
1004  return -1;
1005  }
1006  } else {
1007  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1008  }
1009 
1010  if(elm->memb_constraints) {
1011  int ret = elm->memb_constraints(elm->type, memb_ptr,
1012  ctfailcb, app_key);
1013  if(ret) return ret;
1014  } else {
1015  int ret = elm->type->check_constraints(elm->type,
1016  memb_ptr, ctfailcb, app_key);
1017  if(ret) return ret;
1018  /*
1019  * Cannot inherit it earlier:
1020  * need to make sure we get the updated version.
1021  */
1023  }
1024  }
1025 
1026  return 0;
1027 }
1028 
1031  asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
1033  void *st = *sptr; /* Target structure. */
1034  int extpresent; /* Extension additions are present */
1035  uint8_t *opres; /* Presence of optional root members */
1036  asn_per_data_t opmd;
1037  asn_dec_rval_t rv;
1038  int edx;
1039 
1040  (void)constraints;
1041 
1042  if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
1044 
1045  if(!st) {
1046  st = *sptr = CALLOC(1, specs->struct_size);
1047  if(!st) _ASN_DECODE_FAILED;
1048  }
1049 
1050  ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
1051 
1052  /* Handle extensions */
1053  if(specs->ext_before >= 0) {
1054  extpresent = per_get_few_bits(pd, 1);
1055  if(extpresent < 0) _ASN_DECODE_STARVED;
1056  } else {
1057  extpresent = 0;
1058  }
1059 
1060  /* Prepare a place and read-in the presence bitmap */
1061  memset(&opmd, 0, sizeof(opmd));
1062  if(specs->roms_count) {
1063  opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
1064  if(!opres) _ASN_DECODE_FAILED;
1065  /* Get the presence map */
1066  if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
1067  FREEMEM(opres);
1069  }
1070  opmd.buffer = opres;
1071  opmd.nbits = specs->roms_count;
1072  ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
1073  td->name, specs->roms_count, *opres);
1074  } else {
1075  opres = 0;
1076  }
1077 
1078  /*
1079  * Get the sequence ROOT elements.
1080  */
1081  for(edx = 0; edx < td->elements_count; edx++) {
1082  asn_TYPE_member_t *elm = &td->elements[edx];
1083  void *memb_ptr; /* Pointer to the member */
1084  void **memb_ptr2; /* Pointer to that pointer */
1085 
1086  if(IN_EXTENSION_GROUP(specs, edx))
1087  continue;
1088 
1089  /* Fetch the pointer to this member */
1090  if(elm->flags & ATF_POINTER) {
1091  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1092  } else {
1093  memb_ptr = (char *)st + elm->memb_offset;
1094  memb_ptr2 = &memb_ptr;
1095  }
1096 
1097  /* Deal with optionality */
1098  if(elm->optional) {
1099  int present = per_get_few_bits(&opmd, 1);
1100  ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
1101  td->name, elm->name, present,
1102  (int)opmd.nboff, (int)opmd.nbits);
1103  if(present == 0) {
1104  /* This element is not present */
1105  if(elm->default_value) {
1106  /* Fill-in DEFAULT */
1107  if(elm->default_value(1, memb_ptr2)) {
1108  FREEMEM(opres);
1110  }
1111  ASN_DEBUG("Filled-in default");
1112  }
1113  /* The member is just not present */
1114  continue;
1115  }
1116  /* Fall through */
1117  }
1118 
1119  /* Fetch the member from the stream */
1120  ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
1121  rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
1122  elm->per_constraints, memb_ptr2, pd);
1123  if(rv.code != RC_OK) {
1124  ASN_DEBUG("Failed decode %s in %s",
1125  elm->name, td->name);
1126  FREEMEM(opres);
1127  return rv;
1128  }
1129  }
1130 
1131  /* Optionality map is not needed anymore */
1132  FREEMEM(opres);
1133 
1134  /*
1135  * Deal with extensions.
1136  */
1137  if(extpresent) {
1138  ssize_t bmlength;
1139  uint8_t *epres; /* Presence of extension members */
1140  asn_per_data_t epmd;
1141 
1142  bmlength = uper_get_nslength(pd);
1143  if(bmlength < 0) _ASN_DECODE_STARVED;
1144 
1145  ASN_DEBUG("Extensions %ld present in %s", (long)bmlength, td->name);
1146 
1147  epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
1148  if(!epres) _ASN_DECODE_STARVED;
1149 
1150  /* Get the extensions map */
1151  if(per_get_many_bits(pd, epres, 0, bmlength))
1153 
1154  memset(&epmd, 0, sizeof(epmd));
1155  epmd.buffer = epres;
1156  epmd.nbits = bmlength;
1157  ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
1158  td->name, (long)bmlength, *epres);
1159 
1160  /* Go over extensions and read them in */
1161  for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
1162  asn_TYPE_member_t *elm = &td->elements[edx];
1163  void *memb_ptr; /* Pointer to the member */
1164  void **memb_ptr2; /* Pointer to that pointer */
1165  int present;
1166 
1167  if(!IN_EXTENSION_GROUP(specs, edx)) {
1168  ASN_DEBUG("%d is not extension", edx);
1169  continue;
1170  }
1171 
1172  /* Fetch the pointer to this member */
1173  if(elm->flags & ATF_POINTER) {
1174  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1175  } else {
1176  memb_ptr = (void *)((char *)st + elm->memb_offset);
1177  memb_ptr2 = &memb_ptr;
1178  }
1179 
1180  present = per_get_few_bits(&epmd, 1);
1181  if(present <= 0) {
1182  if(present < 0) break; /* No more extensions */
1183  continue;
1184  }
1185 
1186  ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
1187  rv = uper_open_type_get(opt_codec_ctx, elm->type,
1188  elm->per_constraints, memb_ptr2, pd);
1189  if(rv.code != RC_OK) {
1190  FREEMEM(epres);
1191  return rv;
1192  }
1193  }
1194 
1195  /* Skip over overflow extensions which aren't present
1196  * in this system's version of the protocol */
1197  for(;;) {
1198  ASN_DEBUG("Getting overflow extensions");
1199  switch(per_get_few_bits(&epmd, 1)) {
1200  case -1: break;
1201  case 0: continue;
1202  default:
1203  if(uper_open_type_skip(opt_codec_ctx, pd)) {
1204  FREEMEM(epres);
1206  }
1207  }
1208  break;
1209  }
1210 
1211  FREEMEM(epres);
1212  }
1213 
1214  /* Fill DEFAULT members in extensions */
1215  for(edx = specs->roms_count; edx < specs->roms_count
1216  + specs->aoms_count; edx++) {
1217  asn_TYPE_member_t *elm = &td->elements[edx];
1218  void **memb_ptr2; /* Pointer to member pointer */
1219 
1220  if(!elm->default_value) continue;
1221 
1222  /* Fetch the pointer to this member */
1223  if(elm->flags & ATF_POINTER) {
1224  memb_ptr2 = (void **)((char *)st
1225  + elm->memb_offset);
1226  if(*memb_ptr2) continue;
1227  } else {
1228  continue; /* Extensions are all optionals */
1229  }
1230 
1231  /* Set default value */
1232  if(elm->default_value(1, memb_ptr2)) {
1234  }
1235  }
1236 
1237  rv.consumed = 0;
1238  rv.code = RC_OK;
1239  return rv;
1240 }
1241 
1242 static int
1244  asn_per_outp_t *po1, asn_per_outp_t *po2) {
1247  int exts_present = 0;
1248  int exts_count = 0;
1249  int edx;
1250 
1251  if(specs->ext_before < 0)
1252  return 0;
1253 
1254  /* Find out which extensions are present */
1255  for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
1256  asn_TYPE_member_t *elm = &td->elements[edx];
1257  void *memb_ptr; /* Pointer to the member */
1258  void **memb_ptr2; /* Pointer to that pointer */
1259  int present;
1260 
1261  if(!IN_EXTENSION_GROUP(specs, edx)) {
1262  ASN_DEBUG("%s (@%d) is not extension", elm->type->name, edx);
1263  continue;
1264  }
1265 
1266  /* Fetch the pointer to this member */
1267  if(elm->flags & ATF_POINTER) {
1268  memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
1269  present = (*memb_ptr2 != 0);
1270  } else {
1271  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
1272  memb_ptr2 = &memb_ptr;
1273  present = 1;
1274  }
1275 
1276  ASN_DEBUG("checking %s (@%d) present => %d",
1277  elm->type->name, edx, present);
1278  exts_count++;
1279  exts_present += present;
1280 
1281  /* Encode as presence marker */
1282  if(po1 && per_put_few_bits(po1, present, 1))
1283  return -1;
1284  /* Encode as open type field */
1285  if(po2 && present && uper_open_type_put(elm->type,
1286  elm->per_constraints, *memb_ptr2, po2))
1287  return -1;
1288 
1289  }
1290 
1291  return exts_present ? exts_count : 0;
1292 }
1293 
1296  asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
1299  asn_enc_rval_t er;
1300  int n_extensions;
1301  int edx;
1302  int i;
1303 
1304  (void)constraints;
1305 
1306  if(!sptr)
1308 
1309  er.encoded = 0;
1310 
1311  ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
1312 
1313 
1314  /*
1315  * X.691#18.1 Whether structure is extensible
1316  * and whether to encode extensions
1317  */
1318  if(specs->ext_before >= 0) {
1319  n_extensions = SEQUENCE_handle_extensions(td, sptr, 0, 0);
1320  per_put_few_bits(po, n_extensions ? 1 : 0, 1);
1321  } else {
1322  n_extensions = 0; /* There are no extensions to encode */
1323  }
1324 
1325  /* Encode a presence bitmap */
1326  for(i = 0; i < specs->roms_count; i++) {
1327  asn_TYPE_member_t *elm;
1328  void *memb_ptr; /* Pointer to the member */
1329  void **memb_ptr2; /* Pointer to that pointer */
1330  int present;
1331 
1332  edx = specs->oms[i];
1333  elm = &td->elements[edx];
1334 
1335  /* Fetch the pointer to this member */
1336  if(elm->flags & ATF_POINTER) {
1337  memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
1338  present = (*memb_ptr2 != 0);
1339  } else {
1340  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
1341  memb_ptr2 = &memb_ptr;
1342  present = 1;
1343  }
1344 
1345  /* Eliminate default values */
1346  if(present && elm->default_value
1347  && elm->default_value(0, memb_ptr2) == 1)
1348  present = 0;
1349 
1350  ASN_DEBUG("Element %s %s %s->%s is %s",
1351  elm->flags & ATF_POINTER ? "ptr" : "inline",
1352  elm->default_value ? "def" : "wtv",
1353  td->name, elm->name, present ? "present" : "absent");
1354  if(per_put_few_bits(po, present, 1))
1356  }
1357 
1358  /*
1359  * Encode the sequence ROOT elements.
1360  */
1361  ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before);
1362  for(edx = 0; edx < ((specs->ext_after < 0)
1363  ? td->elements_count : specs->ext_before - 1); edx++) {
1364 
1365  asn_TYPE_member_t *elm = &td->elements[edx];
1366  void *memb_ptr; /* Pointer to the member */
1367  void **memb_ptr2; /* Pointer to that pointer */
1368 
1369  if(IN_EXTENSION_GROUP(specs, edx))
1370  continue;
1371 
1372  ASN_DEBUG("About to encode %s", elm->type->name);
1373 
1374  /* Fetch the pointer to this member */
1375  if(elm->flags & ATF_POINTER) {
1376  memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
1377  if(!*memb_ptr2) {
1378  ASN_DEBUG("Element %s %d not present",
1379  elm->name, edx);
1380  if(elm->optional)
1381  continue;
1382  /* Mandatory element is missing */
1384  }
1385  } else {
1386  memb_ptr = (void *)((char *)sptr + elm->memb_offset);
1387  memb_ptr2 = &memb_ptr;
1388  }
1389 
1390  /* Eliminate default values */
1391  if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
1392  continue;
1393 
1394  ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
1395  er = elm->type->uper_encoder(elm->type, elm->per_constraints,
1396  *memb_ptr2, po);
1397  if(er.encoded == -1)
1398  return er;
1399  }
1400 
1401  /* No extensions to encode */
1402  if(!n_extensions) _ASN_ENCODED_OK(er);
1403 
1404  ASN_DEBUG("Length of %d bit-map", n_extensions);
1405  /* #18.8. Write down the presence bit-map length. */
1406  if(uper_put_nslength(po, n_extensions))
1408 
1409  ASN_DEBUG("Bit-map of %d elements", n_extensions);
1410  /* #18.7. Encoding the extensions presence bit-map. */
1411  /* TODO: act upon NOTE in #18.7 for canonical PER */
1412  if(SEQUENCE_handle_extensions(td, sptr, po, 0) != n_extensions)
1414 
1415  ASN_DEBUG("Writing %d extensions", n_extensions);
1416  /* #18.9. Encode extensions as open type fields. */
1417  if(SEQUENCE_handle_extensions(td, sptr, 0, po) != n_extensions)
1419 
1420  _ASN_ENCODED_OK(er);
1421 }
1422 
int(* default_value)(int setval, void **sptr)
Definition: constr_TYPE.h:149
#define _i_ASN_TEXT_INDENT(nl, level)
Definition: asn_internal.h:82
xer_check_tag
Definition: xer_decoder.h:76
ssize_t der_write_tags(struct asn_TYPE_descriptor_s *type_descriptor, size_t struct_length, int tag_mode, int last_tag_form, ber_tlv_tag_t tag, asn_app_consume_bytes_f *consume_bytes_cb, void *app_key)
Definition: der_encoder.c:77
ssize_t ber_fetch_tag(const void *bufptr, size_t size, ber_tlv_tag_t *tag_r)
Definition: ber_tlv_tag.c:10
#define BER_TLV_CONSTRUCTED(tagptr)
Definition: ber_tlv_tag.h:25
enum asn_TYPE_flags_e flags
Definition: constr_TYPE.h:141
#define _ASN_DECODE_STARVED
Definition: asn_codecs.h:98
int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits)
Definition: per_support.c:323
char * ber_tlv_tag_string(ber_tlv_tag_t tag)
Definition: ber_tlv_tag.c:94
asn_dec_rval_t SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
xer_encoder_flags_e
Definition: xer_encoder.h:17
ssize_t encoded
Definition: asn_codecs.h:48
ssize_t ber_skip_length(struct asn_codec_ctx_s *opt_codec_ctx, int _is_constructed, const void *bufptr, size_t size)
static int SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr, asn_per_outp_t *po1, asn_per_outp_t *po2)
#define PHASE_OUT(ctx)
asn_constr_check_f * memb_constraints
Definition: constr_TYPE.h:147
asn_dec_rval_t SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **struct_ptr, const void *ptr, size_t size, int tag_mode)
ber_tlv_tag_t el_tag
Definition: constr_TYPE.h:157
#define SIZE_VIOLATION
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr)
Definition: constr_TYPE.h:57
#define CALLOC(nmemb, size)
Definition: asn_internal.h:26
asn_per_constraints_t * per_constraints
Definition: constr_TYPE.h:148
#define BER_TAG_VALUE(tag)
Definition: ber_tlv_tag.h:24
static int _ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx)
Definition: asn_internal.h:105
#define XER_ADVANCE(num_bytes)
#define _ASN_ENCODED_OK(rval)
Definition: asn_codecs.h:68
asn_constr_check_f * check_constraints
Definition: constr_TYPE.h:95
#define NEXT_PHASE(ctx)
asn_dec_rval_t ber_check_tags(struct asn_codec_ctx_s *opt_codec_ctx, struct asn_TYPE_descriptor_s *type_descriptor, asn_struct_ctx_t *opt_ctx, const void *ptr, size_t size, int tag_mode, int last_tag_form, ber_tlv_len_t *last_length, int *opt_tlv_form)
Definition: ber_decoder.c:65
#define ASN_STRUCT_FREE(asn_DEF, ptr)
Definition: constr_TYPE.h:56
#define FREEMEM(ptr)
Definition: asn_internal.h:29
#define _ASN_ENCODE_FAILED
Definition: asn_codecs.h:60
ssize_t xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_type_e *_ch_type)
Definition: xer_decoder.c:63
asn_struct_print_f * print_struct
Definition: constr_TYPE.h:94
#define LEFT
enum xer_check_tag xer_check_tag_e
struct asn_TYPE_member_s * elements
Definition: constr_TYPE.h:121
int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align, int get_nbits)
Definition: per_support.c:123
#define ADVANCE(num_bytes)
int() asn_app_consume_bytes_f(const void *buffer, size_t size, void *application_specific_key)
#define RETURN(_code)
xer_type_decoder_f * xer_decoder
Definition: constr_TYPE.h:98
#define BER_TAG_CLASS(tag)
Definition: ber_tlv_tag.h:23
#define _ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3)
Definition: asn_internal.h:77
int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits)
Definition: per_support.c:38
int uper_put_nslength(asn_per_outp_t *po, size_t length)
Definition: per_support.c:468
int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po)
Definition: per_opentype.c:26
size_t consumed
Definition: asn_codecs.h:89
der_type_encoder_f * der_encoder
Definition: constr_TYPE.h:97
#define _i_INDENT(nl)
Definition: asn_internal.h:93
void() asn_app_constraint_failed_f(void *application_specific_key, struct asn_TYPE_descriptor_s *type_descriptor_which_failed, const void *structure_which_failed_ptr, const char *error_message_format,...) GCC_PRINTFLIKE(4
#define IN_EXTENSION_GROUP(specs, memb_idx)
asn_enc_rval_t SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key)
enum asn_dec_rval_code_e code
Definition: asn_codecs.h:88
asn_TYPE_descriptor_t * type
Definition: constr_TYPE.h:146
#define BER_TAGS_EQUAL(tag1, tag2)
Definition: ber_tlv_tag.h:27
int SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key)
asn_TYPE_tag2member_t * tag2el
per_type_encoder_f * uper_encoder
Definition: constr_TYPE.h:101
static void ASN_DEBUG(const char *fmt,...)
Definition: asn_internal.h:62
const uint8_t * buffer
Definition: per_support.h:41
per_type_decoder_f * uper_decoder
Definition: constr_TYPE.h:100
#define _ASN_CTFAIL
Definition: constraints.h:57
int uper_open_type_skip(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd)
Definition: per_opentype.c:252
static int _t2e_cmp(const void *ap, const void *bp)
#define MALLOC(size)
Definition: asn_internal.h:27
asn_enc_rval_t SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po)
ber_tlv_tag_t tag
Definition: constr_TYPE.h:144
int xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth)
Definition: xer_decoder.c:346
void SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only)
ssize_t uper_get_nslength(asn_per_data_t *pd)
Definition: per_support.c:196
int SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key)
asn_dec_rval_t SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **struct_ptr, const char *opt_mname, const void *buf_ptr, size_t size)
asn_enc_rval_t SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key)
enum pxer_chunk_type pxer_chunk_type_e
#define _ASN_DECODE_FAILED
Definition: asn_codecs.h:91
unsigned ber_tlv_tag_t
Definition: ber_tlv_tag.h:18
xer_type_encoder_f * xer_encoder
Definition: constr_TYPE.h:99
asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
Definition: per_opentype.c:245