OCTET_STRING_aper.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 #include <etsi_its_cpm_ts_coding/BIT_STRING.h> /* for .bits_unused member */
9 
10 #undef RETURN
11 #define RETURN(_code) do {\
12  asn_dec_rval_t tmprval;\
13  tmprval.code = _code;\
14  tmprval.consumed = consumed_myself;\
15  return tmprval;\
16  } while(0)
17 
19  { APC_CONSTRAINED, 8, 8, 0, 255 },
20  { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
21  0, 0
22 };
23 
26  const asn_TYPE_descriptor_t *td,
27  const asn_per_constraints_t *constraints,
28  void **sptr, asn_per_data_t *pd) {
29 
30  const asn_OCTET_STRING_specifics_t *specs = td->specifics
33  const asn_per_constraints_t *pc = constraints
34  ? constraints
36  const asn_per_constraint_t *cval;
37  const asn_per_constraint_t *csiz;
38  asn_dec_rval_t rval = { RC_OK, 0 };
39  BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
40  ssize_t consumed_myself = 0;
41  int repeat;
42  enum {
43  OS__BPC_BIT = 0,
44  OS__BPC_CHAR = 1,
45  OS__BPC_U16 = 2,
46  OS__BPC_U32 = 4
47  } bpc; /* Bytes per character */
48  unsigned int unit_bits;
49  unsigned int canonical_unit_bits;
50 
51  (void)opt_codec_ctx;
52 
53  if(pc) {
54  cval = &pc->value;
55  csiz = &pc->size;
56  } else {
59  }
60 
61  switch(specs->subvariant) {
62  case ASN_OSUBV_ANY:
63  case ASN_OSUBV_STR:
64  canonical_unit_bits = unit_bits = 8;
65  if(cval->flags & APC_CONSTRAINED) {
66  /* follow power of 2 rule */
67  if (cval->range_bits <= 2) {
68  unit_bits = 2;
69  } else {
70  if (cval->range_bits <= 4) {
71  unit_bits = 4;
72  /* otherwise, unit_bits = 8; */
73  }
74  }
75  /* unit_bits = cval->range_bits; */
76  ASN_DEBUG("APER decoding ASN_OSUBV_STR range_bits = %d unit_bits = %d\n",
77  cval->range_bits, unit_bits);
78  }
79  bpc = OS__BPC_CHAR;
80  break;
81  case ASN_OSUBV_U16:
82  canonical_unit_bits = unit_bits = 16;
83  if(cval->flags & APC_CONSTRAINED) {
84  unit_bits = cval->range_bits;
85  ASN_DEBUG("APER decoding ASN_OSUBV_U16 range_bits = %d\n", cval->range_bits);
86  }
87  bpc = OS__BPC_U16;
88  break;
89  case ASN_OSUBV_U32:
90  canonical_unit_bits = unit_bits = 32;
91  if(cval->flags & APC_CONSTRAINED) {
92  unit_bits = cval->range_bits;
93  ASN_DEBUG("APER decoding ASN_OSUBV_U32 range_bits = %d\n", cval->range_bits);
94  }
95  bpc = OS__BPC_U32;
96  break;
97 /*
98  case ASN_OSUBV_ANY:
99  ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
100  RETURN(RC_FAIL);
101 */
102  case ASN_OSUBV_BIT:
103  default:
104  canonical_unit_bits = unit_bits = 1;
105  bpc = OS__BPC_BIT;
106  break;
107  }
108 
109  /*
110  * Allocate the string.
111  */
112  if(!st) {
113  st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
114  if(!st) RETURN(RC_FAIL);
115  }
116 
117  ASN_DEBUG("PER Decoding %s size %lld .. %lld bits %d",
118  csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
119  (long long int)csiz->lower_bound, (long long int)csiz->upper_bound,
120  csiz->effective_bits);
121 
122  if(csiz->flags & APC_EXTENSIBLE) {
123  int inext = per_get_few_bits(pd, 1);
124  if(inext < 0) RETURN(RC_WMORE);
125  if(inext) {
128  unit_bits = canonical_unit_bits;
129  }
130  }
131 
132  if(csiz->effective_bits >= 0) {
133  FREEMEM(st->buf);
134  if(bpc) {
135  st->size = csiz->upper_bound * bpc;
136  } else {
137  st->size = (csiz->upper_bound + 7) >> 3;
138  }
139  st->buf = (uint8_t *)MALLOC(st->size + 1);
140  if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
141  }
142 
143  /* X.691, #16.5: zero-length encoding */
144  /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
145  /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
146  if(csiz->effective_bits == 0) {
147  int ret;
148  /* X.691 #16 NOTE 1 for fixed length (<= 16 bits) strings */
149  if (st->size > 2 || csiz->range_bits != 0) {
150  if (aper_get_align(pd) < 0)
151  RETURN(RC_FAIL);
152  }
153  if(bpc) {
154  ASN_DEBUG("Decoding OCTET STRING size %lld",
155  (long long int)csiz->upper_bound);
156  ret = OCTET_STRING_per_get_characters(pd, st->buf,
157  csiz->upper_bound,
158  bpc, unit_bits,
159  cval->lower_bound,
160  cval->upper_bound,
161  pc);
162  if(ret > 0) RETURN(RC_FAIL);
163  } else {
164  ASN_DEBUG("Decoding BIT STRING size %lld",
165  (long long int)csiz->upper_bound);
166  ret = per_get_many_bits(pd, st->buf, 0,
167  unit_bits * csiz->upper_bound);
168  }
169  if(ret < 0) RETURN(RC_WMORE);
170  consumed_myself += unit_bits * csiz->upper_bound;
171  st->buf[st->size] = 0;
172  if(bpc == 0) {
173  int ubs = (csiz->upper_bound & 0x7);
174  st->bits_unused = ubs ? 8 - ubs : 0;
175  }
176  RETURN(RC_OK);
177  }
178 
179  st->size = 0;
180  do {
181  ssize_t raw_len;
182  ssize_t len_bytes;
183  ssize_t len_bits;
184  void *p;
185  int ret;
186 
187  repeat = 0;
188  /* Get the PER length */
189  if (csiz->upper_bound - csiz->lower_bound == 0)
190  /* Indefinite length case */
191  raw_len = aper_get_length(pd, -1, -1, csiz->effective_bits, &repeat);
192  else
193  raw_len = aper_get_length(pd, csiz->lower_bound, csiz->upper_bound,
194  csiz->effective_bits, &repeat);
195  if(raw_len < 0) RETURN(RC_WMORE);
196 
197  ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
198  (long)csiz->effective_bits, (long)raw_len,
199  repeat ? "repeat" : "once", td->name);
200 
201  /* X.691 #16 NOTE 1 for fixed length (<=16 bits) strings */
202  if ((raw_len > 2) || (csiz->upper_bound > 2) || (csiz->range_bits != 0))
203  {
204  if (aper_get_align(pd) < 0)
205  RETURN(RC_FAIL);
206  }
207 
208  if(bpc) {
209  len_bytes = raw_len * bpc;
210  len_bits = len_bytes * unit_bits;
211  } else {
212  len_bits = raw_len;
213  len_bytes = (len_bits + 7) >> 3;
214  if(len_bits & 0x7)
215  st->bits_unused = 8 - (len_bits & 0x7);
216  /* len_bits be multiple of 16K if repeat is set */
217  }
218  p = REALLOC(st->buf, st->size + len_bytes + 1);
219  if(!p) RETURN(RC_FAIL);
220  st->buf = (uint8_t *)p;
221 
222  if(bpc) {
224  &st->buf[st->size],
225  raw_len, bpc,
226  unit_bits,
227  cval->lower_bound,
228  cval->upper_bound,
229  pc);
230  if(ret > 0) RETURN(RC_FAIL);
231  } else {
232  ret = per_get_many_bits(pd, &st->buf[st->size],
233  0, len_bits);
234  }
235  if(ret < 0) RETURN(RC_WMORE);
236  st->size += len_bytes;
237  } while(repeat);
238  st->buf[st->size] = 0; /* nul-terminate */
239 
240  return rval;
241 }
242 
245  const asn_per_constraints_t *constraints,
246  const void *sptr, asn_per_outp_t *po) {
247 
248  const asn_OCTET_STRING_specifics_t *specs = td->specifics
251  const asn_per_constraints_t *pc = constraints
252  ? constraints
254  const asn_per_constraint_t *cval;
255  const asn_per_constraint_t *csiz;
256  const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
257  asn_enc_rval_t er = { 0, 0, 0 };
258  int inext = 0; /* Lies not within extension root */
259  unsigned int unit_bits;
260  unsigned int canonical_unit_bits;
261  unsigned int sizeinunits;
262  const uint8_t *buf;
263  int ret;
264  enum {
265  OS__BPC_BIT = 0,
266  OS__BPC_CHAR = 1,
267  OS__BPC_U16 = 2,
268  OS__BPC_U32 = 4
269  } bpc; /* Bytes per character */
270  int ct_extensible;
271 
272  if(!st || (!st->buf && st->size))
274 
275  if(pc) {
276  cval = &pc->value;
277  csiz = &pc->size;
278  } else {
281  }
282  ct_extensible = csiz->flags & APC_EXTENSIBLE;
283 
284  switch(specs->subvariant) {
285  case ASN_OSUBV_ANY:
286  case ASN_OSUBV_STR:
287  canonical_unit_bits = unit_bits = 8;
288  if(cval->flags & APC_CONSTRAINED) {
289  /* follow power of 2 rule */
290  if (cval->range_bits <= 2) {
291  unit_bits = 2;
292  } else {
293  if (cval->range_bits <= 4)
294  unit_bits = 4;
295  /* otherwise, unit_bits = 8; */
296  }
297  /* unit_bits = cval->range_bits; */
298  ASN_DEBUG("APER encoding ASN_OSUBV_STR range_bits = %d unit_bits = %d\n",
299  cval->range_bits, unit_bits);
300  }
301  bpc = OS__BPC_CHAR;
302  sizeinunits = st->size;
303  break;
304  case ASN_OSUBV_U16:
305  canonical_unit_bits = unit_bits = 16;
306  if(cval->flags & APC_CONSTRAINED) {
307  unit_bits = cval->range_bits;
308  ASN_DEBUG("APER encoding ASN_OSUBV_U16 range_bits = %d\n", cval->range_bits);
309  }
310  bpc = OS__BPC_U16;
311  sizeinunits = st->size / 2;
312  break;
313  case ASN_OSUBV_U32:
314  canonical_unit_bits = unit_bits = 32;
315  if(cval->flags & APC_CONSTRAINED) {
316  unit_bits = cval->range_bits;
317  ASN_DEBUG("APER encoding ASN_OSUBV_U32 range_bits = %d\n", cval->range_bits);
318  }
319  bpc = OS__BPC_U32;
320  sizeinunits = st->size / 4;
321  break;
322 /*
323  case ASN_OSUBV_ANY:
324  ASN__ENCODE_FAILED;
325 */
326  case ASN_OSUBV_BIT:
327  default:
328  canonical_unit_bits = unit_bits = 1;
329  bpc = OS__BPC_BIT;
330  sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
331  ASN_DEBUG("BIT STRING of %d bytes", sizeinunits);
332  break;
333  }
334 
335  ASN_DEBUG("Encoding %s into %d units of %d bits"
336  " (%lld..%lld, effective %d)%s",
337  td->name, sizeinunits, unit_bits,
338  (long long int)csiz->lower_bound,
339  (long long int)csiz->upper_bound,
340  csiz->effective_bits, ct_extensible ? " EXT" : "");
341 
342  /* Figure out wheter size lies within PER visible constraint */
343 
344  if(csiz->effective_bits >= 0) {
345  if((int)sizeinunits < csiz->lower_bound
346  || (int)sizeinunits > csiz->upper_bound) {
347  if(ct_extensible) {
350  unit_bits = canonical_unit_bits;
351  inext = 1;
352  } else
354  }
355  } else {
356  inext = 0;
357  }
358 
359  if(ct_extensible) {
360  /* Declare whether length is [not] within extension root */
361  if(per_put_few_bits(po, inext, 1))
363  }
364 
365  /* X.691, #16.5: zero-length encoding */
366  /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
367  /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
368  if(csiz->effective_bits >= 0) {
369  ASN_DEBUG("Encoding %zu bytes (%lld), length in %d bits",
370  st->size, (long long int)(sizeinunits - csiz->lower_bound),
371  csiz->effective_bits);
372  if (csiz->effective_bits > 0) {
373  ret = aper_put_length(po, csiz->lower_bound, csiz->upper_bound,
374  sizeinunits - csiz->lower_bound, NULL);
375  if(ret < 0) ASN__ENCODE_FAILED;
376  }
377  if (csiz->effective_bits > 0 || (st->size > 2)
378  || (csiz->upper_bound > (2 * 8 / unit_bits))
379  || (csiz->range_bits != 0))
380  { /* X.691 #16 NOTE 1 for fixed length (<=16 bits) strings*/
381  if (aper_put_align(po) < 0)
383  }
384  if(bpc) {
385  ret = OCTET_STRING_per_put_characters(po, st->buf,
386  sizeinunits,
387  bpc, unit_bits,
388  cval->lower_bound,
389  cval->upper_bound,
390  pc);
391  } else {
392  ret = per_put_many_bits(po, st->buf,
393  sizeinunits * unit_bits);
394  }
395  if(ret) ASN__ENCODE_FAILED;
396  ASN__ENCODED_OK(er);
397  }
398 
399  ASN_DEBUG("Encoding %zu bytes", st->size);
400 
401  if(sizeinunits == 0) {
402  if(aper_put_length(po, -1, -1, 0, NULL) < 0)
404  ASN__ENCODED_OK(er);
405  }
406 
407  buf = st->buf;
408  while(sizeinunits) {
409  int need_eom = 0;
410  ssize_t maySave = aper_put_length(po, -1, -1, sizeinunits, &need_eom);
411 
412  if(maySave < 0) ASN__ENCODE_FAILED;
413 
414  ASN_DEBUG("Encoding %ld of %ld",
415  (long)maySave, (long)sizeinunits);
416 
417  if(bpc) {
418  ret = OCTET_STRING_per_put_characters(po, buf, maySave,
419  bpc, unit_bits,
420  cval->lower_bound,
421  cval->upper_bound,
422  pc);
423  } else {
424  ret = per_put_many_bits(po, buf, maySave * unit_bits);
425  }
426  if(ret) ASN__ENCODE_FAILED;
427 
428  if(bpc)
429  buf += maySave * bpc;
430  else
431  buf += maySave >> 3;
432  sizeinunits -= maySave;
433  assert(!(maySave & 0x07) || !sizeinunits);
434  if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0))
435  ASN__ENCODE_FAILED; /* End of Message length */
436  }
437 
438  ASN__ENCODED_OK(er);
439 }
asn_bit_outp_s
Definition: asn_bit_data.h:56
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
BIT_STRING_s::buf
uint8_t * buf
Definition: BIT_STRING.h:15
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
asn_enc_rval_s
Definition: asn_codecs.h:41
BIT_STRING_s::size
size_t size
Definition: BIT_STRING.h:16
aper_put_align
int aper_put_align(asn_per_outp_t *po)
Definition: aper_support.c:185
aper_put_length
ssize_t aper_put_length(asn_per_outp_t *po, ssize_t lb, ssize_t ub, size_t n, int *opt_need_eom)
Definition: aper_support.c:196
RC_WMORE
@ RC_WMORE
Definition: asn_codecs.h:83
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
per_get_few_bits
#define per_get_few_bits(data, bits)
Definition: per_support.h:39
asn_per_constraints_s::value
asn_per_constraint_t value
Definition: per_support.h:31
asn_per_constraint_s
Definition: per_support.h:18
BIT_STRING_s
Definition: BIT_STRING.h:14
asn_OCTET_STRING_specifics_s
Definition: OCTET_STRING.h:125
asn_SPC_OCTET_STRING_specs
asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs
Definition: OCTET_STRING.c:16
REALLOC
#define REALLOC(oldptr, size)
Definition: asn_internal.h:39
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
asn_bit_data_s
Definition: asn_bit_data.h:17
ASN__ENCODE_FAILED
#define ASN__ENCODE_FAILED
Definition: asn_codecs.h:59
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
aper_get_align
int32_t aper_get_align(asn_per_data_t *pd)
Definition: aper_support.c:10
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
asn_OCTET_STRING_specifics_s::subvariant
enum asn_OCTET_STRING_specifics_s::asn_OS_Subvariant subvariant
OCTET_STRING_decode_aper
asn_dec_rval_t OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
Definition: OCTET_STRING_aper.c:25
RC_OK
@ RC_OK
Definition: asn_codecs.h:82
OCTET_STRING_per_put_characters
int OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf, size_t units, unsigned int bpc, unsigned int unit_bits, long lb, long ub, const asn_per_constraints_t *pc)
Definition: OCTET_STRING.c:359
aper_get_length
ssize_t aper_get_length(asn_per_data_t *pd, ssize_t lb, ssize_t ub, int effective_bound_bits, int *repeat)
Definition: aper_support.c:20
per_put_many_bits
#define per_put_many_bits(out, src, nbits)
Definition: per_support.h:47
asn_DEF_OCTET_STRING_constraints
static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints
Definition: OCTET_STRING_aper.c:18
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
OCTET_STRING_encode_aper
asn_enc_rval_t OCTET_STRING_encode_aper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: OCTET_STRING_aper.c:244
per_get_many_bits
#define per_get_many_bits(data, dst, align, bits)
Definition: per_support.h:41
asn_encoding_constraints_s::per_constraints
const struct asn_per_constraints_s * per_constraints
Definition: constr_TYPE.h:213
asn_per_constraints_s::size
asn_per_constraint_t size
Definition: per_support.h:32
asn_internal.h
asn_codec_ctx_s
Definition: asn_codecs.h:23
asn_dec_rval_s
Definition: asn_codecs.h:86
asn_per_constraints_s
Definition: per_support.h:30
BIT_STRING.h
OCTET_STRING_per_get_characters
int OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, size_t units, unsigned int bpc, unsigned int unit_bits, long lb, long ub, const asn_per_constraints_t *pc)
Definition: OCTET_STRING.c:295
BIT_STRING_s::bits_unused
int bits_unused
Definition: BIT_STRING.h:18
asn_TYPE_descriptor_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:247
asn_per_constraint_s::flags
enum asn_per_constraint_s::asn_per_constraint_flags flags
RETURN
#define RETURN(_code)
Definition: OCTET_STRING_aper.c:11
OCTET_STRING.h
per_put_few_bits
#define per_put_few_bits(out, bits, obits)
Definition: per_support.h:46
RC_FAIL
@ RC_FAIL
Definition: asn_codecs.h:84


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