SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / asn_random_fill.c
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  */
6 #include <asn_internal.h>
7 #include <asn_random_fill.h>
8 #include <constr_TYPE.h>
9
10 int
11 asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr,
12                 size_t length) {
13
14     if(td && td->op->random_fill) {
15         asn_random_fill_result_t res =
16             td->op->random_fill(td, struct_ptr, 0, length);
17         return (res.code == ARFILL_OK) ? 0 : -1;
18     } else {
19         return -1;
20     }
21 }
22
23 static uintmax_t
24 asn__intmax_range(intmax_t lb, intmax_t ub) {
25     assert(lb <= ub);
26     if((ub < 0) == (lb < 0)) {
27         return ub - lb;
28     } else if(lb < 0) {
29         return 1 + ((uintmax_t)ub + (uintmax_t)-(lb + 1));
30     } else {
31         assert(!"Unreachable");
32         return 0;
33     }
34 }
35
36 intmax_t
37 asn_random_between(intmax_t lb, intmax_t rb) {
38     if(lb == rb) {
39         return lb;
40     } else {
41         const uintmax_t intmax_max = ((~(uintmax_t)0) >> 1);
42         uintmax_t range = asn__intmax_range(lb, rb);
43         uintmax_t value = 0;
44         uintmax_t got_entropy = 0;
45         (void)intmax_max;
46         int max = 0xffffff;
47
48 #ifdef __WIN32__
49         max = RAND_MAX-1;
50 #endif
51
52         assert(RAND_MAX > max);    /* Seen 7ffffffd! */
53         assert(range < intmax_max);
54
55         for(; got_entropy < range;) {
56             got_entropy = (got_entropy << 24) | max;
57 #ifdef HAVE_RANDOM
58             value = (value << 24) | (random() % max);
59 #else
60             value = (value << 24) | (rand() % max);
61 #endif
62         }
63
64         return lb + (intmax_t)(value % (range + 1));
65     }
66 }