SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / INTEGER_rfill.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 <INTEGER.h>
8
9 asn_random_fill_result_t
10 INTEGER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
11                     const asn_encoding_constraints_t *constraints,
12                     size_t max_length) {
13     const asn_INTEGER_specifics_t *specs =
14         (const asn_INTEGER_specifics_t *)td->specifics;
15     asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
16     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
17     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
18     INTEGER_t *st = *sptr;
19     const asn_INTEGER_enum_map_t *emap;
20     size_t emap_len;
21     intmax_t value;
22     int find_inside_map;
23
24     if(max_length == 0) return result_skipped;
25
26     if(st == NULL) {
27         st = (INTEGER_t *)CALLOC(1, sizeof(*st));
28         if(st == NULL) {
29             return result_failed;
30         }
31     }
32
33     if(specs) {
34         emap = specs->value2enum;
35         emap_len = specs->map_count;
36         if(specs->strict_enumeration) {
37             find_inside_map = emap_len > 0;
38         } else {
39             find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
40         }
41     } else {
42         emap = 0;
43         emap_len = 0;
44         find_inside_map = 0;
45     }
46
47     if(find_inside_map) {
48         assert(emap_len > 0);
49         value = emap[asn_random_between(0, emap_len - 1)].nat_value;
50     } else {
51         static const long variants[] = {
52             -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
53             -16383, -257,   -256,   -255,   -254,   -129,   -128,   -127,
54             -126,   -1,     0,      1,      126,    127,    128,    129,
55             254,    255,    256,    257,    16383,  16384,  16385,  32767,
56             32768,  32769,  65534,  65535,  65536,  65537};
57         if(specs && specs->field_unsigned) {
58             assert(variants[18] == 0);
59             value = variants[asn_random_between(
60                 18, sizeof(variants) / sizeof(variants[0]) - 1)];
61         } else {
62             value = variants[asn_random_between(
63                 0, sizeof(variants) / sizeof(variants[0]) - 1)];
64         }
65
66         if(!constraints) constraints = &td->encoding_constraints;
67 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
68         const asn_per_constraints_t *ct;
69
70         ct = constraints ? constraints->per_constraints : 0;
71         if(ct && (ct->value.flags & APC_CONSTRAINED)) {
72             if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
73                 value = asn_random_between(ct->value.lower_bound,
74                                            ct->value.upper_bound);
75             }
76         }
77 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
78     }
79
80     if(asn_imax2INTEGER(st, value)) {
81         if(st == *sptr) {
82             ASN_STRUCT_RESET(*td, st);
83         } else {
84             ASN_STRUCT_FREE(*td, st);
85         }
86         return result_failed;
87     } else {
88         *sptr = st;
89         result_ok.length = st->size;
90         return result_ok;
91     }
92 }