BIT_STRING_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  */
10 
13  const asn_jer_constraints_t *constraints,
14  const void *sptr, int ilevel,
15  enum jer_encoder_flags_e flags,
16  asn_app_consume_bytes_f *cb, void *app_key) {
17  asn_enc_rval_t er = {0, 0, 0};
18  const char * const h2c = "0123456789ABCDEF";
19  char scratch[16 * 3 + 4];
20  char *p = scratch;
21  const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
22  const asn_jer_constraints_t* cts = constraints ?
23  constraints : td->encoding_constraints.jer_constraints;
24  uint8_t *buf;
25  uint8_t *end;
26 
27  (void)ilevel;
28  (void)flags;
29 
30  int jmin = flags & JER_F_MINIFIED;
31 
32  if(!st || !st->buf)
34 
35  er.encoded = 0;
36 
37  buf = st->buf;
38  end = buf + st->size - 1; /* Last byte is special */
39 
40  /*
41  * Hex dump
42  */
43  if(cts && cts->size != -1) { /* Fixed size */
44  *p++ = '"';
45  for(int i = 0; buf < end; buf++, i++) {
46  if(!(i % 16) && (i || st->size > 16)) {
47  ASN__CALLBACK(scratch, p-scratch);
48  p = scratch;
49  }
50  *p++ = h2c[*buf >> 4];
51  *p++ = h2c[*buf & 0x0F];
52  }
53 
54  ASN__CALLBACK(scratch, p - scratch);
55  p = scratch;
56 
57  if(buf == end) {
58  int ubits = st->bits_unused;
59  uint8_t v = *buf & (0xff << ubits);
60  *p++ = h2c[v >> 4];
61  *p++ = h2c[v & 0x0F];
62  ASN__CALLBACK(scratch, p - scratch);
63  p = scratch;
64  }
65  *p++ = '"';
66  ASN__CALLBACK(scratch, p - scratch);
67  } else { /* Variable size */
68  ASN__CALLBACK("{", 1);
69  if(!jmin) {
70  ASN__TEXT_INDENT(1, ilevel + 1);
71  ASN__CALLBACK("\"value\": ", 9);
72  } else {
73  ASN__CALLBACK("\"value\":", 8);
74  }
75  *p++ = '"';
76  for(int i = 0; buf < end; buf++, i++) {
77  if(!(i % 16) && (i || st->size > 16)) {
78  ASN__CALLBACK(scratch, p-scratch);
79  p = scratch;
80  }
81  *p++ = h2c[*buf >> 4];
82  *p++ = h2c[*buf & 0x0F];
83  }
84 
85  ASN__CALLBACK(scratch, p - scratch);
86  p = scratch;
87 
88  if(buf == end) {
89  int ubits = st->bits_unused;
90  uint8_t v = *buf & (0xff << ubits);
91  *p++ = h2c[v >> 4];
92  *p++ = h2c[v & 0x0F];
93  ASN__CALLBACK(scratch, p - scratch);
94  p = scratch;
95  }
96  *p++ = '"';
97  ASN__CALLBACK(scratch, p - scratch);
98 
99  ASN__CALLBACK(",", 1);
100  if (!jmin) {
101  ASN__TEXT_INDENT(1, ilevel + 1);
102  }
103 
104  if(!jmin) {
105  ASN__CALLBACK("\"length\": ", 10);
106  } else {
107  ASN__CALLBACK("\"length\":", 9);
108  }
109  int wr = snprintf(scratch, sizeof(scratch), "%lu",
110  st->size * 8 - (st->bits_unused));
111  if(wr < 0 || (size_t)wr >= sizeof(scratch)) {
113  }
114  ASN__CALLBACK(scratch, wr);
115  if (!jmin) {
116  ASN__TEXT_INDENT(1, ilevel);
117  }
118  ASN__CALLBACK("}", 1);
119  }
120 
121  ASN__ENCODED_OK(er);
122 cb_failed:
124 }
125 
126 /*
127  * Return a standardized complex structure.
128  */
129 #undef RETURN
130 #define RETURN(_code) \
131  do { \
132  rval.code = _code; \
133  rval.consumed = consumed_myself; \
134  return rval; \
135  } while(0)
136 
137 #define SKIPCHAR(_c) \
138  do { \
139  int found = 0; \
140  for (; p < pend; ++p) { \
141  if (*p == _c) { \
142  found = 1; ++p; \
143  break; \
144  } \
145  } \
146  if(!found) RETURN(RC_WMORE); \
147  } while(0)
148 
151  const asn_TYPE_descriptor_t *td,
152  const asn_jer_constraints_t *constraints,
153  void **sptr,
154  const void *buf_ptr, size_t size) {
155  BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
156  const asn_jer_constraints_t *cts = constraints ?
157  constraints : td->encoding_constraints.jer_constraints;
158  asn_dec_rval_t rval; /* Return value from the decoder */
159  ssize_t consumed_myself = 0; /* Consumed bytes from buf_ptr */
160 
161  /*
162  * Create the string if does not exist.
163  */
164  if(!st) {
165  st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st)));
166  if(!st) ASN__DECODE_FAILED;
167  }
168 
169  const char *p = (const char*)buf_ptr;
170  const char *pend = p + size;
171 
172  if(!cts || cts->size == -1) {
173  SKIPCHAR('{');
174  SKIPCHAR('"');
175  if(pend-p < 5) RETURN(RC_WMORE);
176  if(0 != memcmp(p, "value", 5)) RETURN(RC_FAIL);
177  p += 5;
178  SKIPCHAR('"');
179  SKIPCHAR(':');
180  }
181 
182  /* bitstring value */
183  SKIPCHAR('"');
184 
185  /* calculate size */
186  const char* p0 = p;
187  SKIPCHAR('"');
188  const char* p1 = p - 1;
189  p = p0;
190 
191  void *nptr = REALLOC(st->buf, (p1-p0 + 1) / 2 + 1);
192  if(!nptr) RETURN(RC_FAIL);
193  st->buf = (uint8_t *)nptr;
194  uint8_t *buf = st->buf;
195  unsigned int clv = 0;
196  int half = 0;
197 
198  for(; p < p1; p++) {
199  int ch = *(const unsigned char *)p;
200  switch(ch) {
201  case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
202  case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
203  clv = (clv << 4) + (ch - 0x30);
204  break;
205  case 0x41: case 0x42: case 0x43: /* ABC */
206  case 0x44: case 0x45: case 0x46: /* DEF */
207  clv = (clv << 4) + (ch - 0x41 + 10);
208  break;
209  case 0x61: case 0x62: case 0x63: /* abc */
210  case 0x64: case 0x65: case 0x66: /* def */
211  clv = (clv << 4) + (ch - 0x61 + 10);
212  break;
213  default:
214  *buf = 0; /* JIC */
215  RETURN(RC_FAIL);
216  }
217  if(half++) {
218  half = 0;
219  *buf++ = clv;
220  }
221  }
222 
223  /*
224  * Check partial decoding.
225  */
226  if(half) {
227  RETURN(RC_FAIL);
228  }
229 
230  st->size = buf - st->buf; /* Adjust the buffer size */
231  st->buf[st->size] = 0; /* Courtesy termination */
232 
233  SKIPCHAR('"');
234 
235  if(!cts || cts->size == -1) {
236  SKIPCHAR(',');
237  SKIPCHAR('"');
238  if(pend-p < 6) RETURN(RC_WMORE);
239  if(0 != memcmp(p, "length", 6)) RETURN(RC_FAIL);
240  p += 6;
241  SKIPCHAR('"');
242  SKIPCHAR(':');
243  p0 = p;
244  /* Skip whitespace, numbers, for length calc for INTEGER dec
245  * Stop on first non-whitespace/non-number */
246  int numbered = 0;
247  for (; p < pend; ++p) {
248  switch (*p) {
249  case 0x09: case 0x0a: case 0x0c: case 0x0d:
250  case 0x20:
251  if(!numbered) continue;
252  else break;
253  /* Ignore whitespace */
254  case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
255  case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
256  case 0x2d: /*-*/
257  numbered = 1;
258  continue;
259  }
260  if(numbered) break;
261  }
262  if(!numbered) RETURN(RC_FAIL);
263 
264  unsigned long length;
265 
266  INTEGER_t integer = { 0 };
267  void *integer_ptr = (void *)&integer;
268  memset(&integer, 0, sizeof(integer));
269 
270  asn_dec_rval_t dec =
271  INTEGER_decode_jer(NULL, &asn_DEF_INTEGER, NULL, &integer_ptr, p0, p-p0);
272  if(dec.code == RC_OK) {
273  if(asn_INTEGER2ulong(&integer, (unsigned long *)&length)) {
274  RETURN(RC_FAIL);
275  }
276  } else {
277  RETURN(RC_FAIL);
278  }
280 
281  if(dec.code != RC_OK) RETURN(RC_FAIL);
282  st->bits_unused = (st->size * 8) - length;
283 
284  SKIPCHAR('}');
285  } else {
286  if(st->size * 8 < (size_t)cts->size) {
287  RETURN(RC_FAIL);
288  }
289  st->bits_unused = (st->size * 8) - cts->size;
290  }
291 
292  consumed_myself = (const char *)p - (const char *)buf_ptr;
293  RETURN(RC_OK);
294 }
295 
ASN__PRIMITIVE_TYPE_s
Definition: asn_codecs_prim.h:14
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
asn_jer_constraints_s::size
ssize_t size
Definition: jer_support.h:19
asn_jer_constraints_s
Definition: jer_support.h:18
BIT_STRING_s::buf
uint8_t * buf
Definition: BIT_STRING.h:15
asn_enc_rval_s
Definition: asn_codecs.h:41
BIT_STRING_encode_jer
asn_enc_rval_t BIT_STRING_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: BIT_STRING_jer.c:12
jer_encoder_flags_e
jer_encoder_flags_e
Definition: jer_encoder.h:20
BIT_STRING_s::size
size_t size
Definition: BIT_STRING.h:16
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__CALLBACK
#define ASN__CALLBACK(buf, size)
Definition: asn_internal.h:108
asn_DEF_INTEGER
asn_TYPE_descriptor_t asn_DEF_INTEGER
Definition: INTEGER.c:75
BIT_STRING_s
Definition: BIT_STRING.h:14
REALLOC
#define REALLOC(oldptr, size)
Definition: asn_internal.h:39
ASN__ENCODE_FAILED
#define ASN__ENCODE_FAILED
Definition: asn_codecs.h:59
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
ASN__TEXT_INDENT
#define ASN__TEXT_INDENT(nl, level)
Definition: asn_internal.h:117
RC_OK
@ RC_OK
Definition: asn_codecs.h:82
INTEGER_decode_jer
jer_type_decoder_f INTEGER_decode_jer
Definition: INTEGER.h:65
SKIPCHAR
#define SKIPCHAR(_c)
Definition: BIT_STRING_jer.c:137
INTEGER.h
asn_encoding_constraints_s::jer_constraints
const struct asn_jer_constraints_s * jer_constraints
Definition: constr_TYPE.h:216
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__DECODE_FAILED
#define ASN__DECODE_FAILED
Definition: asn_codecs.h:90
asn_INTEGER2ulong
int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l)
Definition: INTEGER.c:399
asn_enc_rval_s::encoded
ssize_t encoded
Definition: asn_codecs.h:47
asn_application.h
BIT_STRING.h
RETURN
#define RETURN(_code)
Definition: BIT_STRING_jer.c:130
BIT_STRING_s::bits_unused
int bits_unused
Definition: BIT_STRING.h:18
BIT_STRING_decode_jer
asn_dec_rval_t BIT_STRING_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: BIT_STRING_jer.c:150
asn_TYPE_descriptor_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:247
ASN_STRUCT_FREE_CONTENTS_ONLY
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr)
Definition: constr_TYPE.h:123
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


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