Updated INFO.yaml file
[ric-app/kpimon.git] / asn1c_defs / all-defs / BIT_STRING.c
1 /*-\r
2  * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.\r
3  * Redistribution and modifications are permitted subject to BSD license.\r
4  */\r
5 #include <asn_internal.h>\r
6 #include <BIT_STRING.h>\r
7 #include <asn_internal.h>\r
8 \r
9 /*\r
10  * BIT STRING basic type description.\r
11  */\r
12 static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {\r
13         (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))\r
14 };\r
15 asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = {\r
16         sizeof(BIT_STRING_t),\r
17         offsetof(BIT_STRING_t, _asn_ctx),\r
18         ASN_OSUBV_BIT\r
19 };\r
20 asn_TYPE_operation_t asn_OP_BIT_STRING = {\r
21         OCTET_STRING_free,         /* Implemented in terms of OCTET STRING */\r
22         BIT_STRING_print,\r
23         BIT_STRING_compare,\r
24         OCTET_STRING_decode_ber,   /* Implemented in terms of OCTET STRING */\r
25         OCTET_STRING_encode_der,   /* Implemented in terms of OCTET STRING */\r
26         OCTET_STRING_decode_xer_binary,\r
27         BIT_STRING_encode_xer,\r
28 #ifdef  ASN_DISABLE_OER_SUPPORT\r
29         0,\r
30         0,\r
31 #else\r
32         BIT_STRING_decode_oer,\r
33         BIT_STRING_encode_oer,\r
34 #endif  /* ASN_DISABLE_OER_SUPPORT */\r
35 #ifdef  ASN_DISABLE_PER_SUPPORT\r
36         0,\r
37         0,\r
38         0,\r
39         0,\r
40 #else\r
41         BIT_STRING_decode_uper, /* Unaligned PER decoder */\r
42         BIT_STRING_encode_uper, /* Unaligned PER encoder */\r
43         OCTET_STRING_decode_aper,       /* Aligned PER decoder */\r
44         OCTET_STRING_encode_aper,       /* Aligned PER encoder */\r
45 #endif  /* ASN_DISABLE_PER_SUPPORT */\r
46         BIT_STRING_random_fill,\r
47         0       /* Use generic outmost tag fetcher */\r
48 };\r
49 asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {\r
50         "BIT STRING",\r
51         "BIT_STRING",\r
52         &asn_OP_BIT_STRING,\r
53         asn_DEF_BIT_STRING_tags,\r
54         sizeof(asn_DEF_BIT_STRING_tags)\r
55           / sizeof(asn_DEF_BIT_STRING_tags[0]),\r
56         asn_DEF_BIT_STRING_tags,        /* Same as above */\r
57         sizeof(asn_DEF_BIT_STRING_tags)\r
58           / sizeof(asn_DEF_BIT_STRING_tags[0]),\r
59         { 0, 0, BIT_STRING_constraint },\r
60         0, 0,   /* No members */\r
61         &asn_SPC_BIT_STRING_specs\r
62 };\r
63 \r
64 /*\r
65  * BIT STRING generic constraint.\r
66  */\r
67 int\r
68 BIT_STRING_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,\r
69                       asn_app_constraint_failed_f *ctfailcb, void *app_key) {\r
70     const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;\r
71 \r
72         if(st && st->buf) {\r
73                 if((st->size == 0 && st->bits_unused)\r
74                 || st->bits_unused < 0 || st->bits_unused > 7) {\r
75                         ASN__CTFAIL(app_key, td, sptr,\r
76                                 "%s: invalid padding byte (%s:%d)",\r
77                                 td->name, __FILE__, __LINE__);\r
78                         return -1;\r
79                 }\r
80         } else {\r
81                 ASN__CTFAIL(app_key, td, sptr,\r
82                         "%s: value not given (%s:%d)",\r
83                         td->name, __FILE__, __LINE__);\r
84                 return -1;\r
85         }\r
86 \r
87         return 0;\r
88 }\r
89 \r
90 static const char *_bit_pattern[16] = {\r
91         "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",\r
92         "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"\r
93 };\r
94 \r
95 asn_enc_rval_t\r
96 BIT_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,\r
97                       int ilevel, enum xer_encoder_flags_e flags,\r
98                       asn_app_consume_bytes_f *cb, void *app_key) {\r
99         asn_enc_rval_t er = {0, 0, 0};\r
100         char scratch[128];\r
101         char *p = scratch;\r
102         char *scend = scratch + (sizeof(scratch) - 10);\r
103         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;\r
104         int xcan = (flags & XER_F_CANONICAL);\r
105         uint8_t *buf;\r
106         uint8_t *end;\r
107 \r
108         if(!st || !st->buf)\r
109                 ASN__ENCODE_FAILED;\r
110 \r
111         er.encoded = 0;\r
112 \r
113         buf = st->buf;\r
114         end = buf + st->size - 1;       /* Last byte is special */\r
115 \r
116         /*\r
117          * Binary dump\r
118          */\r
119         for(; buf < end; buf++) {\r
120                 int v = *buf;\r
121                 int nline = xcan?0:(((buf - st->buf) % 8) == 0);\r
122                 if(p >= scend || nline) {\r
123                         ASN__CALLBACK(scratch, p - scratch);\r
124                         p = scratch;\r
125                         if(nline) ASN__TEXT_INDENT(1, ilevel);\r
126                 }\r
127                 memcpy(p + 0, _bit_pattern[v >> 4], 4);\r
128                 memcpy(p + 4, _bit_pattern[v & 0x0f], 4);\r
129                 p += 8;\r
130         }\r
131 \r
132         if(!xcan && ((buf - st->buf) % 8) == 0)\r
133                 ASN__TEXT_INDENT(1, ilevel);\r
134         ASN__CALLBACK(scratch, p - scratch);\r
135         p = scratch;\r
136 \r
137         if(buf == end) {\r
138                 int v = *buf;\r
139                 int ubits = st->bits_unused;\r
140                 int i;\r
141                 for(i = 7; i >= ubits; i--)\r
142                         *p++ = (v & (1 << i)) ? 0x31 : 0x30;\r
143                 ASN__CALLBACK(scratch, p - scratch);\r
144         }\r
145 \r
146         if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);\r
147 \r
148         ASN__ENCODED_OK(er);\r
149 cb_failed:\r
150         ASN__ENCODE_FAILED;\r
151 }\r
152 \r
153 \r
154 /*\r
155  * BIT STRING specific contents printer.\r
156  */\r
157 int\r
158 BIT_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,\r
159                  asn_app_consume_bytes_f *cb, void *app_key) {\r
160     const char * const h2c = "0123456789ABCDEF";\r
161         char scratch[64];\r
162         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;\r
163         uint8_t *buf;\r
164         uint8_t *end;\r
165         char *p = scratch;\r
166 \r
167         (void)td;       /* Unused argument */\r
168 \r
169         if(!st || !st->buf)\r
170                 return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;\r
171 \r
172         ilevel++;\r
173         buf = st->buf;\r
174         end = buf + st->size;\r
175 \r
176         /*\r
177          * Hexadecimal dump.\r
178          */\r
179         for(; buf < end; buf++) {\r
180                 if((buf - st->buf) % 16 == 0 && (st->size > 16)\r
181                                 && buf != st->buf) {\r
182                         _i_INDENT(1);\r
183                         /* Dump the string */\r
184                         if(cb(scratch, p - scratch, app_key) < 0) return -1;\r
185                         p = scratch;\r
186                 }\r
187                 *p++ = h2c[*buf >> 4];\r
188                 *p++ = h2c[*buf & 0x0F];\r
189                 *p++ = 0x20;\r
190         }\r
191 \r
192         if(p > scratch) {\r
193                 p--;    /* Eat the tailing space */\r
194 \r
195                 if((st->size > 16)) {\r
196                         _i_INDENT(1);\r
197                 }\r
198 \r
199                 /* Dump the incomplete 16-bytes row */\r
200                 if(cb(scratch, p - scratch, app_key) < 0)\r
201                         return -1;\r
202         }\r
203 \r
204     if(st->bits_unused) {\r
205         int ret = snprintf(scratch, sizeof(scratch), " (%d bit%s unused)",\r
206                            st->bits_unused, st->bits_unused == 1 ? "" : "s");\r
207         assert(ret > 0 && ret < (ssize_t)sizeof(scratch));\r
208         if(ret > 0 && ret < (ssize_t)sizeof(scratch)\r
209            && cb(scratch, ret, app_key) < 0)\r
210             return -1;\r
211     }\r
212 \r
213         return 0;\r
214 }\r
215 \r
216 /*\r
217  * Non-destructively remove the trailing 0-bits from the given bit string.\r
218  */\r
219 static const BIT_STRING_t *\r
220 BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp) {\r
221     const uint8_t *b;\r
222     union {\r
223         const uint8_t *c_buf;\r
224         uint8_t *nc_buf;\r
225     } unconst;\r
226 \r
227     if(st->size == 0) {\r
228         assert(st->bits_unused == 0);\r
229         return st;\r
230     } else {\r
231         for(b = &st->buf[st->size - 1]; b > st->buf && *b == 0; b--) {\r
232             ;\r
233         }\r
234         /* b points to the last byte which may contain data */\r
235         if(*b) {\r
236             int unused = 7;\r
237             uint8_t v = *b;\r
238             v &= -(int8_t)v;\r
239             if(v & 0x0F) unused -= 4;\r
240             if(v & 0x33) unused -= 2;\r
241             if(v & 0x55) unused -= 1;\r
242             tmp->size = b-st->buf + 1;\r
243             tmp->bits_unused = unused;\r
244         } else {\r
245             tmp->size = b-st->buf;\r
246             tmp->bits_unused = 0;\r
247         }\r
248 \r
249         assert(b >= st->buf);\r
250     }\r
251 \r
252     unconst.c_buf = st->buf;\r
253     tmp->buf = unconst.nc_buf;\r
254     return tmp;\r
255 }\r
256 \r
257 /*\r
258  * Lexicographically compare the common prefix of both strings,\r
259  * and if it is the same return -1 for the smallest string.\r
260  */\r
261 int\r
262 BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,\r
263                    const void *bptr) {\r
264     /*\r
265      * Remove information about trailing bits, since\r
266      * X.680 (08/2015) #22.7 "ensure that different semantics are not"\r
267      * "associated with [values that differ only in] the trailing 0 bits."\r
268      */\r
269     BIT_STRING_t compact_a, compact_b;\r
270     const BIT_STRING_t *a = BIT_STRING__compactify(aptr, &compact_a);\r
271     const BIT_STRING_t *b = BIT_STRING__compactify(bptr, &compact_b);\r
272     const asn_OCTET_STRING_specifics_t *specs = td->specifics;\r
273 \r
274     assert(specs && specs->subvariant == ASN_OSUBV_BIT);\r
275 \r
276     if(a && b) {\r
277         size_t common_prefix_size = a->size <= b->size ? a->size : b->size;\r
278         int ret = memcmp(a->buf, b->buf, common_prefix_size);\r
279         if(ret == 0) {\r
280             /* Figure out which string with equal prefixes is longer. */\r
281             if(a->size < b->size) {\r
282                 return -1;\r
283             } else if(a->size > b->size) {\r
284                 return 1;\r
285             } else {\r
286                 /* Figure out how many unused bits */\r
287                 if(a->bits_unused > b->bits_unused) {\r
288                     return -1;\r
289                 } else if(a->bits_unused < b->bits_unused) {\r
290                     return 1;\r
291                 } else {\r
292                     return 0;\r
293                 }\r
294             }\r
295         } else {\r
296             return ret;\r
297         }\r
298     } else if(!a && !b) {\r
299         return 0;\r
300     } else if(!a) {\r
301         return -1;\r
302     } else {\r
303         return 1;\r
304     }\r
305 }\r
306 \r
307 #ifndef  ASN_DISABLE_PER_SUPPORT\r
308 \r
309 #undef  RETURN\r
310 #define RETURN(_code)                       \\r
311     do {                                    \\r
312         asn_dec_rval_t tmprval;             \\r
313         tmprval.code = _code;               \\r
314         tmprval.consumed = consumed_myself; \\r
315         return tmprval;                     \\r
316     } while(0)\r
317 \r
318 static asn_per_constraint_t asn_DEF_BIT_STRING_constraint_size = {\r
319     APC_SEMI_CONSTRAINED, -1, -1, 0, 0};\r
320 \r
321 asn_dec_rval_t\r
322 BIT_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,\r
323                        const asn_TYPE_descriptor_t *td,\r
324                        const asn_per_constraints_t *constraints, void **sptr,\r
325                        asn_per_data_t *pd) {\r
326     const asn_OCTET_STRING_specifics_t *specs = td->specifics\r
327                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics\r
328                 : &asn_SPC_BIT_STRING_specs;\r
329     const asn_per_constraints_t *pc =\r
330         constraints ? constraints : td->encoding_constraints.per_constraints;\r
331         const asn_per_constraint_t *csiz;\r
332         asn_dec_rval_t rval = { RC_OK, 0 };\r
333         BIT_STRING_t *st = (BIT_STRING_t *)*sptr;\r
334         ssize_t consumed_myself = 0;\r
335         int repeat;\r
336 \r
337         (void)opt_codec_ctx;\r
338 \r
339         if(pc) {\r
340                 csiz = &pc->size;\r
341         } else {\r
342                 csiz = &asn_DEF_BIT_STRING_constraint_size;\r
343         }\r
344 \r
345         if(specs->subvariant != ASN_OSUBV_BIT) {\r
346                 ASN_DEBUG("Subvariant %d is not BIT OSUBV_BIT", specs->subvariant);\r
347                 RETURN(RC_FAIL);\r
348     }\r
349 \r
350         /*\r
351          * Allocate the string.\r
352          */\r
353         if(!st) {\r
354                 st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));\r
355                 if(!st) RETURN(RC_FAIL);\r
356         }\r
357 \r
358         ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",\r
359                 csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",\r
360                 csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);\r
361 \r
362         if(csiz->flags & APC_EXTENSIBLE) {\r
363                 int inext = per_get_few_bits(pd, 1);\r
364                 if(inext < 0) RETURN(RC_WMORE);\r
365                 if(inext) {\r
366                         csiz = &asn_DEF_BIT_STRING_constraint_size;\r
367                 }\r
368         }\r
369 \r
370         if(csiz->effective_bits >= 0) {\r
371                 FREEMEM(st->buf);\r
372         st->size = (csiz->upper_bound + 7) >> 3;\r
373         st->buf = (uint8_t *)MALLOC(st->size + 1);\r
374                 if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }\r
375         }\r
376 \r
377         /* X.691, #16.5: zero-length encoding */\r
378         /* X.691, #16.6: short fixed length encoding (up to 2 octets) */\r
379         /* X.691, #16.7: long fixed length encoding (up to 64K octets) */\r
380         if(csiz->effective_bits == 0) {\r
381                 int ret;\r
382         ASN_DEBUG("Encoding BIT STRING size %ld", csiz->upper_bound);\r
383         ret = per_get_many_bits(pd, st->buf, 0, csiz->upper_bound);\r
384                 if(ret < 0) RETURN(RC_WMORE);\r
385                 consumed_myself += csiz->upper_bound;\r
386                 st->buf[st->size] = 0;\r
387         st->bits_unused = (8 - (csiz->upper_bound & 0x7)) & 0x7;\r
388         RETURN(RC_OK);\r
389         }\r
390 \r
391         st->size = 0;\r
392         do {\r
393                 ssize_t raw_len;\r
394                 ssize_t len_bytes;\r
395                 ssize_t len_bits;\r
396                 void *p;\r
397                 int ret;\r
398 \r
399                 /* Get the PER length */\r
400                 raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound,\r
401                                           &repeat);\r
402                 if(raw_len < 0) RETURN(RC_WMORE);\r
403         if(raw_len == 0 && st->buf) break;\r
404 \r
405                 ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",\r
406                         (long)csiz->effective_bits, (long)raw_len,\r
407                         repeat ? "repeat" : "once", td->name);\r
408         len_bits = raw_len;\r
409         len_bytes = (len_bits + 7) >> 3;\r
410         if(len_bits & 0x7) st->bits_unused = 8 - (len_bits & 0x7);\r
411         /* len_bits be multiple of 16K if repeat is set */\r
412         p = REALLOC(st->buf, st->size + len_bytes + 1);\r
413                 if(!p) RETURN(RC_FAIL);\r
414                 st->buf = (uint8_t *)p;\r
415 \r
416         ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);\r
417         if(ret < 0) RETURN(RC_WMORE);\r
418                 st->size += len_bytes;\r
419         } while(repeat);\r
420         st->buf[st->size] = 0;  /* nul-terminate */\r
421 \r
422         return rval;\r
423 }\r
424 \r
425 asn_enc_rval_t\r
426 BIT_STRING_encode_uper(const asn_TYPE_descriptor_t *td,\r
427                        const asn_per_constraints_t *constraints,\r
428                        const void *sptr, asn_per_outp_t *po) {\r
429     const asn_OCTET_STRING_specifics_t *specs =\r
430         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics\r
431                       : &asn_SPC_BIT_STRING_specs;\r
432     const asn_per_constraints_t *pc =\r
433         constraints ? constraints : td->encoding_constraints.per_constraints;\r
434         const asn_per_constraint_t *csiz;\r
435         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;\r
436         BIT_STRING_t compact_bstr;  /* Do not modify this directly! */\r
437         asn_enc_rval_t er = { 0, 0, 0 };\r
438         int inext = 0;          /* Lies not within extension root */\r
439         size_t size_in_bits;\r
440         const uint8_t *buf;\r
441         int ret;\r
442         int ct_extensible;\r
443 \r
444         if(!st || (!st->buf && st->size))\r
445                 ASN__ENCODE_FAILED;\r
446 \r
447         if(specs->subvariant == ASN_OSUBV_BIT) {\r
448         if((st->size == 0 && st->bits_unused) || (st->bits_unused & ~7))\r
449             ASN__ENCODE_FAILED;\r
450     } else {\r
451                 ASN__ENCODE_FAILED;\r
452     }\r
453 \r
454         if(pc) {\r
455         csiz = &pc->size;\r
456     } else {\r
457                 csiz = &asn_DEF_BIT_STRING_constraint_size;\r
458         }\r
459         ct_extensible = csiz->flags & APC_EXTENSIBLE;\r
460 \r
461     /* Figure out the size without the trailing bits */\r
462     st = BIT_STRING__compactify(st, &compact_bstr);\r
463     size_in_bits = 8 * st->size - st->bits_unused;\r
464 \r
465     ASN_DEBUG(\r
466         "Encoding %s into %" ASN_PRI_SIZE " bits"\r
467         " (%ld..%ld, effective %d)%s",\r
468         td->name, size_in_bits, csiz->lower_bound, csiz->upper_bound,\r
469         csiz->effective_bits, ct_extensible ? " EXT" : "");\r
470 \r
471     /* Figure out whether size lies within PER visible constraint */\r
472 \r
473     if(csiz->effective_bits >= 0) {\r
474         if((ssize_t)size_in_bits > csiz->upper_bound) {\r
475             if(ct_extensible) {\r
476                 csiz = &asn_DEF_BIT_STRING_constraint_size;\r
477                 inext = 1;\r
478             } else {\r
479                 ASN__ENCODE_FAILED;\r
480             }\r
481         }\r
482     } else {\r
483         inext = 0;\r
484     }\r
485 \r
486     if(ct_extensible) {\r
487                 /* Declare whether length is [not] within extension root */\r
488                 if(per_put_few_bits(po, inext, 1))\r
489                         ASN__ENCODE_FAILED;\r
490         }\r
491 \r
492     if(csiz->effective_bits >= 0 && !inext) {\r
493         int add_trailer = (ssize_t)size_in_bits < csiz->lower_bound;\r
494         ASN_DEBUG(\r
495             "Encoding %" ASN_PRI_SIZE " bytes (%ld), length (in %d bits) trailer %d; actual "\r
496             "value %" ASN_PRI_SSIZE "",\r
497             st->size, size_in_bits - csiz->lower_bound, csiz->effective_bits,\r
498             add_trailer,\r
499             add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound);\r
500         ret = per_put_few_bits(\r
501             po, add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound,\r
502             csiz->effective_bits);\r
503         if(ret) ASN__ENCODE_FAILED;\r
504         ret = per_put_many_bits(po, st->buf, size_in_bits);\r
505         if(ret) ASN__ENCODE_FAILED;\r
506         if(add_trailer) {\r
507             static const uint8_t zeros[16];\r
508             size_t trailing_zero_bits = csiz->lower_bound - size_in_bits;\r
509             while(trailing_zero_bits > 0) {\r
510                 if(trailing_zero_bits > 8 * sizeof(zeros)) {\r
511                     ret = per_put_many_bits(po, zeros, 8 * sizeof(zeros));\r
512                     trailing_zero_bits -= 8 * sizeof(zeros);\r
513                 } else {\r
514                     ret = per_put_many_bits(po, zeros, trailing_zero_bits);\r
515                     trailing_zero_bits = 0;\r
516                 }\r
517                 if(ret) ASN__ENCODE_FAILED;\r
518             }\r
519         }\r
520         ASN__ENCODED_OK(er);\r
521     }\r
522 \r
523     ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size);\r
524 \r
525     buf = st->buf;\r
526     do {\r
527         int need_eom = 0;\r
528         ssize_t maySave = uper_put_length(po, size_in_bits, &need_eom);\r
529         if(maySave < 0) ASN__ENCODE_FAILED;\r
530 \r
531         ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "", maySave, size_in_bits);\r
532 \r
533         ret = per_put_many_bits(po, buf, maySave);\r
534         if(ret) ASN__ENCODE_FAILED;\r
535 \r
536         buf += maySave >> 3;\r
537         size_in_bits -= maySave;\r
538         assert(!(maySave & 0x07) || !size_in_bits);\r
539         if(need_eom && uper_put_length(po, 0, 0))\r
540             ASN__ENCODE_FAILED; /* End of Message length */\r
541     } while(size_in_bits);\r
542 \r
543     ASN__ENCODED_OK(er);\r
544 }\r
545 \r
546 #endif  /* ASN_DISABLE_PER_SUPPORT */\r
547 \r
548 asn_random_fill_result_t\r
549 BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,\r
550                        const asn_encoding_constraints_t *constraints,\r
551                        size_t max_length) {\r
552     const asn_OCTET_STRING_specifics_t *specs =\r
553         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics\r
554                       : &asn_SPC_BIT_STRING_specs;\r
555     asn_random_fill_result_t result_ok = {ARFILL_OK, 1};\r
556     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};\r
557     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};\r
558     static unsigned lengths[] = {0,     1,     2,     3,     4,     8,\r
559                                  126,   127,   128,   16383, 16384, 16385,\r
560                                  65534, 65535, 65536, 65537};\r
561     uint8_t *buf;\r
562     uint8_t *bend;\r
563     uint8_t *b;\r
564     size_t rnd_bits, rnd_len;\r
565     BIT_STRING_t *st;\r
566 \r
567     if(max_length == 0) return result_skipped;\r
568 \r
569     switch(specs->subvariant) {\r
570     case ASN_OSUBV_ANY:\r
571         return result_failed;\r
572     case ASN_OSUBV_BIT:\r
573         break;\r
574     default:\r
575         break;\r
576     }\r
577 \r
578     /* Figure out how far we should go */\r
579     rnd_bits = lengths[asn_random_between(\r
580         0, sizeof(lengths) / sizeof(lengths[0]) - 1)];\r
581     if(!constraints || !constraints->per_constraints)\r
582         constraints = &td->encoding_constraints;\r
583     if(constraints->per_constraints) {\r
584         const asn_per_constraint_t *pc = &constraints->per_constraints->size;\r
585         if(pc->flags & APC_CONSTRAINED) {\r
586             long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length\r
587                                              ? pc->upper_bound\r
588                                              : (ssize_t)max_length;\r
589             if(max_length < (size_t)pc->lower_bound) {\r
590                 return result_skipped;\r
591             }\r
592             if(pc->flags & APC_EXTENSIBLE) {\r
593                 switch(asn_random_between(0, 5)) {\r
594                 case 0:\r
595                     if(pc->lower_bound > 0) {\r
596                         rnd_bits = pc->lower_bound - 1;\r
597                         break;\r
598                     }\r
599                     /* Fall through */\r
600                 case 1:\r
601                     rnd_bits = pc->upper_bound + 1;\r
602                     break;\r
603                 case 2:\r
604                     /* Keep rnd_bits from the table */\r
605                     if(rnd_bits < max_length) {\r
606                         break;\r
607                     }\r
608                     /* Fall through */\r
609                 default:\r
610                     rnd_bits = asn_random_between(pc->lower_bound,\r
611                                                   suggested_upper_bound);\r
612                 }\r
613             } else {\r
614                 rnd_bits =\r
615                     asn_random_between(pc->lower_bound, suggested_upper_bound);\r
616             }\r
617         } else {\r
618             rnd_bits = asn_random_between(0, max_length - 1);\r
619         }\r
620     } else if(rnd_bits >= max_length) {\r
621         rnd_bits = asn_random_between(0, max_length - 1);\r
622     }\r
623 \r
624     rnd_len = (rnd_bits + 7) / 8;\r
625     buf = CALLOC(1, rnd_len + 1);\r
626     if(!buf) return result_failed;\r
627 \r
628     bend = &buf[rnd_len];\r
629 \r
630     for(b = buf; b < bend; b++) {\r
631         *(uint8_t *)b = asn_random_between(0, 255);\r
632     }\r
633     *b = 0; /* Zero-terminate just in case. */\r
634 \r
635     if(*sptr) {\r
636         st = *sptr;\r
637         FREEMEM(st->buf);\r
638     } else {\r
639         st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));\r
640         if(!st) {\r
641             FREEMEM(buf);\r
642             return result_failed;\r
643         }\r
644     }\r
645 \r
646     st->buf = buf;\r
647     st->size = rnd_len;\r
648     st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;\r
649     if(st->bits_unused) {\r
650         assert(st->size > 0);\r
651         st->buf[st->size-1] &= 0xff << st->bits_unused;\r
652     }\r
653 \r
654     result_ok.length = st->size;\r
655     return result_ok;\r
656 }\r