BIT_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 
9 #undef RETURN
10 #define RETURN(_code) \
11  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_SEMI_CONSTRAINED, -1, -1, 0, 0};
20 
23  const asn_TYPE_descriptor_t *td,
24  const asn_per_constraints_t *constraints, void **sptr,
25  asn_per_data_t *pd) {
26  const asn_OCTET_STRING_specifics_t *specs = td->specifics
29  const asn_per_constraints_t *pc =
30  constraints ? constraints : td->encoding_constraints.per_constraints;
31  const asn_per_constraint_t *csiz;
32  asn_dec_rval_t rval = { RC_OK, 0 };
33  BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
34  ssize_t consumed_myself = 0;
35  int repeat;
36 
37  (void)opt_codec_ctx;
38 
39  if(pc) {
40  csiz = &pc->size;
41  } else {
43  }
44 
45  if(specs->subvariant != ASN_OSUBV_BIT) {
46  ASN_DEBUG("Subvariant %d is not BIT OSUBV_BIT", specs->subvariant);
47  RETURN(RC_FAIL);
48  }
49 
50  /*
51  * Allocate the string.
52  */
53  if(!st) {
54  st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
55  if(!st) RETURN(RC_FAIL);
56  }
57 
58  ASN_DEBUG("PER Decoding %s size %"ASN_PRIdMAX" .. %"ASN_PRIdMAX" bits %d",
59  csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
60  csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
61 
62  if(csiz->flags & APC_EXTENSIBLE) {
63  int inext = per_get_few_bits(pd, 1);
64  if(inext < 0) RETURN(RC_WMORE);
65  if(inext) {
67  }
68  }
69 
70  if(csiz->effective_bits >= 0) {
71  FREEMEM(st->buf);
72  st->size = (csiz->upper_bound + 7) >> 3;
73  st->buf = (uint8_t *)MALLOC(st->size + 1);
74  if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
75  }
76 
77  /* X.691, #16.5: zero-length encoding */
78  /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
79  /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
80  if(csiz->effective_bits == 0) {
81  int ret;
82  ASN_DEBUG("Encoding BIT STRING size %"ASN_PRIdMAX"", csiz->upper_bound);
83  ret = per_get_many_bits(pd, st->buf, 0, csiz->upper_bound);
84  if(ret < 0) RETURN(RC_WMORE);
85  consumed_myself += csiz->upper_bound;
86  st->buf[st->size] = 0;
87  st->bits_unused = (8 - (csiz->upper_bound & 0x7)) & 0x7;
88  RETURN(RC_OK);
89  }
90 
91  st->size = 0;
92  do {
93  ssize_t raw_len;
94  ssize_t len_bytes;
95  ssize_t len_bits;
96  void *p;
97  int ret;
98 
99  /* Get the PER length */
100  raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound,
101  &repeat);
102  if(raw_len < 0) RETURN(RC_WMORE);
103  if(raw_len == 0 && st->buf) break;
104  /* Check upper bound for Constrained Length */
105  if (csiz->effective_bits >= 0 && csiz->effective_bits <= 16 && raw_len > csiz->upper_bound && !(csiz->flags & APC_EXTENSIBLE)) {
107  }
108 
109  ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
110  (long)csiz->effective_bits, (long)raw_len,
111  repeat ? "repeat" : "once", td->name);
112  len_bits = raw_len;
113  len_bytes = (len_bits + 7) >> 3;
114  if(len_bits & 0x7) st->bits_unused = 8 - (len_bits & 0x7);
115  /* len_bits be multiple of 16K if repeat is set */
116  p = REALLOC(st->buf, st->size + len_bytes + 1);
117  if(!p) RETURN(RC_FAIL);
118  st->buf = (uint8_t *)p;
119 
120  ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
121  if(ret < 0) RETURN(RC_WMORE);
122  st->size += len_bytes;
123  } while(repeat);
124  st->buf[st->size] = 0; /* nul-terminate */
125 
126  return rval;
127 }
128 
131  const asn_per_constraints_t *constraints,
132  const void *sptr, asn_per_outp_t *po) {
133  const asn_OCTET_STRING_specifics_t *specs =
136  const asn_per_constraints_t *pc =
137  constraints ? constraints : td->encoding_constraints.per_constraints;
138  const asn_per_constraint_t *csiz;
139  const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
140 #if defined(UPER_REMOVE_TRAILING_BITS)
141  BIT_STRING_t compact_bstr; /* Do not modify this directly! */
142 #endif
143  asn_enc_rval_t er = { 0, 0, 0 };
144  int inext = 0; /* Lies not within extension root */
145  size_t size_in_bits;
146  const uint8_t *buf;
147  int ret;
148  int ct_extensible;
149 
150  if(!st || (!st->buf && st->size))
152 
153  if(specs->subvariant == ASN_OSUBV_BIT) {
154  if((st->size == 0 && st->bits_unused) || (st->bits_unused & ~7))
156  } else {
158  }
159 
160  if(pc) {
161  csiz = &pc->size;
162  } else {
164  }
165  ct_extensible = csiz->flags & APC_EXTENSIBLE;
166 
167 #if defined(UPER_REMOVE_TRAILING_BITS)
168  /* Figure out the size without the trailing bits */
169  st = BIT_STRING__compactify(st, &compact_bstr);
170  /*
171  * Reason for disabling the above truncation:
172  * trailing bits in a bit-string usually
173  * are meaningful, as "0000" is not the same as "000000".
174  */
175 #endif /* UPER_REMOVE_TRAILING_BITS */
176  size_in_bits = 8 * st->size - st->bits_unused;
177 
178  ASN_DEBUG(
179  "Encoding %s into %" ASN_PRI_SIZE " bits"
180  " (%"ASN_PRIdMAX"..%"ASN_PRIdMAX", effective %d)%s",
181  td->name, size_in_bits, csiz->lower_bound, csiz->upper_bound,
182  csiz->effective_bits, ct_extensible ? " EXT" : "");
183 
184  /* Figure out whether size lies within PER visible constraint */
185 
186  if(csiz->effective_bits >= 0) {
187  if((ssize_t)size_in_bits > csiz->upper_bound) {
188  if(ct_extensible) {
190  inext = 1;
191  } else {
193  }
194  }
195  } else {
196  inext = 0;
197  }
198 
199  if(ct_extensible) {
200  /* Declare whether length is [not] within extension root */
201  if(per_put_few_bits(po, inext, 1))
203  }
204 
205  if(csiz->effective_bits >= 0 && !inext) {
206  int add_trailer = (ssize_t)size_in_bits < csiz->lower_bound;
207  ASN_DEBUG(
208  "Encoding %" ASN_PRI_SIZE " bytes (%"ASN_PRIdMAX"), length (in %d bits) trailer %d; actual "
209  "value %" ASN_PRI_SSIZE "",
210  st->size, size_in_bits - csiz->lower_bound, csiz->effective_bits,
211  add_trailer,
212  add_trailer ? 0 : (ssize_t)size_in_bits - (ssize_t)csiz->lower_bound);
213  ret = per_put_few_bits(
214  po, add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound,
215  csiz->effective_bits);
216  if(ret) ASN__ENCODE_FAILED;
217  ret = per_put_many_bits(po, st->buf, size_in_bits);
218  if(ret) ASN__ENCODE_FAILED;
219  if(add_trailer) {
220  static const uint8_t zeros[16];
221  size_t trailing_zero_bits = csiz->lower_bound - size_in_bits;
222  while(trailing_zero_bits > 0) {
223  if(trailing_zero_bits > 8 * sizeof(zeros)) {
224  ret = per_put_many_bits(po, zeros, 8 * sizeof(zeros));
225  trailing_zero_bits -= 8 * sizeof(zeros);
226  } else {
227  ret = per_put_many_bits(po, zeros, trailing_zero_bits);
228  trailing_zero_bits = 0;
229  }
230  if(ret) ASN__ENCODE_FAILED;
231  }
232  }
233  ASN__ENCODED_OK(er);
234  }
235 
236  ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size);
237 
238  buf = st->buf;
239  do {
240  int need_eom = 0;
241  ssize_t maySave = uper_put_length(po, size_in_bits, &need_eom);
242  if(maySave < 0) ASN__ENCODE_FAILED;
243 
244  ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "", maySave, size_in_bits);
245 
246  ret = per_put_many_bits(po, buf, maySave);
247  if(ret) ASN__ENCODE_FAILED;
248 
249  buf += maySave >> 3;
250  size_in_bits -= maySave;
251  assert(!(maySave & 0x07) || !size_in_bits);
252  if(need_eom && uper_put_length(po, 0, 0))
253  ASN__ENCODE_FAILED; /* End of Message length */
254  } while(size_in_bits);
255 
256  ASN__ENCODED_OK(er);
257 }
asn_bit_outp_s
Definition: asn_bit_data.h:56
ASN_PRIdMAX
#define ASN_PRIdMAX
Definition: asn_system.h:181
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
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
RETURN
#define RETURN(_code)
Definition: BIT_STRING_uper.c:10
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
BIT_STRING_encode_uper
asn_enc_rval_t BIT_STRING_encode_uper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: BIT_STRING_uper.c:130
BIT_STRING_s
Definition: BIT_STRING.h:14
asn_OCTET_STRING_specifics_s
Definition: OCTET_STRING.h:125
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
asn_SPC_BIT_STRING_specs
asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs
Definition: BIT_STRING.c:14
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
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
ASN_PRI_SSIZE
#define ASN_PRI_SSIZE
Definition: asn_system.h:173
asn_internal.h
BIT_STRING__compactify
const BIT_STRING_t * BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp)
Definition: BIT_STRING.c:133
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_DEF_BIT_STRING_constraint_size
static asn_per_constraint_t asn_DEF_BIT_STRING_constraint_size
Definition: BIT_STRING_uper.c:18
BIT_STRING_decode_uper
asn_dec_rval_t BIT_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: BIT_STRING_uper.c:22
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
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
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_cam_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:21:22