BIT_STRING_rfill.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 
11  const asn_encoding_constraints_t *constraints,
12  size_t max_length) {
13  const asn_OCTET_STRING_specifics_t *specs =
16  asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
17  asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
18  asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
19  static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
20  126, 127, 128, 16383, 16384, 16385,
21  65534, 65535, 65536, 65537};
22  uint8_t *buf;
23  uint8_t *bend;
24  uint8_t *b;
25  size_t rnd_bits, rnd_len;
26  BIT_STRING_t *st;
27 
28  if(max_length == 0) return result_skipped;
29 
30  switch(specs->subvariant) {
31  case ASN_OSUBV_ANY:
32  return result_failed;
33  case ASN_OSUBV_BIT:
34  break;
35  default:
36  break;
37  }
38 
39  /* Figure out how far we should go */
40  rnd_bits = lengths[asn_random_between(
41  0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
42 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
43  if(!constraints || !constraints->per_constraints)
44  constraints = &td->encoding_constraints;
45  if(constraints->per_constraints) {
46  const asn_per_constraint_t *pc = &constraints->per_constraints->size;
47  if(pc->flags & APC_CONSTRAINED) {
48  long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
49  ? pc->upper_bound
50  : (ssize_t)max_length;
51  if(max_length < (size_t)pc->lower_bound) {
52  return result_skipped;
53  }
54  if(pc->flags & APC_EXTENSIBLE) {
55  switch(asn_random_between(0, 5)) {
56  case 0:
57  if(pc->lower_bound > 0) {
58  rnd_bits = pc->lower_bound - 1;
59  break;
60  }
61  /* Fall through */
62  case 1:
63  rnd_bits = pc->upper_bound + 1;
64  break;
65  case 2:
66  /* Keep rnd_bits from the table */
67  if(rnd_bits < max_length) {
68  break;
69  }
70  /* Fall through */
71  default:
72  rnd_bits = asn_random_between(pc->lower_bound,
73  suggested_upper_bound);
74  }
75  } else {
76  rnd_bits =
77  asn_random_between(pc->lower_bound, suggested_upper_bound);
78  }
79  } else {
80  rnd_bits = asn_random_between(0, max_length - 1);
81  }
82  } else {
83 #else
84  if(!constraints) constraints = &td->encoding_constraints;
85  {
86 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
87  if(rnd_bits >= max_length) {
88  rnd_bits = asn_random_between(0, max_length - 1);
89  }
90  }
91 
92  rnd_len = (rnd_bits + 7) / 8;
93  buf = CALLOC(1, rnd_len + 1);
94  if(!buf) return result_failed;
95 
96  bend = &buf[rnd_len];
97 
98  for(b = buf; b < bend; b++) {
99  *(uint8_t *)b = asn_random_between(0, 255);
100  }
101  *b = 0; /* Zero-terminate just in case. */
102 
103  if(*sptr) {
104  st = *sptr;
105  FREEMEM(st->buf);
106  } else {
107  st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
108  if(!st) {
109  FREEMEM(buf);
110  return result_failed;
111  }
112  }
113 
114  st->buf = buf;
115  st->size = rnd_len;
116  st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;
117  if(st->bits_unused) {
118  assert(st->size > 0);
119  st->buf[st->size-1] &= 0xff << st->bits_unused;
120  }
121 
122  result_ok.length = st->size;
123  return result_ok;
124 }
BIT_STRING_s::buf
uint8_t * buf
Definition: BIT_STRING.h:15
BIT_STRING_s::size
size_t size
Definition: BIT_STRING.h:16
asn_per_constraint_s::lower_bound
intmax_t lower_bound
Definition: per_support.h:27
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
asn_per_constraint_s
Definition: per_support.h:18
BIT_STRING_random_fill
asn_random_fill_result_t BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, const asn_encoding_constraints_t *constraints, size_t max_length)
Definition: BIT_STRING_rfill.c:10
BIT_STRING_s
Definition: BIT_STRING.h:14
asn_OCTET_STRING_specifics_s
Definition: OCTET_STRING.h:125
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
asn_random_fill_result_s
Definition: asn_random_fill.h:24
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
asn_random_between
intmax_t asn_random_between(intmax_t min, intmax_t max)
Definition: asn_random_fill.c:38
asn_SPC_BIT_STRING_specs
asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs
Definition: BIT_STRING.c:14
asn_encoding_constraints_s
Definition: constr_TYPE.h:208
asn_internal.h
BIT_STRING.h
BIT_STRING_s::bits_unused
int bits_unused
Definition: BIT_STRING.h:18
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


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