asn_codecs_prim_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  * Local internal type passed around as an argument.
11  */
12 struct jdp_arg_s {
14  void *struct_key;
17  int want_more;
18 };
19 
20 /*
21  * Since some kinds of primitive values can be encoded using value-specific
22  * tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must
23  * be supplied with such tags to parse them as needed.
24  */
25 static int
26 jer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
27  struct jdp_arg_s *arg = (struct jdp_arg_s *)key;
28  enum jer_pbd_rval bret;
29 
30  /*
31  * The chunk_buf is guaranteed to start at '<'.
32  */
33  assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);
34 
35  /*
36  * Decoding was performed once already. Prohibit doing it again.
37  */
38  if(arg->decoded_something)
39  return -1;
40 
41  bret = arg->prim_body_decoder(arg->type_descriptor,
42  arg->struct_key, chunk_buf,
43  chunk_size);
44  switch(bret) {
46  case JPBD_DECODER_LIMIT:
48  break;
49  case JPBD_BODY_CONSUMED:
50  /* Tag decoded successfully */
51  arg->decoded_something = 1;
52  /* Fall through */
53  case JPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
54  return 0;
55  }
56 
57  return -1;
58 }
59 
60 static ssize_t
61 jer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
62  struct jdp_arg_s *arg = (struct jdp_arg_s *)key;
63  enum jer_pbd_rval bret;
64  size_t lead_wsp_size;
65 
66  if(arg->decoded_something) {
67  if(jer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {
68  /*
69  * Example:
70  * "<INTEGER>123<!--/--> </INTEGER>"
71  * ^- chunk_buf position.
72  */
73  return chunk_size;
74  }
75  /*
76  * Decoding was done once already. Prohibit doing it again.
77  */
78  return -1;
79  }
80 
81  if(!have_more) {
82  /*
83  * If we've received something like "1", we can't really
84  * tell whether it is really `1` or `123`, until we know
85  * that there is no more data coming.
86  * The have_more argument will be set to 1 once something
87  * like this is available to the caller of this callback:
88  * "1<tag_start..."
89  */
90  arg->want_more = 1;
91  return -1;
92  }
93 
94  lead_wsp_size = jer_whitespace_span(chunk_buf, chunk_size);
95  chunk_buf = (chunk_buf == NULL)? NULL : ((const char *)chunk_buf + lead_wsp_size);
96  chunk_size -= lead_wsp_size;
97 
98  bret = arg->prim_body_decoder(arg->type_descriptor,
99  arg->struct_key, chunk_buf,
100  chunk_size);
101  switch(bret) {
102  case JPBD_SYSTEM_FAILURE:
103  case JPBD_DECODER_LIMIT:
105  break;
106  case JPBD_BODY_CONSUMED:
107  /* Tag decoded successfully */
108  arg->decoded_something = 1;
109  /* Fall through */
110  case JPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
111  return lead_wsp_size + chunk_size;
112  }
113 
114  return -1;
115 }
116 
119  const asn_TYPE_descriptor_t *td, void **sptr,
120  size_t struct_size,
121  const void *buf_ptr, size_t size,
123  asn_struct_ctx_t s_ctx;
124  struct jdp_arg_s s_arg;
125  asn_dec_rval_t rc;
126 
127  /*
128  * Create the structure if does not exist.
129  */
130  if(!*sptr) {
131  *sptr = CALLOC(1, struct_size);
132  if(!*sptr) ASN__DECODE_FAILED;
133  }
134 
135  memset(&s_ctx, 0, sizeof(s_ctx));
136  s_arg.type_descriptor = td;
137  s_arg.struct_key = *sptr;
139  s_arg.decoded_something = 0;
140  s_arg.want_more = 0;
141 
142  rc = jer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
143  buf_ptr, size,
146  switch(rc.code) {
147  case RC_OK:
148  if(!s_arg.decoded_something) {
149  char ch;
150  ASN_DEBUG("Primitive body is not recognized, "
151  "supplying empty one");
152  /*
153  * Decoding opportunity has come and gone.
154  * Where's the result?
155  * Try to feed with empty body, see if it eats it.
156  */
158  s_arg.struct_key, &ch, 0)
159  != JPBD_BODY_CONSUMED) {
160  /*
161  * This decoder does not like empty stuff.
162  */
164  }
165  }
166  break;
167  case RC_WMORE:
168  /*
169  * Redo the whole thing later.
170  * We don't have a context to save intermediate parsing state.
171  */
172  rc.consumed = 0;
173  break;
174  case RC_FAIL:
175  rc.consumed = 0;
176  if(s_arg.want_more)
177  rc.code = RC_WMORE;
178  else
180  break;
181  }
182  return rc;
183 }
asn_struct_ctx_s
Definition: constr_TYPE.h:29
JPBD_BODY_CONSUMED
@ JPBD_BODY_CONSUMED
Definition: asn_codecs_prim.h:61
jdp_arg_s
Definition: asn_codecs_prim_jer.c:12
jer_pbd_rval
jer_pbd_rval
Definition: asn_codecs_prim.h:56
JPBD_SYSTEM_FAILURE
@ JPBD_SYSTEM_FAILURE
Definition: asn_codecs_prim.h:57
JPBD_NOT_BODY_IGNORE
@ JPBD_NOT_BODY_IGNORE
Definition: asn_codecs_prim.h:60
RC_WMORE
@ RC_WMORE
Definition: asn_codecs.h:83
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
jer_decode_general
asn_dec_rval_t jer_decode_general(const asn_codec_ctx_t *opt_codec_ctx, asn_struct_ctx_t *ctx, void *struct_key, const void *buf_ptr, size_t size, int(*opt_unexpected_tag_decoder)(void *struct_key, const void *chunk_buf, size_t chunk_size), ssize_t(*body_receiver)(void *struct_key, const void *chunk_buf, size_t chunk_size, int have_more))
Definition: jer_decoder.c:210
jdp_arg_s::decoded_something
int decoded_something
Definition: asn_codecs_prim_jer.c:16
asn_codecs_prim.h
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
jdp_arg_s::prim_body_decoder
jer_primitive_body_decoder_f * prim_body_decoder
Definition: asn_codecs_prim_jer.c:15
jdp_arg_s::type_descriptor
const asn_TYPE_descriptor_t * type_descriptor
Definition: asn_codecs_prim_jer.c:13
jer_decode__unexpected_tag
static int jer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size)
Definition: asn_codecs_prim_jer.c:26
jer_primitive_body_decoder_f
enum jer_pbd_rval() jer_primitive_body_decoder_f(const asn_TYPE_descriptor_t *td, void *struct_ptr, const void *chunk_buf, size_t chunk_size)
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
jer_decode_primitive
asn_dec_rval_t jer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, void **sptr, size_t struct_size, const void *buf_ptr, size_t size, jer_primitive_body_decoder_f *prim_body_decoder)
Definition: asn_codecs_prim_jer.c:118
jdp_arg_s::want_more
int want_more
Definition: asn_codecs_prim_jer.c:17
jer_decode__primitive_body
static ssize_t jer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more)
Definition: asn_codecs_prim_jer.c:61
JPBD_DECODER_LIMIT
@ JPBD_DECODER_LIMIT
Definition: asn_codecs_prim.h:58
JPBD_BROKEN_ENCODING
@ JPBD_BROKEN_ENCODING
Definition: asn_codecs_prim.h:59
key
static void ssize_t void * key
Definition: asn_internal.h:96
asn_internal.h
asn_codec_ctx_s
Definition: asn_codecs.h:23
asn_dec_rval_s
Definition: asn_codecs.h:86
ASN__DECODE_FAILED
#define ASN__DECODE_FAILED
Definition: asn_codecs.h:90
jdp_arg_s::struct_key
void * struct_key
Definition: asn_codecs_prim_jer.c:14
RC_FAIL
@ RC_FAIL
Definition: asn_codecs.h:84


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