SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / constr_SEQUENCE.c
1 /*
2  * Copyright (c) 2003-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_TYPE_operation_t asn_OP_SEQUENCE = {
10     SEQUENCE_free,
11 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
12     SEQUENCE_print,
13 #else
14     0,
15 #endif  /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
16     SEQUENCE_compare,
17 #if !defined(ASN_DISABLE_BER_SUPPORT)
18     SEQUENCE_decode_ber,
19     SEQUENCE_encode_der,
20 #else
21     0,
22     0,
23 #endif  /* !defined(ASN_DISABLE_BER_SUPPORT) */
24 #if !defined(ASN_DISABLE_XER_SUPPORT)
25     SEQUENCE_decode_xer,
26     SEQUENCE_encode_xer,
27 #else
28     0,
29     0,
30 #endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
31 #if !defined(ASN_DISABLE_JER_SUPPORT)
32     SEQUENCE_encode_jer,
33 #else
34     0,
35 #endif  /* !defined(ASN_DISABLE_JER_SUPPORT) */
36 #if !defined(ASN_DISABLE_OER_SUPPORT)
37     SEQUENCE_decode_oer,
38     SEQUENCE_encode_oer,
39 #else
40     0,
41     0,
42 #endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
43 #if !defined(ASN_DISABLE_UPER_SUPPORT)
44     SEQUENCE_decode_uper,
45     SEQUENCE_encode_uper,
46 #else
47     0,
48     0,
49 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) */
50 #if !defined(ASN_DISABLE_APER_SUPPORT)
51     SEQUENCE_decode_aper,
52     SEQUENCE_encode_aper,
53 #else
54     0,
55     0,
56 #endif  /* !defined(ASN_DISABLE_APER_SUPPORT) */
57 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
58     SEQUENCE_random_fill,
59 #else
60     0,
61 #endif  /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
62     0  /* Use generic outmost tag fetcher */
63 };
64
65 void
66 SEQUENCE_free(const asn_TYPE_descriptor_t *td, void *sptr,
67               enum asn_struct_free_method method) {
68     size_t edx;
69     const asn_SEQUENCE_specifics_t *specs =
70         (const asn_SEQUENCE_specifics_t *)td->specifics;
71     asn_struct_ctx_t *ctx; /* Decoder context */
72
73         if(!td || !sptr)
74                 return;
75
76         ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
77
78         for(edx = 0; edx < td->elements_count; edx++) {
79                 asn_TYPE_member_t *elm = &td->elements[edx];
80                 void *memb_ptr;
81                 if(elm->flags & ATF_POINTER) {
82                         memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
83                         if(memb_ptr)
84                                 ASN_STRUCT_FREE(*elm->type, memb_ptr);
85                 } else {
86                         memb_ptr = (void *)((char *)sptr + elm->memb_offset);
87                         ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
88                 }
89         }
90
91         /* Clean parsing context */
92         ctx = (asn_struct_ctx_t *)((char *)sptr + specs->ctx_offset);
93         FREEMEM(ctx->ptr);
94
95     switch(method) {
96     case ASFM_FREE_EVERYTHING:
97         FREEMEM(sptr);
98         break;
99     case ASFM_FREE_UNDERLYING:
100         break;
101     case ASFM_FREE_UNDERLYING_AND_RESET:
102         memset(
103             sptr, 0,
104             ((const asn_SEQUENCE_specifics_t *)(td->specifics))->struct_size);
105         break;
106     }
107 }
108
109 int
110 SEQUENCE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
111                     asn_app_constraint_failed_f *ctfailcb, void *app_key) {
112     size_t edx;
113
114         if(!sptr) {
115                 ASN__CTFAIL(app_key, td, sptr,
116                         "%s: value not given (%s:%d)",
117                         td->name, __FILE__, __LINE__);
118                 return -1;
119         }
120
121         /*
122          * Iterate over structure members and check their validity.
123          */
124         for(edx = 0; edx < td->elements_count; edx++) {
125                 asn_TYPE_member_t *elm = &td->elements[edx];
126                 const void *memb_ptr;
127                 asn_constr_check_f *constr;
128                 int ret;
129
130                 if(elm->flags & ATF_POINTER) {
131                         memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
132                         if(!memb_ptr) {
133                                 if(elm->optional)
134                                         continue;
135                                 ASN__CTFAIL(app_key, td, sptr,
136                                 "%s: mandatory element %s absent (%s:%d)",
137                                 td->name, elm->name, __FILE__, __LINE__);
138                                 return -1;
139                         }
140                 } else {
141                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
142                 }
143
144                 constr = elm->encoding_constraints.general_constraints;
145                 if(!constr)
146                         constr = elm->type->encoding_constraints.general_constraints;
147
148                 ret = constr(elm->type, memb_ptr, ctfailcb, app_key);
149                 if(ret) return ret;
150         }
151
152         return 0;
153 }
154
155 int
156 SEQUENCE_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
157                  const void *bptr) {
158     size_t edx;
159
160         for(edx = 0; edx < td->elements_count; edx++) {
161                 asn_TYPE_member_t *elm = &td->elements[edx];
162                 const void *amemb;
163                 const void *bmemb;
164         int ret;
165
166                 if(elm->flags & ATF_POINTER) {
167             amemb =
168                 *(const void *const *)((const char *)aptr + elm->memb_offset);
169             bmemb =
170                 *(const void *const *)((const char *)bptr + elm->memb_offset);
171             if(!amemb) {
172                 if(!bmemb) continue;
173                 if(elm->default_value_cmp
174                    && elm->default_value_cmp(bmemb) == 0) {
175                     /* A is absent, but B is present and equal to DEFAULT */
176                     continue;
177                 }
178                 return -1;
179             } else if(!bmemb) {
180                 if(elm->default_value_cmp
181                    && elm->default_value_cmp(amemb) == 0) {
182                     /* B is absent, but A is present and equal to DEFAULT */
183                     continue;
184                 }
185                 return 1;
186             }
187                 } else {
188             amemb = (const void *)((const char *)aptr + elm->memb_offset);
189             bmemb = (const void *)((const char *)bptr + elm->memb_offset);
190                 }
191
192         ret = elm->type->op->compare_struct(elm->type, amemb, bmemb);
193         if(ret != 0) return ret;
194     }
195
196     return 0;
197 }