INTEGER_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 
10 INTEGER_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
11  const asn_TYPE_descriptor_t *td,
12  const asn_per_constraints_t *constraints, void **sptr,
13  asn_per_data_t *pd) {
14  const asn_INTEGER_specifics_t *specs =
16  asn_dec_rval_t rval = { RC_OK, 0 };
17  INTEGER_t *st = (INTEGER_t *)*sptr;
18  const asn_per_constraint_t *ct;
19  int repeat;
20 
21  (void)opt_codec_ctx;
22 
23  if(!st) {
24  st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
25  if(!st) ASN__DECODE_FAILED;
26  }
27 
28  if(!constraints) constraints = td->encoding_constraints.per_constraints;
29  ct = constraints ? &constraints->value : 0;
30 
31  if(ct && ct->flags & APC_EXTENSIBLE) {
32  int inext = per_get_few_bits(pd, 1);
33  if(inext < 0) ASN__DECODE_STARVED;
34  if(inext) ct = 0;
35  }
36 
37  FREEMEM(st->buf);
38  st->buf = 0;
39  st->size = 0;
40  if(ct) {
41  if(ct->flags & APC_SEMI_CONSTRAINED) {
42  st->buf = (uint8_t *)CALLOC(1, 2);
43  if(!st->buf) ASN__DECODE_FAILED;
44  st->size = 1;
45  } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
46  size_t size = (ct->range_bits + 7) >> 3;
47  st->buf = (uint8_t *)MALLOC(1 + size + 1);
48  if(!st->buf) ASN__DECODE_FAILED;
49  st->size = size;
50  }
51  }
52 
53  /* X.691-2008/11, #13.2.2, constrained whole number */
54  if(ct && ct->flags != APC_UNCONSTRAINED) {
55  /* #11.5.6 */
56  ASN_DEBUG("Integer with range %d bits", ct->range_bits);
57  if(ct->range_bits >= 0) {
58  if((size_t)ct->range_bits > 8 * sizeof(uintmax_t))
60 
61  if(specs && specs->field_unsigned) {
62  uintmax_t uvalue = 0;
64  &uvalue, ct->range_bits))
66  ASN_DEBUG("Got value %"ASN_PRIuMAX" + low %"ASN_PRIdMAX"",
67  uvalue, ct->lower_bound);
68  uvalue += ct->lower_bound;
69  if (uvalue > (uintmax_t)ct->upper_bound)
71  if(asn_umax2INTEGER(st, uvalue))
73  } else {
74  uintmax_t uvalue = 0;
75  intmax_t svalue;
77  &uvalue, ct->range_bits))
79  ASN_DEBUG("Got value %"ASN_PRIuMAX" + low %"ASN_PRIdMAX"",
80  uvalue, ct->lower_bound);
81  if(per_imax_range_unrebase(uvalue, ct->lower_bound,
82  ct->upper_bound, &svalue)
83  || asn_imax2INTEGER(st, svalue)) {
85  }
86  }
87  return rval;
88  }
89  } else {
90  ASN_DEBUG("Decoding unconstrained integer %s", td->name);
91  }
92 
93  /* X.691, #12.2.3, #12.2.4 */
94  do {
95  ssize_t len = 0;
96  void *p = NULL;
97  int ret = 0;
98 
99  /* Get the PER length */
100  len = uper_get_length(pd, -1, 0, &repeat);
101  if(len < 0) ASN__DECODE_STARVED;
102 
103  p = REALLOC(st->buf, st->size + len + 1);
104  if(!p) ASN__DECODE_FAILED;
105  st->buf = (uint8_t *)p;
106 
107  ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
108  if(ret < 0) ASN__DECODE_STARVED;
109  st->size += len;
110  } while(repeat);
111  st->buf[st->size] = 0; /* JIC */
112 
113  /* #12.2.3 */
114  if(ct && ct->lower_bound) {
115  /*
116  * TODO: replace by in-place arithmetic.
117  */
118  long value = 0;
119  if(asn_INTEGER2long(st, &value))
121  if(asn_imax2INTEGER(st, value + ct->lower_bound))
123  }
124 
125  return rval;
126 }
127 
130  const asn_per_constraints_t *constraints, const void *sptr,
131  asn_per_outp_t *po) {
132  const asn_INTEGER_specifics_t *specs =
133  (const asn_INTEGER_specifics_t *)td->specifics;
134  asn_enc_rval_t er = {0,0,0};
135  const INTEGER_t *st = (const INTEGER_t *)sptr;
136  const uint8_t *buf;
137  const uint8_t *end;
138  const asn_per_constraint_t *ct;
139  union {
140  intmax_t s;
141  uintmax_t u;
142  } value;
143 
144  if(!st || st->size == 0) ASN__ENCODE_FAILED;
145 
146  if(!constraints) constraints = td->encoding_constraints.per_constraints;
147  ct = constraints ? &constraints->value : 0;
148 
149  er.encoded = 0;
150 
151  if(ct) {
152  int inext = 0;
153  if(specs && specs->field_unsigned) {
154  if(asn_INTEGER2umax(st, &value.u))
156  /* Check proper range */
157  if(ct->flags & APC_SEMI_CONSTRAINED) {
158  if(value.u < (uintmax_t)ct->lower_bound)
159  inext = 1;
160  } else if(ct->range_bits >= 0) {
161  if(value.u < (uintmax_t)ct->lower_bound
162  || value.u > (uintmax_t)ct->upper_bound)
163  inext = 1;
164  }
165  ASN_DEBUG("Value %"ASN_PRIuMAX" (%02x/%" ASN_PRI_SIZE ") lb %"ASN_PRIuMAX" ub %"ASN_PRIuMAX" %s",
166  value.u, st->buf[0], st->size,
167  (uintmax_t)ct->lower_bound, (uintmax_t)ct->upper_bound,
168  inext ? "ext" : "fix");
169  } else {
170  if(asn_INTEGER2imax(st, &value.s))
172  /* Check proper range */
173  if(ct->flags & APC_SEMI_CONSTRAINED) {
174  if(value.s < ct->lower_bound)
175  inext = 1;
176  } else if(ct->range_bits >= 0) {
177  if(value.s < ct->lower_bound
178  || value.s > ct->upper_bound)
179  inext = 1;
180  }
181  ASN_DEBUG("Value %"ASN_PRIdMAX" (%02x/%" ASN_PRI_SIZE ") lb %"ASN_PRIdMAX" ub %"ASN_PRIdMAX" %s",
182  value.s, st->buf[0], st->size,
183  ct->lower_bound, ct->upper_bound,
184  inext ? "ext" : "fix");
185  }
186  if(ct->flags & APC_EXTENSIBLE) {
187  if(per_put_few_bits(po, inext, 1))
189  if(inext) ct = 0;
190  } else if(inext) {
192  }
193  }
194 
195  /* X.691-11/2008, #13.2.2, test if constrained whole number */
196  if(ct && ct->range_bits >= 0) {
197  uintmax_t v;
198  /* #11.5.6 -> #11.3 */
199  if(specs && specs->field_unsigned) {
200  if(((uintmax_t)ct->lower_bound > (uintmax_t)(ct->upper_bound)
201  || (value.u < (uintmax_t)ct->lower_bound))
202  || (value.u > (uintmax_t)ct->upper_bound)) {
203  ASN_DEBUG("Value %"ASN_PRIuMAX" to-be-encoded is outside the bounds [%"ASN_PRIuMAX", %"ASN_PRIuMAX"]!",
204  value.u, (uintmax_t)ct->lower_bound, (uintmax_t)ct->upper_bound);
206  }
207  v = value.u - (uintmax_t)ct->lower_bound;
208  } else {
209  if(per_imax_range_rebase(value.s, ct->lower_bound, ct->upper_bound, &v)) {
211  }
212  }
213  ASN_DEBUG("Encoding integer %"ASN_PRIuMAX" with range %d bits",
214  v, ct->range_bits);
217  ASN__ENCODED_OK(er);
218  }
219 
220  if(ct && ct->lower_bound) {
221  ASN_DEBUG("Adjust lower bound to %"ASN_PRIdMAX"", ct->lower_bound);
222  /* TODO: adjust lower bound */
224  }
225 
226  for(buf = st->buf, end = st->buf + st->size; buf < end;) {
227  int need_eom = 0;
228  ssize_t mayEncode = uper_put_length(po, end - buf, &need_eom);
229  if(mayEncode < 0)
231  if(per_put_many_bits(po, buf, 8 * mayEncode))
233  buf += mayEncode;
234  if(need_eom && uper_put_length(po, 0, 0)) ASN__ENCODE_FAILED;
235  }
236 
237  ASN__ENCODED_OK(er);
238 }
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_encode_uper
asn_enc_rval_t INTEGER_encode_uper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: INTEGER_uper.c:129
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
per_imax_range_rebase
int per_imax_range_rebase(intmax_t v, intmax_t lb, intmax_t ub, uintmax_t *output)
Definition: uper_support.c:235
asn_enc_rval_s
Definition: asn_codecs.h:41
asn_per_constraint_s::lower_bound
intmax_t lower_bound
Definition: per_support.h:27
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
uper_get_constrained_whole_number
int uper_get_constrained_whole_number(asn_per_data_t *pd, uintmax_t *v, int nbits)
Definition: uper_support.c:124
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
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
per_imax_range_unrebase
int per_imax_range_unrebase(uintmax_t inp, intmax_t lb, intmax_t ub, intmax_t *outp)
Definition: uper_support.c:280
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
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
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
uper_put_constrained_whole_number_u
int uper_put_constrained_whole_number_u(asn_per_outp_t *po, uintmax_t v, int nbits)
Definition: uper_support.c:151
asn_per_constraint_s::range_bits
int range_bits
Definition: per_support.h:25
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
ASN_PRIuMAX
#define ASN_PRIuMAX
Definition: asn_system.h:180
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
INTEGER_decode_uper
asn_dec_rval_t INTEGER_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: INTEGER_uper.c:10
per_put_few_bits
#define per_put_few_bits(out, bits, obits)
Definition: per_support.h:46


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