SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / constr_SEQUENCE_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_SEQUENCE.h>
8
9 asn_random_fill_result_t
10 SEQUENCE_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_SEQUENCE_specifics_t *specs =
14         (const asn_SEQUENCE_specifics_t *)td->specifics;
15     asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
16     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
17     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
18     void *st = *sptr;
19     size_t edx;
20
21     if(max_length == 0) return result_skipped;
22
23     (void)constr;
24
25     if(st == NULL) {
26         st = CALLOC(1, specs->struct_size);
27         if(st == NULL) {
28             return result_failed;
29         }
30     }
31
32     for(edx = 0; edx < td->elements_count; edx++) {
33         const asn_TYPE_member_t *elm = &td->elements[edx];
34         void *memb_ptr;    /* Pointer to the member */
35         void **memb_ptr2;  /* Pointer to that pointer */
36         asn_random_fill_result_t tmpres;
37
38         if(elm->optional && asn_random_between(0, 4) == 2) {
39             /* Sometimes decide not to fill the optional value */
40             continue;
41         }
42
43         if(elm->flags & ATF_POINTER) {
44             /* Member is a pointer to another structure */
45             memb_ptr2 = (void **)((char *)st + elm->memb_offset);
46         } else {
47             memb_ptr = (char *)st + elm->memb_offset;
48             memb_ptr2 = &memb_ptr;
49         }
50
51         tmpres = elm->type->op->random_fill(
52             elm->type, memb_ptr2, &elm->encoding_constraints,
53             max_length > result_ok.length ? max_length - result_ok.length : 0);
54         switch(tmpres.code) {
55         case ARFILL_OK:
56             result_ok.length += tmpres.length;
57             continue;
58         case ARFILL_SKIPPED:
59             assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
60             continue;
61         case ARFILL_FAILED:
62             if(st == *sptr) {
63                 ASN_STRUCT_RESET(*td, st);
64             } else {
65                 ASN_STRUCT_FREE(*td, st);
66             }
67             return tmpres;
68         }
69     }
70
71     *sptr = st;
72
73     return result_ok;
74 }