SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / NativeInteger_ber.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 <NativeInteger.h>
8 #include <INTEGER.h>
9
10 /*
11  * Decode INTEGER type.
12  */
13 asn_dec_rval_t
14 NativeInteger_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
15                          const asn_TYPE_descriptor_t *td, void **nint_ptr,
16                          const void *buf_ptr, size_t size, int tag_mode) {
17     const asn_INTEGER_specifics_t *specs =
18         (const asn_INTEGER_specifics_t *)td->specifics;
19     long *native = (long *)*nint_ptr;
20     asn_dec_rval_t rval;
21     ber_tlv_len_t length;
22
23     /*
24      * If the structure is not there, allocate it.
25      */
26     if(native == NULL) {
27         native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
28         if(native == NULL) {
29             rval.code = RC_FAIL;
30             rval.consumed = 0;
31             return rval;
32         }
33     }
34
35     ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
36               td->name, tag_mode);
37
38     /*
39      * Check tags.
40      */
41     rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
42                           tag_mode, 0, &length, 0);
43     if(rval.code != RC_OK)
44         return rval;
45
46     ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
47
48     /*
49      * Make sure we have this length.
50      */
51     buf_ptr = ((const char *)buf_ptr) + rval.consumed;
52     size -= rval.consumed;
53     if(length > (ber_tlv_len_t)size) {
54         rval.code = RC_WMORE;
55         rval.consumed = 0;
56         return rval;
57     }
58
59     /*
60      * ASN.1 encoded INTEGER: buf_ptr, length
61      * Fill the native, at the same time checking for overflow.
62      * If overflow occurred, return with RC_FAIL.
63      */
64     {
65         INTEGER_t tmp;
66         union {
67             const void *constbuf;
68             void *nonconstbuf;
69         } unconst_buf;
70         long l;
71
72         unconst_buf.constbuf = buf_ptr;
73         tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
74         tmp.size = length;
75
76         if((specs&&specs->field_unsigned)
77             ? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
78             : asn_INTEGER2long(&tmp, &l)) {
79             rval.code = RC_FAIL;
80             rval.consumed = 0;
81             return rval;
82         }
83
84         *native = l;
85     }
86
87     rval.code = RC_OK;
88     rval.consumed += length;
89
90     ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
91               (long)rval.consumed, (long)length, td->name, (long)*native);
92
93     return rval;
94 }
95
96 /*
97  * Encode the NativeInteger using the standard INTEGER type DER encoder.
98  */
99 asn_enc_rval_t
100 NativeInteger_encode_der(const asn_TYPE_descriptor_t *sd, const void *ptr,
101                          int tag_mode, ber_tlv_tag_t tag,
102                          asn_app_consume_bytes_f *cb, void *app_key) {
103     unsigned long native = *(const unsigned long *)ptr; /* Disable sign ext. */
104     asn_enc_rval_t erval = {0,0,0};
105     INTEGER_t tmp;
106
107 #ifdef WORDS_BIGENDIAN  /* Opportunistic optimization */
108
109     tmp.buf = (uint8_t *)&native;
110     tmp.size = sizeof(native);
111
112 #else  /* Works even if WORDS_BIGENDIAN is not set where should've been */
113     uint8_t buf[sizeof(native)];
114     uint8_t *p;
115
116     /* Prepare a fake INTEGER */
117     for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
118         *p = (uint8_t)native;
119
120     tmp.buf = buf;
121     tmp.size = sizeof(buf);
122 #endif  /* WORDS_BIGENDIAN */
123
124     /* Encode fake INTEGER */
125     erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
126     if(erval.structure_ptr == &tmp) {
127         erval.structure_ptr = ptr;
128     }
129     return erval;
130 }