constr_SEQUENCE_jer.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  */
9 
10 /*
11  * Return a standardized complex structure.
12  */
13 #undef RETURN
14 #define RETURN(_code) \
15  do { \
16  rval.code = _code; \
17  rval.consumed = consumed_myself; \
18  return rval; \
19  } while(0)
20 
21 /*
22  * Check whether we are inside the extensions group.
23  */
24 #define IN_EXTENSION_GROUP(specs, memb_idx) \
25  ((specs)->first_extension >= 0 \
26  && (unsigned)(specs)->first_extension <= (memb_idx))
27 
28 #undef JER_ADVANCE
29 #define JER_ADVANCE(num_bytes) \
30  do { \
31  size_t num = (num_bytes); \
32  ptr = ((const char *)ptr) + num; \
33  size -= num; \
34  consumed_myself += num; \
35  } while(0)
36 
37 /*
38  * Decode the JER (JSON) data.
39  */
41 SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
42  const asn_TYPE_descriptor_t *td,
43  const asn_jer_constraints_t *constraints,
44  void **struct_ptr, const void *ptr, size_t size) {
45  /*
46  * Bring closer parts of structure description.
47  */
48  const asn_SEQUENCE_specifics_t *specs
49  = (const asn_SEQUENCE_specifics_t *)td->specifics;
50  asn_TYPE_member_t *elements = td->elements;
51 
52  /*
53  * ... and parts of the structure being constructed.
54  */
55  void *st = *struct_ptr; /* Target structure. */
56  asn_struct_ctx_t *ctx; /* Decoder context */
57 
58  asn_dec_rval_t rval; /* Return value from a decoder */
59  ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
60  ssize_t edx; /* Element index */
61 
62  /*
63  * Create the target structure if it is not present already.
64  */
65  if(st == 0) {
66  st = *struct_ptr = CALLOC(1, specs->struct_size);
67  if(st == 0) RETURN(RC_FAIL);
68  }
69 
70  /*
71  * Restore parsing context.
72  */
73  ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
74 
75  /*
76  * Phases of JER/JSON processing:
77  * Phase 0: Check that the key matches our expectations.
78  * Phase 1: Processing body and reacting on closing token.
79  * Phase 2: Processing inner type.
80  * Phase 3: Skipping unknown extensions.
81  * Phase 4: PHASED OUT
82  */
83  for(edx = ctx->step; ctx->phase <= 3;) {
84  pjer_chunk_type_e ch_type; /* JER chunk type */
85  ssize_t ch_size; /* Chunk size */
86  jer_check_sym_e scv; /* Tag check value */
87  asn_TYPE_member_t *elm;
88 
89 
90  /*
91  * Go inside the inner member of a sequence.
92  */
93  if(ctx->phase == 2) {
94  asn_dec_rval_t tmprval;
95  void *memb_ptr_dontuse; /* Pointer to the member */
96  void **memb_ptr2; /* Pointer to that pointer */
97 
98  elm = &td->elements[edx];
99  if(elm->flags & ATF_POINTER) {
100  /* Member is a pointer to another structure */
101  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
102  } else {
103  memb_ptr_dontuse = (char *)st + elm->memb_offset;
104  memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */
105  }
106 
107  if(elm->flags & ATF_OPEN_TYPE) {
108  tmprval = OPEN_TYPE_jer_get(opt_codec_ctx, td, st, elm, ptr, size);
109  } else {
110  /* Invoke the inner type decoder, m.b. multiple times */
111  tmprval = elm->type->op->jer_decoder(opt_codec_ctx,
112  elm->type,
114  memb_ptr2,
115  ptr, size);
116  }
117  JER_ADVANCE(tmprval.consumed);
118  if(tmprval.code != RC_OK)
119  RETURN(tmprval.code);
120  ctx->phase = 1; /* Back to body processing */
121  ctx->step = ++edx;
122  ASN_DEBUG("JER/SEQUENCE phase => %d, step => %d",
123  ctx->phase, ctx->step);
124  /* Fall through */
125  }
126 
127  /*
128  * Get the next part of the JSON stream.
129  */
130  ch_size = jer_next_token(&ctx->context, ptr, size,
131  &ch_type);
132  if(ch_size == -1) {
133  RETURN(RC_FAIL);
134  } else {
135  switch(ch_type) {
136  case PJER_WMORE:
137  RETURN(RC_WMORE);
138 
139  case PJER_TEXT: /* Ignore free-standing text */
140  JER_ADVANCE(ch_size); /* Skip silently */
141  continue;
142 
143  case PJER_DLM:
144  case PJER_VALUE:
145  case PJER_KEY:
146  break; /* Check the rest down there */
147  }
148  }
149 
150  scv = jer_check_sym(ptr, ch_size, NULL);
151  ASN_DEBUG("JER/SEQUENCE: scv = %d, ph=%d [%s]",
152  scv, ctx->phase, td->name);
153 
154 
155  /* Skip the extensions section */
156  if(ctx->phase == 3) {
157  switch(jer_skip_unknown(scv, &ctx->left)) {
158  case -1:
159  ctx->phase = 4;
160  RETURN(RC_FAIL);
161  case 0:
162  JER_ADVANCE(ch_size);
163  continue;
164  case 1:
165  JER_ADVANCE(ch_size);
166  ctx->phase = 1;
167  continue;
168  case 2:
169  ctx->phase = 1;
170  break;
171  }
172  }
173 
174  switch(scv) {
175  case JCK_OEND:
176  if(ctx->phase == 0) break;
177  ctx->phase = 0;
178 
179  if(edx >= td->elements_count ||
180  /* Explicit OPTIONAL specs reaches the end */
181  (edx + elements[edx].optional == td->elements_count) ||
182  /* All extensions are optional */
183  IN_EXTENSION_GROUP(specs, edx)) {
184  JER_ADVANCE(ch_size);
185  JER_ADVANCE(jer_whitespace_span(ptr, size));
186  ctx->phase = 4; /* Phase out */
187  RETURN(RC_OK);
188  } else {
189  ASN_DEBUG("Premature end of JER SEQUENCE");
190  RETURN(RC_FAIL);
191  }
192  case JCK_COMMA:
193  ADVANCE(ch_size);
194  continue;
195  /* Fall through */
196  case JCK_OSTART: /* '{' */
197  if(ctx->phase == 0) {
198  JER_ADVANCE(ch_size);
199  ctx->phase = 1; /* Processing body phase */
200  continue;
201  }
202 
203  /* Fall through */
204  case JCK_KEY:
205  case JCK_UNKNOWN:
206  ASN_DEBUG("JER/SEQUENCE: scv=%d, ph=%d, edx=%" ASN_PRI_SIZE "",
207  scv, ctx->phase, edx);
208  if(ctx->phase != 1) {
209  break; /* Really unexpected */
210  }
211 
212  if (td->elements_count == 0) {
213  JER_ADVANCE(ch_size);
214  continue;
215  }
216 
217  if(edx < td->elements_count) {
218  /*
219  * We have to check which member is next.
220  */
221  size_t n;
222  size_t edx_end = edx + elements[edx].optional + 1;
223  if(edx_end > td->elements_count) {
224  edx_end = td->elements_count;
225  }
226 
227  for(n = edx; n < edx_end; n++) {
228  elm = &td->elements[n];
229  scv = jer_check_sym(ptr, ch_size, elm->name);
230  switch (scv) {
231  case JCK_KEY:
232  ctx->step = edx = n;
233  ctx->phase = 2;
234 
235  ADVANCE(ch_size); /* skip key */
236  /* skip colon */
237  ch_size = jer_next_token(&ctx->context, ptr, size,
238  &ch_type);
239  if(ch_size == -1) {
240  RETURN(RC_FAIL);
241  } else {
242  switch(ch_type) {
243  case PJER_WMORE:
244  RETURN(RC_WMORE);
245  case PJER_TEXT:
246  JER_ADVANCE(ch_size);
247  break;
248  default:
249  RETURN(RC_FAIL);
250  }
251  }
252  break;
253  case JCK_UNKNOWN:
254  continue;
255  default:
256  n = edx_end;
257  break; /* Phase out */
258  }
259  break;
260  }
261  if(n != edx_end)
262  continue;
263  } else {
264  ASN_DEBUG("Out of defined members: %" ASN_PRI_SIZE "/%u",
265  edx, td->elements_count);
266  }
267 
268  /* It is expected extension */
269  if(IN_EXTENSION_GROUP(specs,
270  edx + (edx < td->elements_count
271  ? elements[edx].optional : 0))) {
272  ASN_DEBUG("Got anticipated extension at %" ASN_PRI_SIZE "",
273  edx);
274  ctx->left = 1;
275  ctx->phase = 3; /* Skip ...'s */
276  JER_ADVANCE(ch_size);
277  continue;
278  }
279 
280  /* Fall through */
281  default:
282  break;
283  }
284 
285  ASN_DEBUG("Unexpected JSON key in SEQUENCE [%c%c%c%c%c%c]",
286  size>0?((const char *)ptr)[0]:'.',
287  size>1?((const char *)ptr)[1]:'.',
288  size>2?((const char *)ptr)[2]:'.',
289  size>3?((const char *)ptr)[3]:'.',
290  size>4?((const char *)ptr)[4]:'.',
291  size>5?((const char *)ptr)[5]:'.');
292  break;
293  }
294 
295  ctx->phase = 4; /* "Phase out" on hard failure */
296  RETURN(RC_FAIL);
297 }
298 
299 
301  const asn_jer_constraints_t* constraints, const void *sptr,
302  int ilevel, enum jer_encoder_flags_e flags,
303  asn_app_consume_bytes_f *cb, void *app_key) {
304  asn_enc_rval_t er = {0,0,0};
305  int jmin = (flags & JER_F_MINIFIED);
306  asn_TYPE_descriptor_t *tmp_def_val_td = 0;
307  void *tmp_def_val = 0;
308  size_t edx;
309 
310  if(!sptr) ASN__ENCODE_FAILED;
311 
312  er.encoded = 0;
313 
314  int bAddComma = 0;
315  ASN__CALLBACK("{", 1);
316  for(edx = 0; edx < td->elements_count; edx++) {
317  asn_enc_rval_t tmper = {0,0,0};
318  asn_TYPE_member_t *elm = &td->elements[edx];
319  const void *memb_ptr;
320  const char *mname = elm->name;
321  unsigned int mlen = strlen(mname);
322 
323  if(elm->flags & ATF_POINTER) {
324  memb_ptr =
325  *(const void *const *)((const char *)sptr + elm->memb_offset);
326  if(!memb_ptr) {
327  assert(tmp_def_val == 0);
328  if(elm->default_value_set) {
329  if(elm->default_value_set(&tmp_def_val)) {
331  } else {
332  memb_ptr = tmp_def_val;
333  tmp_def_val_td = elm->type;
334  }
335  } else if(elm->optional) {
336  continue;
337  } else {
338  /* Mandatory element is missing */
340  }
341  }
342  } else {
343  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
344  }
345 
346  if (bAddComma == 1) {
347  ASN__CALLBACK(",", 1);
348  bAddComma = 0;
349  }
350 
351  if(!jmin) {
352  ASN__TEXT_INDENT(1, ilevel + 1);
353  ASN__CALLBACK3("\"", 1, mname, mlen, "\": ", 3);
354  } else {
355  ASN__CALLBACK3("\"", 1, mname, mlen, "\":", 2);
356  }
357 
358  /* Print the member itself */
359  tmper = elm->type->op->jer_encoder(elm->type,
361  memb_ptr,
362  ilevel + 1, flags, cb, app_key);
363  if(tmp_def_val) {
364  ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
365  tmp_def_val = 0;
366  }
367  if(tmper.encoded == -1) return tmper;
368  er.encoded += tmper.encoded;
369  if (edx != td->elements_count - 1) {
370  bAddComma = 1;
371  }
372  }
373  if(!jmin) ASN__TEXT_INDENT(1, ilevel);
374  ASN__CALLBACK("}", 1);
375 
376 
377  ASN__ENCODED_OK(er);
378 cb_failed:
379  if(tmp_def_val) ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
381 }
ASN_STRUCT_FREE
#define ASN_STRUCT_FREE(asn_DEF, ptr)
Definition: constr_TYPE.h:102
asn_struct_ctx_s
Definition: constr_TYPE.h:29
SEQUENCE_encode_jer
asn_enc_rval_t SEQUENCE_encode_jer(const asn_TYPE_descriptor_t *td, const asn_jer_constraints_t *constraints, const void *sptr, int ilevel, enum jer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key)
Definition: constr_SEQUENCE_jer.c:300
asn_TYPE_member_s::memb_offset
unsigned memb_offset
Definition: constr_TYPE.h:275
PJER_TEXT
@ PJER_TEXT
Definition: jer_decoder.h:68
JCK_COMMA
@ JCK_COMMA
Definition: jer_decoder.h:84
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
asn_jer_constraints_s
Definition: jer_support.h:18
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
jer_encoder_flags_e
jer_encoder_flags_e
Definition: jer_encoder.h:20
RC_WMORE
@ RC_WMORE
Definition: asn_codecs.h:83
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
JER_F_MINIFIED
@ JER_F_MINIFIED
Definition: jer_encoder.h:23
asn_TYPE_operation_s::jer_encoder
jer_type_encoder_f * jer_encoder
Definition: constr_TYPE.h:194
ASN__CALLBACK
#define ASN__CALLBACK(buf, size)
Definition: asn_internal.h:108
ASN__CALLBACK3
#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3)
Definition: asn_internal.h:112
JCK_OEND
@ JCK_OEND
Definition: jer_decoder.h:86
pjer_chunk_type_e
enum pjer_chunk_type pjer_chunk_type_e
JCK_UNKNOWN
@ JCK_UNKNOWN
Definition: jer_decoder.h:82
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
IN_EXTENSION_GROUP
#define IN_EXTENSION_GROUP(specs, memb_idx)
Definition: constr_SEQUENCE_jer.c:24
asn_TYPE_member_s::type
asn_TYPE_descriptor_t * type
Definition: constr_TYPE.h:278
ASN__TEXT_INDENT
#define ASN__TEXT_INDENT(nl, level)
Definition: asn_internal.h:117
JCK_KEY
@ JCK_KEY
Definition: jer_decoder.h:83
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
ATF_OPEN_TYPE
@ ATF_OPEN_TYPE
Definition: constr_TYPE.h:269
asn_SEQUENCE_specifics_s::ctx_offset
unsigned ctx_offset
Definition: constr_SEQUENCE.h:19
asn_TYPE_member_s::name
const char * name
Definition: constr_TYPE.h:283
RC_OK
@ RC_OK
Definition: asn_codecs.h:82
jer_whitespace_span
size_t jer_whitespace_span(const void *chunk_buf, size_t chunk_size)
Definition: jer_decoder.c:273
asn_TYPE_descriptor_s::op
asn_TYPE_operation_t * op
Definition: constr_TYPE.h:232
asn_dec_rval_s::consumed
size_t consumed
Definition: asn_codecs.h:88
PJER_DLM
@ PJER_DLM
Definition: jer_decoder.h:71
ASN_PRI_SIZE
#define ASN_PRI_SIZE
Definition: asn_system.h:172
JER_ADVANCE
#define JER_ADVANCE(num_bytes)
Definition: constr_SEQUENCE_jer.c:29
jer_check_sym
jer_check_sym
Definition: jer_decoder.h:80
PJER_VALUE
@ PJER_VALUE
Definition: jer_decoder.h:70
asn_encoding_constraints_s::jer_constraints
const struct asn_jer_constraints_s * jer_constraints
Definition: constr_TYPE.h:216
asn_TYPE_operation_s::jer_decoder
jer_type_decoder_f * jer_decoder
Definition: constr_TYPE.h:193
jer_skip_unknown
int jer_skip_unknown(jer_check_sym_e scv, ber_tlv_len_t *depth)
Definition: jer_decoder.c:299
RETURN
#define RETURN(_code)
Definition: constr_SEQUENCE_jer.c:14
asn_app_consume_bytes_f
int() asn_app_consume_bytes_f(const void *buffer, size_t size, void *application_specific_key)
Definition: asn_application.h:124
asn_SEQUENCE_specifics_s
Definition: constr_SEQUENCE.h:14
asn_internal.h
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
PJER_KEY
@ PJER_KEY
Definition: jer_decoder.h:69
jer_next_token
ssize_t jer_next_token(int *stateContext, const void *buffer, size_t size, pjer_chunk_type_e *_ch_type)
Definition: jer_decoder.c:64
constr_SEQUENCE.h
asn_enc_rval_s::encoded
ssize_t encoded
Definition: asn_codecs.h:47
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
OPEN_TYPE_jer_get
asn_dec_rval_t OPEN_TYPE_jer_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, const void *ptr, size_t size)
Definition: OPEN_TYPE_jer.c:11
SEQUENCE_decode_jer
asn_dec_rval_t SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_jer_constraints_t *constraints, void **struct_ptr, const void *ptr, size_t size)
Definition: constr_SEQUENCE_jer.c:41
ADVANCE
#define ADVANCE(num_bytes)
Definition: OPEN_TYPE.h:21
jer_check_sym_e
enum jer_check_sym jer_check_sym_e
PJER_WMORE
@ PJER_WMORE
Definition: jer_decoder.h:67
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
RC_FAIL
@ RC_FAIL
Definition: asn_codecs.h:84
asn_dec_rval_s::code
enum asn_dec_rval_code_e code
Definition: asn_codecs.h:87
asn_TYPE_member_s::default_value_set
int(* default_value_set)(void **sptr)
Definition: constr_TYPE.h:282
JCK_OSTART
@ JCK_OSTART
Definition: jer_decoder.h:85


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