constr_CHOICE_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  */
8 
9 /*
10  * Return a standardized complex structure.
11  */
12 #undef RETURN
13 #define RETURN(_code) \
14  do { \
15  rval.code = _code; \
16  rval.consumed = consumed_myself; \
17  return rval; \
18  } while(0)
19 
20 #undef JER_ADVANCE
21 #define JER_ADVANCE(num_bytes) \
22  do { \
23  size_t num = num_bytes; \
24  buf_ptr = (const void *)(((const char *)buf_ptr) + num); \
25  size -= num; \
26  consumed_myself += num; \
27  } while(0)
28 
29 /*
30  * Decode the JER (JSON) data.
31  */
33 CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
34  const asn_TYPE_descriptor_t *td,
35  const asn_jer_constraints_t *constraints,
36  void **struct_ptr, const void *buf_ptr, size_t size) {
37  /*
38  * Bring closer parts of structure description.
39  */
40  const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
41 
42  /*
43  * Parts of the structure being constructed.
44  */
45  void *st = *struct_ptr; /* Target structure. */
46  asn_struct_ctx_t *ctx; /* Decoder context */
47 
48  asn_dec_rval_t rval; /* Return value of a decoder */
49  ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
50  size_t edx; /* Element index */
51 
52  /*
53  * Create the target structure if it is not present already.
54  */
55  if(st == 0) {
56  st = *struct_ptr = CALLOC(1, specs->struct_size);
57  if(st == 0) RETURN(RC_FAIL);
58  }
59 
60  /*
61  * Restore parsing context.
62  */
63  ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
64 
65  /*
66  * Phases of JER/JSON processing:
67  * Phase 0: Check that the opening key matches our expectations.
68  * Phase 1: Processing body and reacting on closing token.
69  * Phase 2: Processing inner type.
70  * Phase 3: Only waiting for closing token.
71  * Phase 4: Skipping unknown extensions.
72  * Phase 5: PHASED OUT
73  */
74  for(edx = ctx->step; ctx->phase <= 4;) {
75  pjer_chunk_type_e ch_type; /* JER chunk type */
76  ssize_t ch_size; /* Chunk size */
77  jer_check_sym_e scv; /* Tag check value */
78  asn_TYPE_member_t *elm;
79 
80  /*
81  * Go inside the member.
82  */
83  if(ctx->phase == 2) {
84  asn_dec_rval_t tmprval;
85  void *memb_ptr; /* Pointer to the member */
86  void **memb_ptr2; /* Pointer to that pointer */
87  unsigned old_present __attribute__((unused));
88 
89  elm = &td->elements[edx];
90 
91  if(elm->flags & ATF_POINTER) {
92  /* Member is a pointer to another structure */
93  memb_ptr2 = (void **)((char *)st
94  + elm->memb_offset);
95  } else {
96  memb_ptr = (char *)st + elm->memb_offset;
97  memb_ptr2 = &memb_ptr;
98  }
99 
100  /* Start/Continue decoding the inner member */
101  tmprval = elm->type->op->jer_decoder(opt_codec_ctx,
102  elm->type,
104  memb_ptr2,
105  buf_ptr, size);
106  JER_ADVANCE(tmprval.consumed);
107  ASN_DEBUG("JER/CHOICE: itdf: [%s] code=%d",
108  elm->type->name, tmprval.code);
109  old_present = _fetch_present_idx(st,
110  specs->pres_offset,
111  specs->pres_size);
112  assert(old_present == 0 || old_present == edx + 1);
113  /* Record what we've got */
114  _set_present_idx(st,
115  specs->pres_offset,
116  specs->pres_size, edx + 1);
117  if(tmprval.code != RC_OK)
118  RETURN(tmprval.code);
119  ctx->phase = 3;
120  /* Fall through */
121  }
122 
123  /*
124  * Get the next part of the JSON stream.
125  */
126  ch_size = jer_next_token(&ctx->context, buf_ptr, size, &ch_type);
127  if(ch_size == -1) {
128  RETURN(RC_FAIL);
129  } else {
130  switch(ch_type) {
131  case PJER_WMORE:
132  RETURN(RC_WMORE);
133 
134  case PJER_TEXT: /* Ignore free-standing text */
135  JER_ADVANCE(ch_size); /* Skip silently */
136  continue;
137 
138  case PJER_DLM:
139  case PJER_VALUE:
140  case PJER_KEY:
141  break; /* Check the rest down there */
142  }
143  }
144 
145  scv = jer_check_sym(buf_ptr, ch_size, NULL);
146  ASN_DEBUG("JER/CHOICE checked [%c%c%c%c] of [%s], scv=%d",
147  ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
148  ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
149  ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
150  ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
151  td->name, scv);
152 
153  /* Skip the extensions section */
154  if(ctx->phase == 4) {
155  ASN_DEBUG("skip_unknown(%d, %ld)",
156  scv, (long)ctx->left);
157  switch(jer_skip_unknown(scv, &ctx->left)) {
158  case -1:
159  ctx->phase = 5;
160  RETURN(RC_FAIL);
161  case 1:
162  ctx->phase = 3;
163  /* Fall through */
164  case 0:
165  JER_ADVANCE(ch_size);
166  continue;
167  case 2:
168  ctx->phase = 3;
169  break;
170  }
171  }
172 
173  switch(scv) {
174  case JCK_OEND:
175  if(ctx->phase != 3)
176  break;
177  JER_ADVANCE(ch_size);
178  ctx->phase = 5; /* Phase out */
179  RETURN(RC_OK);
180 
181  case JCK_COMMA:
182  JER_ADVANCE(ch_size);
183  continue;
184 
185  case JCK_OSTART:
186  if(ctx->phase == 0) {
187  JER_ADVANCE(ch_size);
188  ctx->phase = 1; /* Processing body phase */
189  continue;
190  }
191  /* Fall through */
192  case JCK_KEY:
193  case JCK_UNKNOWN:
194 
195  if(ctx->phase != 1)
196  break; /* Really unexpected */
197 
198  /*
199  * Search which inner member corresponds to this key.
200  */
201  for(edx = 0; edx < td->elements_count; edx++) {
202  elm = &td->elements[edx];
203  scv = jer_check_sym(buf_ptr,ch_size,elm->name);
204  switch(scv) {
205  case JCK_KEY:
206  /*
207  * Process this member.
208  */
209  ctx->step = edx;
210  ctx->phase = 2;
211  JER_ADVANCE(ch_size); /* skip key */
212  /* skip colon */
213  ch_size = jer_next_token(&ctx->context, buf_ptr, size,
214  &ch_type);
215  if(ch_size == -1) {
216  RETURN(RC_FAIL);
217  } else {
218  switch(ch_type) {
219  case PJER_WMORE:
220  RETURN(RC_WMORE);
221  case PJER_TEXT:
222  JER_ADVANCE(ch_size);
223  break;
224  default:
225  RETURN(RC_FAIL);
226  }
227  }
228  break;
229  case JCK_UNKNOWN:
230  continue;
231  default:
232  edx = td->elements_count;
233  break; /* Phase out */
234  }
235  break;
236  }
237  if(edx != td->elements_count)
238  continue;
239 
240  /* It is expected extension */
241  if(specs->ext_start != -1) {
242  ASN_DEBUG("Got anticipated extension");
243  ctx->left = 1;
244  ctx->phase = 4; /* Skip ...'s */
245  JER_ADVANCE(ch_size);
246  continue;
247  }
248 
249  /* Fall through */
250  default:
251  break;
252  }
253 
254  ASN_DEBUG("Unexpected JSON token [%c%c%c%c] in CHOICE [%s]"
255  " (ph=%d)",
256  ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
257  ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
258  ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
259  ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
260  td->name, ctx->phase);
261  break;
262  }
263 
264  ctx->phase = 5; /* Phase out, just in case */
265  RETURN(RC_FAIL);
266 }
267 
270  const void *sptr, int ilevel, enum jer_encoder_flags_e flags,
271  asn_app_consume_bytes_f *cb, void *app_key) {
272  const asn_CHOICE_specifics_t *specs =
273  (const asn_CHOICE_specifics_t *)td->specifics;
274  asn_enc_rval_t er = {0,0,0};
275  unsigned present = 0;
276  int jmin = (flags & JER_F_MINIFIED);
277 
278  if(!sptr)
280 
281  /*
282  * Figure out which CHOICE element is encoded.
283  */
284  present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
285 
286  if(present == 0 || present > td->elements_count) {
288  } else {
289  asn_enc_rval_t tmper = {0,0,0};
290  asn_TYPE_member_t *elm = &td->elements[present-1];
291  const void *memb_ptr = NULL;
292  const char *mname = elm->name;
293  unsigned int mlen = strlen(mname);
294 
295  if(elm->flags & ATF_POINTER) {
296  memb_ptr =
297  *(const void *const *)((const char *)sptr + elm->memb_offset);
298  if(!memb_ptr) ASN__ENCODE_FAILED;
299  } else {
300  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
301  }
302 
303  er.encoded = 0;
304 
305  ASN__CALLBACK("{",1);
306  if(!jmin) {
307  ASN__TEXT_INDENT(1, ilevel + 1);
308  ASN__CALLBACK3("\"", 1, mname, mlen, "\": ", 3);
309  } else {
310  ASN__CALLBACK3("\"", 1, mname, mlen, "\":", 2);
311  }
312 
313  tmper = elm->type->op->jer_encoder(elm->type,
315  memb_ptr,
316  ilevel + 1, flags, cb, app_key);
317  if(tmper.encoded == -1) return tmper;
318  er.encoded += tmper.encoded;
319 
320  if(!jmin) ASN__TEXT_INDENT(1, ilevel);
321  ASN__CALLBACK("}", 1);
322  }
323 
324  ASN__ENCODED_OK(er);
325 cb_failed:
327 }
asn_struct_ctx_s
Definition: constr_TYPE.h:29
asn_TYPE_member_s::memb_offset
unsigned memb_offset
Definition: constr_TYPE.h:275
RETURN
#define RETURN(_code)
Definition: constr_CHOICE_jer.c:13
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_TYPE_descriptor_s::elements_count
unsigned elements_count
Definition: constr_TYPE.h:253
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
asn_CHOICE_specifics_s::ctx_offset
unsigned ctx_offset
Definition: constr_CHOICE.h:19
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
asn_CHOICE_specifics_s::struct_size
unsigned struct_size
Definition: constr_CHOICE.h:18
asn_CHOICE_specifics_s
Definition: constr_CHOICE.h:14
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
CHOICE_encode_jer
asn_enc_rval_t CHOICE_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_CHOICE_jer.c:269
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
CHOICE_decode_jer
asn_dec_rval_t CHOICE_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 *buf_ptr, size_t size)
Definition: constr_CHOICE_jer.c:33
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
_set_present_idx
void _set_present_idx(void *sptr, unsigned offset, unsigned size, unsigned present)
Definition: constr_CHOICE.c:236
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__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
asn_CHOICE_specifics_s::pres_offset
unsigned pres_offset
Definition: constr_CHOICE.h:20
asn_CHOICE_specifics_s::ext_start
signed ext_start
Definition: constr_CHOICE.h:36
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_dec_rval_s::consumed
size_t consumed
Definition: asn_codecs.h:88
PJER_DLM
@ PJER_DLM
Definition: jer_decoder.h:71
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_ADVANCE
#define JER_ADVANCE(num_bytes)
Definition: constr_CHOICE_jer.c:21
jer_skip_unknown
int jer_skip_unknown(jer_check_sym_e scv, ber_tlv_len_t *depth)
Definition: jer_decoder.c:299
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_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
constr_CHOICE.h
asn_dec_rval_s
Definition: asn_codecs.h:86
PJER_KEY
@ PJER_KEY
Definition: jer_decoder.h:69
_fetch_present_idx
unsigned _fetch_present_idx(const void *struct_ptr, unsigned off, unsigned size)
Definition: constr_CHOICE.c:215
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
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
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
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_CHOICE_specifics_s::pres_size
unsigned pres_size
Definition: constr_CHOICE.h:21
JCK_OSTART
@ JCK_OSTART
Definition: jer_decoder.h:85


etsi_its_cpm_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:22:37