INTEGER_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 struct je2v_key {
10  const char *start;
11  const char *stop;
13  const unsigned int *evmap;
14 };
15 
16 static int
17 INTEGER_jer_st_prealloc(INTEGER_t *st, int min_size) {
18  void *p = MALLOC(min_size + 1);
19  if(p) {
20  void *b = st->buf;
21  st->size = 0;
22  st->buf = p;
23  FREEMEM(b);
24  return 0;
25  } else {
26  return -1;
27  }
28 }
29 /*
30  * Decode the chunk of JSON text encoding INTEGER.
31  */
32 static enum jer_pbd_rval
34  const void *chunk_buf, size_t chunk_size) {
35  const asn_INTEGER_specifics_t *specs =
37  INTEGER_t *st = (INTEGER_t *)sptr;
38  intmax_t dec_value;
39  const char *lp;
40  const char *lstart = (const char *)chunk_buf;
41  const char *lstop = lstart + chunk_size;
42  enum {
43  ST_LEADSPACE,
44  ST_WAITDIGITS,
45  ST_DIGITS,
46  ST_ZERO,
47  ST_DIGITS_TRAILSPACE,
48  ST_UNEXPECTED
49  } state = ST_LEADSPACE;
50  const char *dec_value_start = 0; /* INVARIANT: always !0 in ST_DIGITS */
51  const char *dec_value_end = 0;
52 
53  if(chunk_size)
54  ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
55  (long)chunk_size, *lstart, lstop[-1]);
56 
57  if(INTEGER_jer_st_prealloc(st, (chunk_size/3) + 1))
58  return JPBD_SYSTEM_FAILURE;
59 
60  /*
61  * We may have received a tag here. It will be processed inline.
62  * Use strtoul()-like code and serialize the result.
63  */
64  for(lp = lstart; lp < lstop; lp++) {
65  int lv = *lp;
66  switch(lv) {
67  case 0x09: case 0x0a: case 0x0d: case 0x20:
68  switch(state) {
69  case ST_LEADSPACE:
70  case ST_DIGITS_TRAILSPACE:
71  continue;
72  case ST_DIGITS:
73  case ST_ZERO:
74  dec_value_end = lp;
75  state = ST_DIGITS_TRAILSPACE;
76  continue;
77  default:
78  break;
79  }
80  break;
81  case 0x2d: /* '-' */
82  if(state == ST_LEADSPACE) {
83  dec_value = 0;
84  dec_value_start = lp;
85  state = ST_WAITDIGITS;
86  continue;
87  }
88  break;
89  case 0x30: /* 0 */
90  switch(state) {
91  case ST_DIGITS: continue;
92  case ST_LEADSPACE:
93  case ST_WAITDIGITS:
94  dec_value = 0;
95  dec_value_start = lp;
96  state = ST_ZERO;
97  continue;
98  case ST_ZERO: /* forbidden leading zero */
99  return JPBD_BROKEN_ENCODING;
100  default:
101  break;
102  }
103  break;
104  /* [1-9] */
105  case 0x31: case 0x32: case 0x33: case 0x34:
106  case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
107  switch(state) {
108  case ST_DIGITS: continue;
109  case ST_LEADSPACE:
110  dec_value = 0;
111  dec_value_start = lp;
112  /* FALL THROUGH */
113  case ST_WAITDIGITS:
114  state = ST_DIGITS;
115  continue;
116  case ST_ZERO: /* forbidden leading zero */
117  return JPBD_BROKEN_ENCODING;
118  default:
119  break;
120  }
121  break;
122  }
123 
124  /* Found extra non-numeric stuff */
125  ASN_DEBUG("INTEGER :: Found non-numeric 0x%2x at %ld",
126  lv, (long)(lp - lstart));
127  state = ST_UNEXPECTED;
128  break;
129  }
130 
131  switch(state) {
132  case ST_DIGITS:
133  case ST_ZERO:
134  dec_value_end = lstop;
135  /* FALL THROUGH */
136  case ST_DIGITS_TRAILSPACE:
137  /* The last symbol encountered was a digit. */
138  switch(asn_strtoimax_lim(dec_value_start, &dec_value_end, &dec_value)) {
139  case ASN_STRTOX_OK:
140  if(specs && specs->field_unsigned && (uintmax_t) dec_value <= ULONG_MAX) {
141  break;
142  } else if(dec_value >= LONG_MIN && dec_value <= LONG_MAX) {
143  break;
144  } else {
145  /*
146  * We model INTEGER on long for JER,
147  * to avoid rewriting all the tests at once.
148  */
149  ASN_DEBUG("INTEGER exceeds long range");
150  }
151  /* Fall through */
153  ASN_DEBUG("INTEGER decode %s hit range limit", td->name);
154  return JPBD_DECODER_LIMIT;
158  return JPBD_BROKEN_ENCODING;
159  }
160  break;
161  case ST_LEADSPACE:
162  /* Content not found */
163  return JPBD_NOT_BODY_IGNORE;
164  case ST_WAITDIGITS:
165  case ST_UNEXPECTED:
166  ASN_DEBUG("INTEGER: No useful digits (state %d)", state);
167  return JPBD_BROKEN_ENCODING; /* No digits */
168  }
169 
170  /*
171  * Convert the result of parsing of enumeration or a straight
172  * decimal value into a BER representation.
173  */
174  if(asn_imax2INTEGER(st, dec_value)) {
175  ASN_DEBUG("INTEGER decode %s conversion failed", td->name);
176  return JPBD_SYSTEM_FAILURE;
177  }
178 
179  return JPBD_BODY_CONSUMED;
180 }
181 
183 INTEGER_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
184  const asn_TYPE_descriptor_t *td,
185  const asn_jer_constraints_t *constraints,
186  void **sptr, const void *buf_ptr, size_t size) {
187  return jer_decode_primitive(opt_codec_ctx, td,
188  sptr, sizeof(INTEGER_t),
189  buf_ptr, size, INTEGER__jer_body_decode);
190 }
191 
192 
195  const asn_jer_constraints_t *constraints,
196  const void *sptr, int ilevel, enum jer_encoder_flags_e flags,
197  asn_app_consume_bytes_f *cb, void *app_key) {
198  const INTEGER_t *st = (const INTEGER_t *)sptr;
199  asn_enc_rval_t er = {0,0,0};
200 
201  (void)ilevel;
202  (void)flags;
203 
204  if(!st || !st->buf)
206 
207  er.encoded = INTEGER__dump(td, st, cb, app_key, 2);
208  if(er.encoded < 0) ASN__ENCODE_FAILED;
209 
210  ASN__ENCODED_OK(er);
211 }
je2v_key
Definition: INTEGER_jer.c:9
INTEGER_encode_jer
asn_enc_rval_t INTEGER_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: INTEGER_jer.c:194
asn_strtoimax_lim
enum asn_strtox_result_e asn_strtoimax_lim(const char *str, const char **end, intmax_t *l)
Definition: INTEGER.c:538
JPBD_BODY_CONSUMED
@ JPBD_BODY_CONSUMED
Definition: asn_codecs_prim.h:61
ASN__PRIMITIVE_TYPE_s
Definition: asn_codecs_prim.h:14
ASN_STRTOX_EXPECT_MORE
@ ASN_STRTOX_EXPECT_MORE
Definition: INTEGER.h:120
jer_pbd_rval
jer_pbd_rval
Definition: asn_codecs_prim.h:56
JPBD_SYSTEM_FAILURE
@ JPBD_SYSTEM_FAILURE
Definition: asn_codecs_prim.h:57
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
INTEGER_decode_jer
asn_dec_rval_t INTEGER_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_jer_constraints_t *constraints, void **sptr, const void *buf_ptr, size_t size)
Definition: INTEGER_jer.c:183
ASN__PRIMITIVE_TYPE_s::size
size_t size
Definition: asn_codecs_prim.h:16
INTEGER__dump
ssize_t INTEGER__dump(const asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER)
Definition: INTEGER.c:103
asn_jer_constraints_s
Definition: jer_support.h:18
je2v_key::vemap
const asn_INTEGER_enum_map_t * vemap
Definition: INTEGER_jer.c:12
JPBD_NOT_BODY_IGNORE
@ JPBD_NOT_BODY_IGNORE
Definition: asn_codecs_prim.h:60
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
ASN_STRTOX_OK
@ ASN_STRTOX_OK
Definition: INTEGER.h:121
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
ASN__ENCODE_FAILED
#define ASN__ENCODE_FAILED
Definition: asn_codecs.h:59
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
je2v_key::stop
const char * stop
Definition: INTEGER_jer.c:11
ASN__PRIMITIVE_TYPE_s::buf
uint8_t * buf
Definition: asn_codecs_prim.h:15
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
asn_imax2INTEGER
int asn_imax2INTEGER(INTEGER_t *i, intmax_t l)
Definition: INTEGER.c:329
jer_decode_primitive
asn_dec_rval_t jer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr, 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
asn_INTEGER_specifics_s
Definition: INTEGER.h:28
je2v_key::start
const char * start
Definition: INTEGER_jer.c:10
ASN_STRTOX_ERROR_RANGE
@ ASN_STRTOX_ERROR_RANGE
Definition: INTEGER.h:118
ASN_STRTOX_EXTRA_DATA
@ ASN_STRTOX_EXTRA_DATA
Definition: INTEGER.h:122
JPBD_DECODER_LIMIT
@ JPBD_DECODER_LIMIT
Definition: asn_codecs_prim.h:58
INTEGER.h
INTEGER__jer_body_decode
static enum jer_pbd_rval INTEGER__jer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size)
Definition: INTEGER_jer.c:33
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
JPBD_BROKEN_ENCODING
@ JPBD_BROKEN_ENCODING
Definition: asn_codecs_prim.h:59
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_dec_rval_s
Definition: asn_codecs.h:86
asn_enc_rval_s::encoded
ssize_t encoded
Definition: asn_codecs.h:47
INTEGER_jer_st_prealloc
static int INTEGER_jer_st_prealloc(INTEGER_t *st, int min_size)
Definition: INTEGER_jer.c:17
asn_INTEGER_specifics_s::field_unsigned
int field_unsigned
Definition: INTEGER.h:35
je2v_key::evmap
const unsigned int * evmap
Definition: INTEGER_jer.c:13
ASN_STRTOX_ERROR_INVAL
@ ASN_STRTOX_ERROR_INVAL
Definition: INTEGER.h:119
asn_INTEGER_enum_map_s
Definition: INTEGER.h:21


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