SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / constr_CHOICE_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 <constr_CHOICE.h>
8
9 asn_random_fill_result_t
10 CHOICE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
11                    const asn_encoding_constraints_t *constr,
12                    size_t max_length) {
13     const asn_CHOICE_specifics_t *specs =
14         (const asn_CHOICE_specifics_t *)td->specifics;
15     asn_random_fill_result_t res;
16     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
17     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
18     const asn_TYPE_member_t *elm;
19     unsigned present;
20     void *memb_ptr;    /* Pointer to the member */
21     void **memb_ptr2;  /* Pointer to that pointer */
22     void *st = *sptr;
23
24     if(max_length == 0) return result_skipped;
25
26     (void)constr;
27
28     if(st == NULL) {
29         st = CALLOC(1, specs->struct_size);
30         if(st == NULL) {
31             return result_failed;
32         }
33     }
34
35     present = asn_random_between(1, td->elements_count);
36     elm = &td->elements[present - 1];
37
38     if(elm->flags & ATF_POINTER) {
39         /* Member is a pointer to another structure */
40         memb_ptr2 = (void **)((char *)st + elm->memb_offset);
41     } else {
42         memb_ptr = (char *)st + elm->memb_offset;
43         memb_ptr2 = &memb_ptr;
44     }
45
46     res = elm->type->op->random_fill(elm->type, memb_ptr2,
47                                     &elm->encoding_constraints, max_length);
48     _set_present_idx(st, specs->pres_offset, specs->pres_size, present);
49     if(res.code == ARFILL_OK) {
50         *sptr = st;
51     } else {
52         if(st == *sptr) {
53             ASN_STRUCT_RESET(*td, st);
54         } else {
55             ASN_STRUCT_FREE(*td, st);
56         }
57     }
58
59     return res;
60 }