SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / NativeEnumerated_uper.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 <NativeEnumerated.h>
8
9 asn_dec_rval_t
10 NativeEnumerated_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
11                              const asn_TYPE_descriptor_t *td,
12                              const asn_per_constraints_t *constraints,
13                              void **sptr, asn_per_data_t *pd) {
14     const asn_INTEGER_specifics_t *specs = td->specifics;
15     asn_dec_rval_t rval = { RC_OK, 0 };
16     long *native = (long *)*sptr;
17     const asn_per_constraint_t *ct;
18     long value;
19
20     (void)opt_codec_ctx;
21
22     if(constraints) ct = &constraints->value;
23     else if(td->encoding_constraints.per_constraints)
24         ct = &td->encoding_constraints.per_constraints->value;
25     else ASN__DECODE_FAILED;  /* Mandatory! */
26     if(!specs) ASN__DECODE_FAILED;
27
28     if(!native) {
29         native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
30         if(!native) ASN__DECODE_FAILED;
31     }
32
33     ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
34
35     if(ct->flags & APC_EXTENSIBLE) {
36         int inext = per_get_few_bits(pd, 1);
37         if(inext < 0) ASN__DECODE_STARVED;
38         if(inext) ct = 0;
39     }
40
41     if(ct && ct->range_bits >= 0) {
42         value = per_get_few_bits(pd, ct->range_bits);
43         if(value < 0) ASN__DECODE_STARVED;
44         if(value >= (specs->extension
45             ? specs->extension - 1 : specs->map_count))
46             ASN__DECODE_FAILED;
47     } else {
48         if(!specs->extension)
49             ASN__DECODE_FAILED;
50         /*
51          * X.691, #10.6: normally small non-negative whole number;
52          */
53         value = uper_get_nsnnwn(pd);
54         if(value < 0) ASN__DECODE_STARVED;
55         value += specs->extension - 1;
56         if(value >= specs->map_count)
57             ASN__DECODE_FAILED;
58     }
59
60     *native = specs->value2enum[value].nat_value;
61     ASN_DEBUG("Decoded %s = %ld", td->name, *native);
62
63     return rval;
64 }
65
66 asn_enc_rval_t
67 NativeEnumerated_encode_uper(const asn_TYPE_descriptor_t *td,
68                              const asn_per_constraints_t *constraints,
69                              const void *sptr, asn_per_outp_t *po) {
70     const asn_INTEGER_specifics_t *specs =
71         (const asn_INTEGER_specifics_t *)td->specifics;
72     asn_enc_rval_t er = {0,0,0};
73     long native, value;
74     const asn_per_constraint_t *ct;
75     int inext = 0;
76     asn_INTEGER_enum_map_t key;
77     const asn_INTEGER_enum_map_t *kf;
78
79     if(!sptr) ASN__ENCODE_FAILED;
80     if(!specs) ASN__ENCODE_FAILED;
81
82     if(constraints) ct = &constraints->value;
83     else if(td->encoding_constraints.per_constraints)
84         ct = &td->encoding_constraints.per_constraints->value;
85     else ASN__ENCODE_FAILED;  /* Mandatory! */
86
87     ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
88
89     er.encoded = 0;
90
91     native = *(const long *)sptr;
92
93     key.nat_value = native;
94     kf = bsearch(&key, specs->value2enum, specs->map_count,
95         sizeof(key), NativeEnumerated__compar_value2enum);
96     if(!kf) {
97         ASN_DEBUG("No element corresponds to %ld", native);
98         ASN__ENCODE_FAILED;
99     }
100     value = kf - specs->value2enum;
101
102     if(ct->range_bits >= 0) {
103         int cmpWith = specs->extension
104             ? specs->extension - 1 : specs->map_count;
105         if(value >= cmpWith)
106             inext = 1;
107     }
108     if(ct->flags & APC_EXTENSIBLE) {
109         if(per_put_few_bits(po, inext, 1))
110             ASN__ENCODE_FAILED;
111         if(inext) ct = 0;
112     } else if(inext) {
113         ASN__ENCODE_FAILED;
114     }
115
116     if(ct && ct->range_bits >= 0) {
117         if(per_put_few_bits(po, value, ct->range_bits))
118             ASN__ENCODE_FAILED;
119         ASN__ENCODED_OK(er);
120     }
121
122     if(!specs->extension)
123         ASN__ENCODE_FAILED;
124
125     /*
126      * X.691, #10.6: normally small non-negative whole number;
127      */
128     ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
129         value, specs->extension, inext,
130         value - (inext ? (specs->extension - 1) : 0));
131     if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
132         ASN__ENCODE_FAILED;
133
134     ASN__ENCODED_OK(er);
135 }