OCTET_STRING_uper.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_cam_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, void **sptr,
28  asn_per_data_t *pd) {
29  const asn_OCTET_STRING_specifics_t *specs = td->specifics
32  const asn_per_constraints_t *pc =
33  constraints ? constraints : td->encoding_constraints.per_constraints;
34  const asn_per_constraint_t *cval;
35  const asn_per_constraint_t *csiz;
36  asn_dec_rval_t rval = { RC_OK, 0 };
37  OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
38  ssize_t consumed_myself = 0;
39  int repeat;
40  enum {
41  OS__BPC_CHAR = 1,
42  OS__BPC_U16 = 2,
43  OS__BPC_U32 = 4
44  } bpc; /* Bytes per character */
45  unsigned int unit_bits;
46  unsigned int canonical_unit_bits;
47 
48  (void)opt_codec_ctx;
49 
50  if(pc) {
51  cval = &pc->value;
52  csiz = &pc->size;
53  } else {
56  }
57 
58  switch(specs->subvariant) {
59  default:
60  case ASN_OSUBV_ANY:
61  case ASN_OSUBV_BIT:
62  ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
63  RETURN(RC_FAIL);
64  break;
65  case ASN_OSUBV_STR:
66  canonical_unit_bits = unit_bits = 8;
67  if(cval->flags & APC_CONSTRAINED)
68  unit_bits = cval->range_bits;
69  bpc = OS__BPC_CHAR;
70  break;
71  case ASN_OSUBV_U16:
72  canonical_unit_bits = unit_bits = 16;
73  if(cval->flags & APC_CONSTRAINED)
74  unit_bits = cval->range_bits;
75  bpc = OS__BPC_U16;
76  break;
77  case ASN_OSUBV_U32:
78  canonical_unit_bits = unit_bits = 32;
79  if(cval->flags & APC_CONSTRAINED)
80  unit_bits = cval->range_bits;
81  bpc = OS__BPC_U32;
82  break;
83  }
84 
85  /*
86  * Allocate the string.
87  */
88  if(!st) {
89  st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
90  if(!st) RETURN(RC_FAIL);
91  }
92 
93  ASN_DEBUG("PER Decoding %s size %"ASN_PRIdMAX" .. %"ASN_PRIdMAX" bits %d",
94  csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
95  csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
96 
97  if(csiz->flags & APC_EXTENSIBLE) {
98  int inext = per_get_few_bits(pd, 1);
99  if(inext < 0) RETURN(RC_WMORE);
100  if(inext) {
102  unit_bits = canonical_unit_bits;
103  }
104  }
105 
106  if(csiz->effective_bits >= 0) {
107  FREEMEM(st->buf);
108  if(bpc) {
109  st->size = csiz->upper_bound * bpc;
110  } else {
111  st->size = (csiz->upper_bound + 7) >> 3;
112  }
113  st->buf = (uint8_t *)MALLOC(st->size + 1);
114  if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
115  }
116 
117  /* X.691, #16.5: zero-length encoding */
118  /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
119  /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
120  if(csiz->effective_bits == 0) {
121  int ret;
122  if(bpc) {
123  ASN_DEBUG("Encoding OCTET STRING size %"ASN_PRIdMAX"",
124  csiz->upper_bound);
125  ret = OCTET_STRING_per_get_characters(pd, st->buf,
126  csiz->upper_bound,
127  bpc, unit_bits,
128  cval->lower_bound,
129  cval->upper_bound,
130  pc);
131  if(ret > 0) RETURN(RC_FAIL);
132  } else {
133  ASN_DEBUG("Encoding BIT STRING size %"ASN_PRIdMAX"",
134  csiz->upper_bound);
135  ret = per_get_many_bits(pd, st->buf, 0,
136  unit_bits * csiz->upper_bound);
137  }
138  if(ret < 0) RETURN(RC_WMORE);
139  consumed_myself += unit_bits * csiz->upper_bound;
140  st->buf[st->size] = 0;
141  RETURN(RC_OK);
142  }
143 
144  st->size = 0;
145  do {
146  ssize_t raw_len;
147  ssize_t len_bytes;
148  void *p;
149  int ret;
150 
151  /* Get the PER length */
152  raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound,
153  &repeat);
154  if(raw_len < 0) RETURN(RC_WMORE);
155  if(raw_len == 0 && st->buf) break;
156 
157  ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
158  (long)csiz->effective_bits, (long)raw_len,
159  repeat ? "repeat" : "once", td->name);
160  len_bytes = raw_len * bpc;
161  p = REALLOC(st->buf, st->size + len_bytes + 1);
162  if(!p) RETURN(RC_FAIL);
163  st->buf = (uint8_t *)p;
164 
165  ret = OCTET_STRING_per_get_characters(pd, &st->buf[st->size], raw_len,
166  bpc, unit_bits, cval->lower_bound,
167  cval->upper_bound, pc);
168  if(ret > 0) RETURN(RC_FAIL);
169  if(ret < 0) RETURN(RC_WMORE);
170  st->size += len_bytes;
171  } while(repeat);
172  st->buf[st->size] = 0; /* nul-terminate */
173 
174  return rval;
175 }
176 
179  const asn_per_constraints_t *constraints,
180  const void *sptr, asn_per_outp_t *po) {
181  const asn_OCTET_STRING_specifics_t *specs = td->specifics
184  const asn_per_constraints_t *pc = constraints
185  ? constraints
187  const asn_per_constraint_t *cval;
188  const asn_per_constraint_t *csiz;
189  const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
190  asn_enc_rval_t er = { 0, 0, 0 };
191  int inext = 0; /* Lies not within extension root */
192  unsigned int unit_bits;
193  unsigned int canonical_unit_bits;
194  size_t size_in_units;
195  const uint8_t *buf;
196  int ret;
197  enum {
198  OS__BPC_CHAR = 1,
199  OS__BPC_U16 = 2,
200  OS__BPC_U32 = 4
201  } bpc; /* Bytes per character */
202  int ct_extensible;
203 
204  if(!st || (!st->buf && st->size))
206 
207  if(pc) {
208  cval = &pc->value;
209  csiz = &pc->size;
210  } else {
213  }
214  ct_extensible = csiz->flags & APC_EXTENSIBLE;
215 
216  switch(specs->subvariant) {
217  default:
218  case ASN_OSUBV_ANY:
219  case ASN_OSUBV_BIT:
221  case ASN_OSUBV_STR:
222  canonical_unit_bits = unit_bits = 8;
223  if(cval->flags & APC_CONSTRAINED)
224  unit_bits = cval->range_bits;
225  bpc = OS__BPC_CHAR;
226  size_in_units = st->size;
227  break;
228  case ASN_OSUBV_U16:
229  canonical_unit_bits = unit_bits = 16;
230  if(cval->flags & APC_CONSTRAINED)
231  unit_bits = cval->range_bits;
232  bpc = OS__BPC_U16;
233  size_in_units = st->size >> 1;
234  if(st->size & 1) {
235  ASN_DEBUG("%s string size is not modulo 2", td->name);
237  }
238  break;
239  case ASN_OSUBV_U32:
240  canonical_unit_bits = unit_bits = 32;
241  if(cval->flags & APC_CONSTRAINED)
242  unit_bits = cval->range_bits;
243  bpc = OS__BPC_U32;
244  size_in_units = st->size >> 2;
245  if(st->size & 3) {
246  ASN_DEBUG("%s string size is not modulo 4", td->name);
248  }
249  break;
250  }
251 
252  ASN_DEBUG("Encoding %s into %" ASN_PRI_SIZE " units of %d bits"
253  " (%"ASN_PRIdMAX"..%"ASN_PRIdMAX", effective %d)%s",
254  td->name, size_in_units, unit_bits,
255  csiz->lower_bound, csiz->upper_bound,
256  csiz->effective_bits, ct_extensible ? " EXT" : "");
257 
258  /* Figure out whether size lies within PER visible constraint */
259 
260  if(csiz->effective_bits >= 0) {
261  if((ssize_t)size_in_units < csiz->lower_bound
262  || (ssize_t)size_in_units > csiz->upper_bound) {
263  if(ct_extensible) {
265  unit_bits = canonical_unit_bits;
266  inext = 1;
267  } else {
269  }
270  }
271  } else {
272  inext = 0;
273  }
274 
275  if(ct_extensible) {
276  /* Declare whether length is [not] within extension root */
277  if(per_put_few_bits(po, inext, 1))
279  }
280 
281  if(csiz->effective_bits >= 0 && !inext) {
282  ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes (%"ASN_PRIdMAX"), length in %d bits", st->size,
283  size_in_units - csiz->lower_bound, csiz->effective_bits);
284  ret = per_put_few_bits(po, size_in_units - csiz->lower_bound,
285  csiz->effective_bits);
286  if(ret) ASN__ENCODE_FAILED;
287  ret = OCTET_STRING_per_put_characters(po, st->buf, size_in_units, bpc,
288  unit_bits, cval->lower_bound,
289  cval->upper_bound, pc);
290  if(ret) ASN__ENCODE_FAILED;
291  ASN__ENCODED_OK(er);
292  }
293 
294  ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size);
295 
296  buf = st->buf;
297  ASN_DEBUG("Encoding %" ASN_PRI_SIZE " in units", size_in_units);
298  do {
299  int need_eom = 0;
300  ssize_t may_save = uper_put_length(po, size_in_units, &need_eom);
301  if(may_save < 0) ASN__ENCODE_FAILED;
302 
303  ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "%s", may_save, size_in_units,
304  need_eom ? ",+EOM" : "");
305 
306  ret = OCTET_STRING_per_put_characters(po, buf, may_save, bpc, unit_bits,
307  cval->lower_bound,
308  cval->upper_bound, pc);
309  if(ret) ASN__ENCODE_FAILED;
310 
311  buf += may_save * bpc;
312  size_in_units -= may_save;
313  assert(!(may_save & 0x07) || !size_in_units);
314  if(need_eom && uper_put_length(po, 0, 0))
315  ASN__ENCODE_FAILED; /* End of Message length */
316  } while(size_in_units);
317 
318  ASN__ENCODED_OK(er);
319 }
asn_bit_outp_s
Definition: asn_bit_data.h:56
OCTET_STRING_decode_uper
asn_dec_rval_t OCTET_STRING_decode_uper(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_uper.c:25
ASN_PRIdMAX
#define ASN_PRIdMAX
Definition: asn_system.h:181
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
asn_enc_rval_s
Definition: asn_codecs.h:41
uper_put_length
ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length, int *opt_need_eom)
Definition: uper_support.c:168
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
OCTET_STRING::buf
uint8_t * buf
Definition: OCTET_STRING.h:15
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
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
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
ASN_PRI_SIZE
#define ASN_PRI_SIZE
Definition: asn_system.h:172
asn_DEF_OCTET_STRING_constraints
static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints
Definition: OCTET_STRING_uper.c:18
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
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
OCTET_STRING
Definition: OCTET_STRING.h:14
ASN_PRI_SSIZE
#define ASN_PRI_SSIZE
Definition: asn_system.h:173
OCTET_STRING_encode_uper
asn_enc_rval_t OCTET_STRING_encode_uper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: OCTET_STRING_uper.c:178
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
RETURN
#define RETURN(_code)
Definition: OCTET_STRING_uper.c:11
uper_get_length
ssize_t uper_get_length(asn_per_data_t *pd, int effective_bound_bits, size_t lower_bound, int *repeat)
Definition: uper_support.c:14
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
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
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
OCTET_STRING::size
size_t size
Definition: OCTET_STRING.h:16


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