Fix licensing issues
[ric-plt/resource-status-manager.git] / RSM / 3rdparty / asn1codec / e2ap_engine / NativeEnumerated.c
1
2 /*-
3  * Copyright (c) 2004, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
6 /*
7  * Read the NativeInteger.h for the explanation wrt. differences between
8  * INTEGER and NativeInteger.
9  * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
10  * implementation deals with the standard (machine-specific) representation
11  * of them instead of using the platform-independent buffer.
12  */
13 #include <asn_internal.h>
14 #include <NativeEnumerated.h>
15
16 /*
17  * NativeEnumerated basic type description.
18  */
19 static const ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
20         (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
21 };
22 asn_TYPE_operation_t asn_OP_NativeEnumerated = {
23         NativeInteger_free,
24         NativeInteger_print,
25         NativeInteger_compare,
26         NativeInteger_decode_ber,
27         NativeInteger_encode_der,
28         NativeInteger_decode_xer,
29         NativeEnumerated_encode_xer,
30 #ifdef  ASN_DISABLE_OER_SUPPORT
31         0,
32         0,
33 #else
34         NativeEnumerated_decode_oer,
35         NativeEnumerated_encode_oer,
36 #endif  /* ASN_DISABLE_OER_SUPPORT */
37 #ifdef  ASN_DISABLE_PER_SUPPORT
38         0,
39         0,
40         0,
41         0,
42 #else
43         NativeEnumerated_decode_uper,
44         NativeEnumerated_encode_uper,
45         NativeEnumerated_decode_aper,
46         NativeEnumerated_encode_aper,
47 #endif  /* ASN_DISABLE_PER_SUPPORT */
48         NativeEnumerated_random_fill,
49         0       /* Use generic outmost tag fetcher */
50 };
51 asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
52         "ENUMERATED",                   /* The ASN.1 type is still ENUMERATED */
53         "ENUMERATED",
54         &asn_OP_NativeEnumerated,
55         asn_DEF_NativeEnumerated_tags,
56         sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
57         asn_DEF_NativeEnumerated_tags,  /* Same as above */
58         sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
59         { 0, 0, asn_generic_no_constraint },
60         0, 0,   /* No members */
61         0       /* No specifics */
62 };
63
64 asn_enc_rval_t
65 NativeEnumerated_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
66                             int ilevel, enum xer_encoder_flags_e flags,
67                             asn_app_consume_bytes_f *cb, void *app_key) {
68     const asn_INTEGER_specifics_t *specs =
69         (const asn_INTEGER_specifics_t *)td->specifics;
70     asn_enc_rval_t er = {0,0,0};
71     const long *native = (const long *)sptr;
72     const asn_INTEGER_enum_map_t *el;
73
74     (void)ilevel;
75     (void)flags;
76
77     if(!native) ASN__ENCODE_FAILED;
78
79     el = INTEGER_map_value2enum(specs, *native);
80     if(el) {
81         er.encoded =
82             asn__format_to_callback(cb, app_key, "<%s/>", el->enum_name);
83         if(er.encoded < 0) ASN__ENCODE_FAILED;
84         ASN__ENCODED_OK(er);
85     } else {
86         ASN_DEBUG(
87             "ASN.1 forbids dealing with "
88             "unknown value of ENUMERATED type");
89         ASN__ENCODE_FAILED;
90     }
91 }
92
93 asn_dec_rval_t
94 NativeEnumerated_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
95                              const asn_TYPE_descriptor_t *td,
96                              const asn_per_constraints_t *constraints,
97                              void **sptr, asn_per_data_t *pd) {
98     const asn_INTEGER_specifics_t *specs = td->specifics;
99     asn_dec_rval_t rval = { RC_OK, 0 };
100         long *native = (long *)*sptr;
101         const asn_per_constraint_t *ct = NULL; // BMC
102         long value;
103
104         (void)opt_codec_ctx;
105
106         if(constraints) ct = &constraints->value;
107         else if(td->encoding_constraints.per_constraints)
108                 ct = &td->encoding_constraints.per_constraints->value;
109         else ASN__DECODE_FAILED;        /* Mandatory! */
110         if(!specs) ASN__DECODE_FAILED;
111
112         if(!native) {
113                 native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
114                 if(!native) ASN__DECODE_FAILED;
115         }
116
117         ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
118
119         if(ct && ct->flags & APC_EXTENSIBLE) { // BMC
120                 int inext = per_get_few_bits(pd, 1);
121                 if(inext < 0) ASN__DECODE_STARVED;
122                 if(inext) ct = 0;
123         }
124
125         if(ct && ct->range_bits >= 0) {
126                 value = per_get_few_bits(pd, ct->range_bits);
127                 if(value < 0) ASN__DECODE_STARVED;
128                 if(value >= (specs->extension
129                         ? specs->extension - 1 : specs->map_count))
130                         ASN__DECODE_FAILED;
131         } else {
132                 if(!specs->extension)
133                         ASN__DECODE_FAILED;
134                 /*
135                  * X.691, #10.6: normally small non-negative whole number;
136                  */
137                 value = uper_get_nsnnwn(pd);
138                 if(value < 0) ASN__DECODE_STARVED;
139                 value += specs->extension - 1;
140                 if(value >= specs->map_count)
141                         ASN__DECODE_FAILED;
142         }
143
144         *native = specs->value2enum[value].nat_value;
145         ASN_DEBUG("Decoded %s = %ld", td->name, *native);
146
147         return rval;
148 }
149
150 static int
151 NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
152         const asn_INTEGER_enum_map_t *a = ap;
153         const asn_INTEGER_enum_map_t *b = bp;
154         if(a->nat_value == b->nat_value)
155                 return 0;
156         if(a->nat_value < b->nat_value)
157                 return -1;
158         return 1;
159 }
160
161 asn_enc_rval_t
162 NativeEnumerated_encode_uper(const asn_TYPE_descriptor_t *td,
163                              const asn_per_constraints_t *constraints,
164                              const void *sptr, asn_per_outp_t *po) {
165         const asn_INTEGER_specifics_t *specs =
166         (const asn_INTEGER_specifics_t *)td->specifics;
167         asn_enc_rval_t er = {0,0,0};
168         long native, value;
169         const asn_per_constraint_t *ct = NULL; // BMC
170         int inext = 0;
171         asn_INTEGER_enum_map_t key;
172         const asn_INTEGER_enum_map_t *kf;
173
174         if(!sptr) ASN__ENCODE_FAILED;
175         if(!specs) ASN__ENCODE_FAILED;
176
177         if(constraints) ct = &constraints->value;
178         else if(td->encoding_constraints.per_constraints)
179                 ct = &td->encoding_constraints.per_constraints->value;
180         else ASN__ENCODE_FAILED;        /* Mandatory! */
181
182         ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
183
184         er.encoded = 0;
185
186         native = *(const long *)sptr;
187
188         key.nat_value = native;
189         kf = bsearch(&key, specs->value2enum, specs->map_count,
190                 sizeof(key), NativeEnumerated__compar_value2enum);
191         if(!kf) {
192                 ASN_DEBUG("No element corresponds to %ld", native);
193                 ASN__ENCODE_FAILED;
194         }
195         value = kf - specs->value2enum;
196
197         if(ct && ct->range_bits >= 0) { // BMC
198                 int cmpWith = specs->extension
199                                 ? specs->extension - 1 : specs->map_count;
200                 if(value >= cmpWith)
201                         inext = 1;
202         }
203         if(ct && ct->flags & APC_EXTENSIBLE) { // BMC
204                 if(per_put_few_bits(po, inext, 1))
205                         ASN__ENCODE_FAILED;
206                 if(inext) ct = 0;
207         } else if(inext) {
208                 ASN__ENCODE_FAILED;
209         }
210
211         if(ct && ct->range_bits >= 0) {
212                 if(per_put_few_bits(po, value, ct->range_bits))
213                         ASN__ENCODE_FAILED;
214                 ASN__ENCODED_OK(er);
215         }
216
217         if(!specs->extension)
218                 ASN__ENCODE_FAILED;
219
220         /*
221          * X.691, #10.6: normally small non-negative whole number;
222          */
223         ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
224                 value, specs->extension, inext,
225                 value - (inext ? (specs->extension - 1) : 0));
226         if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
227                 ASN__ENCODE_FAILED;
228
229         ASN__ENCODED_OK(er);
230 }
231
232 asn_dec_rval_t
233 NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
234                              const asn_TYPE_descriptor_t *td,
235                              const asn_per_constraints_t *constraints,
236                              void **sptr, asn_per_data_t *pd) {
237         const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
238         asn_dec_rval_t rval = { RC_OK, 0 };
239         long *native = (long *)*sptr;
240         const asn_per_constraint_t *ct = NULL; // BMC
241         long value;
242
243         (void)opt_codec_ctx;
244
245         if(constraints) ct = &constraints->value;
246         else if(td->encoding_constraints.per_constraints)
247                 ct = &td->encoding_constraints.per_constraints->value;
248         else ASN__DECODE_FAILED;        /* Mandatory! */
249         if(!specs) ASN__DECODE_FAILED;
250
251         if(!native) {
252                 native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
253                 if(!native) ASN__DECODE_FAILED;
254         }
255
256         ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
257
258         if(ct && ct->flags & APC_EXTENSIBLE) { // BMC
259                 int inext = per_get_few_bits(pd, 1);
260                 if(inext < 0) ASN__DECODE_STARVED;
261                 if(inext) ct = 0;
262         }
263
264         /* Deal with APER padding */
265         if(ct && ct->upper_bound >= 255) {
266                 int padding = 0;
267                 padding = (8 - (pd->moved % 8)) % 8;
268                 ASN_DEBUG("For NativeEnumerated %s,offset= %lu Padding bits = %d", td->name, pd->moved, padding);
269                 ASN_DEBUG("For NativeEnumerated %s, upper bound = %lu", td->name, ct->upper_bound);
270                 if(padding > 0)
271                         per_get_few_bits(pd, padding);
272         }
273
274         if(ct && ct->range_bits >= 0) {
275                 value = per_get_few_bits(pd, ct->range_bits);
276                 if(value < 0) ASN__DECODE_STARVED;
277                 if(value >= (specs->extension
278                              ? specs->extension - 1 : specs->map_count))
279                         ASN__DECODE_FAILED;
280         } else {
281                 if(!specs->extension)
282                         ASN__DECODE_FAILED;
283                 /*
284                  * X.691, #10.6: normally small non-negative whole number;
285                  */
286                 value = uper_get_nsnnwn(pd);
287                 if(value < 0) ASN__DECODE_STARVED;
288                 value += specs->extension - 1;
289                 if(value >= specs->map_count)
290                         ASN__DECODE_FAILED;
291         }
292
293         *native = specs->value2enum[value].nat_value;
294         ASN_DEBUG("Decoded %s = %ld", td->name, *native);
295
296         return rval;
297 }
298
299 asn_enc_rval_t
300 NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td,
301                              const asn_per_constraints_t *constraints,
302                              const void *sptr, asn_per_outp_t *po) {
303         const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
304         asn_enc_rval_t er = {0,0,0};
305         long native, value;
306         const asn_per_constraint_t *ct = NULL; // BMC
307         int inext = 0;
308         asn_INTEGER_enum_map_t key;
309         asn_INTEGER_enum_map_t *kf;
310
311         if(!sptr) ASN__ENCODE_FAILED;
312         if(!specs) ASN__ENCODE_FAILED;
313
314         if(constraints) ct = &constraints->value;
315         else if(td->encoding_constraints.per_constraints)
316                 ct = &td->encoding_constraints.per_constraints->value;
317         else ASN__ENCODE_FAILED;        /* Mandatory! */
318
319         ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
320
321         er.encoded = 0;
322
323         native = *(const long *)sptr;
324         if(native < 0) ASN__ENCODE_FAILED;
325
326         key.nat_value = native;
327         kf = bsearch(&key, specs->value2enum, specs->map_count,
328                      sizeof(key), NativeEnumerated__compar_value2enum);
329         if(!kf) {
330                 ASN_DEBUG("No element corresponds to %ld", native);
331                 ASN__ENCODE_FAILED;
332         }
333         value = kf - specs->value2enum;
334
335         if(ct && ct->range_bits >= 0) { // BMC
336                 int cmpWith = specs->extension
337                               ? specs->extension - 1 : specs->map_count;
338                 if(value >= cmpWith)
339                         inext = 1;
340         }
341         if(ct && ct->flags & APC_EXTENSIBLE) { // BMC
342                 if(per_put_few_bits(po, inext, 1))
343                         ASN__ENCODE_FAILED;
344                 if(inext) ct = 0;
345         } else if(inext) {
346                 ASN__ENCODE_FAILED;
347         }
348
349         if(ct && ct->range_bits >= 0) {
350                 if(per_put_few_bits(po, value, ct->range_bits))
351                         ASN__ENCODE_FAILED;
352                 ASN__ENCODED_OK(er);
353         }
354
355         if(!specs->extension)
356                 ASN__ENCODE_FAILED;
357
358         /*
359          * X.691, #10.6: normally small non-negative whole number;
360          */
361         ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
362                   value, specs->extension, inext,
363                   value - (inext ? (specs->extension - 1) : 0));
364         if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
365                 ASN__ENCODE_FAILED;
366
367         ASN__ENCODED_OK(er);
368 }