INTEGER_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 
10 INTEGER_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
11  const asn_TYPE_descriptor_t *td,
12  const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
13  const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
14  asn_dec_rval_t rval = { RC_OK, 0 };
15  INTEGER_t *st = (INTEGER_t *)*sptr;
16  const asn_per_constraint_t *ct;
17  int repeat;
18 
19  (void)opt_codec_ctx;
20 
21  if(!st) {
22  st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
23  if(!st) ASN__DECODE_FAILED;
24  }
25 
26  if(!constraints) constraints = td->encoding_constraints.per_constraints;
27  ct = constraints ? &constraints->value : 0;
28 
29  if(ct && ct->flags & APC_EXTENSIBLE) {
30  int inext = per_get_few_bits(pd, 1);
31  if(inext < 0) ASN__DECODE_STARVED;
32  if(inext) ct = 0;
33  }
34 
35  FREEMEM(st->buf);
36  st->buf = 0;
37  st->size = 0;
38  if(ct) {
39  if(ct->flags & APC_SEMI_CONSTRAINED) {
40  st->buf = (uint8_t *)CALLOC(1, 2);
41  if(!st->buf) ASN__DECODE_FAILED;
42  st->size = 1;
43  } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
44  size_t size = (ct->range_bits + 7) >> 3;
45  st->buf = (uint8_t *)MALLOC(1 + size + 1);
46  if(!st->buf) ASN__DECODE_FAILED;
47  st->size = size;
48  }
49  }
50 
51  /* X.691, #12.2.2 */
52  if(ct && ct->flags != APC_UNCONSTRAINED) {
53  /* #10.5.6 */
54  ASN_DEBUG("Integer with range %d bits", ct->range_bits);
55  if(ct->range_bits >= 0) {
56  if (ct->range_bits > 16) {
57  int max_range_bytes = (ct->range_bits >> 3) +
58  (((ct->range_bits % 8) > 0) ? 1 : 0);
59  int length = 0, i;
60  intmax_t value = 0;
61 
62  for (i = 1; ; i++) {
63  int upper = 1 << i;
64  if (upper >= max_range_bytes)
65  break;
66  }
67  ASN_DEBUG("Can encode %d (%d bytes) in %d bits", ct->range_bits,
68  max_range_bytes, i);
69 
70  if ((length = per_get_few_bits(pd, i)) < 0)
72 
73  /* X.691 #12.2.6 length determinant + lb (1) */
74  length += 1;
75  ASN_DEBUG("Got length %d", length);
76  if (aper_get_align(pd) != 0)
78  while (length--) {
79  int buf = per_get_few_bits(pd, 8);
80  if (buf < 0)
82  value += (((intmax_t)buf) << (8 * length));
83  }
84 
85  value += ct->lower_bound;
86  if((specs && specs->field_unsigned)
87  ? asn_umax2INTEGER(st, (uintmax_t)value)
88  : asn_imax2INTEGER(st, value))
90  ASN_DEBUG("Got value %"ASN_PRIdMAX" + low %"ASN_PRIdMAX"",
91  value, (intmax_t)ct->lower_bound);
92  } else {
93  intmax_t value = 0;
94  if (ct->range_bits < 8) {
95  value = per_get_few_bits(pd, ct->range_bits);
96  if(value < 0) ASN__DECODE_STARVED;
97  } else if (ct->range_bits == 8) {
98  if (aper_get_align(pd) < 0)
100  value = per_get_few_bits(pd, ct->range_bits);
101  if(value < 0) ASN__DECODE_STARVED;
102  } else {
103  /* Align */
104  if (aper_get_align(pd) < 0)
106  value = per_get_few_bits(pd, 16);
107  if(value < 0) ASN__DECODE_STARVED;
108  }
109  value += ct->lower_bound;
110  if((specs && specs->field_unsigned)
111  ? asn_umax2INTEGER(st, (uintmax_t)value)
112  : asn_imax2INTEGER(st, value))
114  ASN_DEBUG("Got value %"ASN_PRIdMAX" + low %"ASN_PRIdMAX"",
115  value, (intmax_t)ct->lower_bound);
116  }
117  return rval;
118  } else {
120  }
121  } else {
122  ASN_DEBUG("Decoding unconstrained integer %s", td->name);
123  }
124 
125  /* X.691, #12.2.3, #12.2.4 */
126  do {
127  ssize_t len;
128  void *p;
129  int ret;
130 
131  /* Get the PER length */
132  len = aper_get_length(pd, -1, -1, -1, &repeat);
133  if(len < 0) ASN__DECODE_STARVED;
134 
135  p = REALLOC(st->buf, st->size + len + 1);
136  if(!p) ASN__DECODE_FAILED;
137  st->buf = (uint8_t *)p;
138 
139  ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
140  if(ret < 0) ASN__DECODE_STARVED;
141  st->size += len;
142  } while(repeat);
143  st->buf[st->size] = 0; /* JIC */
144 
145  /* #12.2.3 */
146  if(ct && ct->lower_bound) {
147  /*
148  * TODO: replace by in-place arithmetics.
149  */
150  long value;
151  if(asn_INTEGER2long(st, &value))
153  if(asn_long2INTEGER(st, value + ct->lower_bound))
155  }
156 
157  return rval;
158 }
159 
162  const asn_per_constraints_t *constraints,
163  const void *sptr, asn_per_outp_t *po) {
164  const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
165  asn_enc_rval_t er = {0,0,0};
166  const INTEGER_t *st = (const INTEGER_t *)sptr;
167  const uint8_t *buf;
168  const uint8_t *end;
169  const asn_per_constraint_t *ct;
170  intmax_t value = 0;
171 
172  if(!st || st->size == 0) ASN__ENCODE_FAILED;
173 
174  if(!constraints) constraints = td->encoding_constraints.per_constraints;
175  ct = constraints ? &constraints->value : 0;
176 
177  er.encoded = 0;
178 
179  if(ct) {
180  int inext = 0;
181  if(specs && specs->field_unsigned) {
182  uintmax_t uval;
183  if(asn_INTEGER2umax(st, &uval))
185  /* Check proper range */
186  if(ct->flags & APC_SEMI_CONSTRAINED) {
187  if(uval < (uintmax_t)ct->lower_bound)
188  inext = 1;
189  } else if(ct->range_bits >= 0) {
190  if(uval < (uintmax_t)ct->lower_bound
191  || uval > (uintmax_t)ct->upper_bound)
192  inext = 1;
193  }
194  ASN_DEBUG("Value %"ASN_PRIdMAX" (%02x/%"ASN_PRI_SIZE") lb %"ASN_PRIdMAX" ub %"ASN_PRIdMAX" %s",
195  uval, st->buf[0], st->size,
196  (intmax_t)ct->lower_bound,
197  (intmax_t)ct->upper_bound,
198  inext ? "ext" : "fix");
199  value = uval;
200  } else {
201  if(asn_INTEGER2imax(st, &value)) ASN__ENCODE_FAILED;
202  /* Check proper range */
203  if(ct->flags & APC_SEMI_CONSTRAINED) {
204  if(value < ct->lower_bound)
205  inext = 1;
206  } else if(ct->range_bits >= 0) {
207  if(value < ct->lower_bound
208  || value > ct->upper_bound)
209  inext = 1;
210  }
211  ASN_DEBUG("Value %"ASN_PRIdMAX" (%02x/%"ASN_PRI_SIZE") lb %"ASN_PRIdMAX" ub %"ASN_PRIdMAX" %s",
212  value, st->buf[0], st->size,
213  (intmax_t)ct->lower_bound,
214  (intmax_t)ct->upper_bound,
215  inext ? "ext" : "fix");
216  }
217  if(ct->flags & APC_EXTENSIBLE) {
218  if(per_put_few_bits(po, inext, 1))
220  if(inext) ct = 0;
221  } else if(inext) {
223  }
224  }
225 
226  /* X.691, #12.2.2 */
227  if(ct && ct->range_bits >= 0) {
228  uintmax_t v;
229 
230  /* #10.5.6 */
231  ASN_DEBUG("Encoding integer %"ASN_PRIdMAX" (%"ASN_PRIdMAX") with range %d bits",
232  value, (intmax_t)(value - ct->lower_bound),
233  ct->range_bits);
234 
235  v = value - ct->lower_bound;
236 
237  /* #12 <= 8 -> alignment ? */
238  int range = ct->upper_bound - ct->lower_bound + 1;
239  if (ct->range_bits < 8 || (ct->range_bits == 8 && range < 256)) {
240  if(per_put_few_bits(po, 0x00 | v, ct->range_bits))
242  } else if (ct->range_bits == 8) {
243  if(aper_put_align(po) < 0)
245  if(per_put_few_bits(po, 0x00 | v, ct->range_bits))
247  } else if (ct->range_bits <= 16) {
248  /* Consume the bytes to align on octet */
249  if(aper_put_align(po) < 0)
251  if(per_put_few_bits(po, 0x0000 | v, 16))
253  } else {
254  /* TODO: extend to >64 bits */
255  int64_t v64 = v;
256  int i, j;
257  int max_range_bytes = (ct->range_bits >> 3) +
258  (((ct->range_bits % 8) > 0) ? 1 : 0);
259 
260  for (i = 1; ; i++) {
261  int upper = 1 << i;
262  if (upper >= max_range_bytes)
263  break;
264  }
265 
266  for (j = sizeof(int64_t) -1; j != 0; j--) {
267  int64_t val;
268  val = v64 >> (j * 8);
269  if (val != 0)
270  break;
271  }
272 
273  /* Putting length in the minimum number of bits ex: 5 = 3bits */
274  if (per_put_few_bits(po, j, i))
276 
277  /* Consume the bits to align on octet */
278  if (aper_put_align(po) < 0)
280  /* Put the value */
281  for (i = 0; i <= j; i++) {
282  if(per_put_few_bits(po, (v64 >> (8 * (j - i))) & 0xff, 8))
284  }
285  }
286  ASN__ENCODED_OK(er);
287  }
288 
289  if(ct && ct->lower_bound) {
290  ASN_DEBUG("Adjust lower bound to %"ASN_PRIdMAX"", (intmax_t)ct->lower_bound);
291  /* TODO: adjust lower bound */
293  }
294 
295  for(buf = st->buf, end = st->buf + st->size; buf < end;) {
296  int need_eom = 0;
297  ssize_t mayEncode = aper_put_length(po, -1, -1, end - buf, &need_eom);
298  if(mayEncode < 0)
300  if(per_put_many_bits(po, buf, 8 * mayEncode))
302  buf += mayEncode;
303  if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0))
305  }
306 
307  ASN__ENCODED_OK(er);
308 }
asn_bit_outp_s
Definition: asn_bit_data.h:56
asn_INTEGER2imax
int asn_INTEGER2imax(const INTEGER_t *i, intmax_t *l)
Definition: INTEGER.c:219
ASN__PRIMITIVE_TYPE_s
Definition: asn_codecs_prim.h:14
INTEGER_decode_aper
asn_dec_rval_t INTEGER_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: INTEGER_aper.c:10
ASN_PRIdMAX
#define ASN_PRIdMAX
Definition: asn_system.h:181
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
ASN__PRIMITIVE_TYPE_s::size
size_t size
Definition: asn_codecs_prim.h:16
asn_enc_rval_s
Definition: asn_codecs.h:41
aper_put_align
int aper_put_align(asn_per_outp_t *po)
Definition: aper_support.c:185
asn_per_constraint_s::lower_bound
intmax_t lower_bound
Definition: per_support.h:27
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
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_constraint_s
Definition: per_support.h:18
INTEGER_encode_aper
asn_enc_rval_t INTEGER_encode_aper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: INTEGER_aper.c:161
asn_INTEGER2umax
int asn_INTEGER2umax(const INTEGER_t *i, uintmax_t *l)
Definition: INTEGER.c:271
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__PRIMITIVE_TYPE_s::buf
uint8_t * buf
Definition: asn_codecs_prim.h:15
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_imax2INTEGER
int asn_imax2INTEGER(INTEGER_t *i, intmax_t l)
Definition: INTEGER.c:329
asn_umax2INTEGER
int asn_umax2INTEGER(INTEGER_t *i, uintmax_t l)
Definition: INTEGER.c:303
asn_INTEGER_specifics_s
Definition: INTEGER.h:28
RC_OK
@ RC_OK
Definition: asn_codecs.h:82
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
ASN_PRI_SIZE
#define ASN_PRI_SIZE
Definition: asn_system.h:172
per_put_many_bits
#define per_put_many_bits(out, src, nbits)
Definition: per_support.h:47
INTEGER.h
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
ASN__DECODE_STARVED
#define ASN__DECODE_STARVED
Definition: asn_codecs.h:97
per_get_many_bits
#define per_get_many_bits(data, dst, align, bits)
Definition: per_support.h:41
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_per_constraint_s::range_bits
int range_bits
Definition: per_support.h:25
asn_long2INTEGER
int asn_long2INTEGER(INTEGER_t *i, long l)
Definition: INTEGER.c:414
asn_per_constraints_s
Definition: per_support.h:30
asn_per_constraint_s::upper_bound
intmax_t upper_bound
Definition: per_support.h:28
asn_per_constraint_s::flags
enum asn_per_constraint_s::asn_per_constraint_flags flags
asn_INTEGER2long
int asn_INTEGER2long(const INTEGER_t *i, long *l)
Definition: INTEGER.c:384
per_put_few_bits
#define per_put_few_bits(out, bits, obits)
Definition: per_support.h:46


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