SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / NativeReal.c
1 /*-
2  * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
5 /*
6  * Read the NativeReal.h for the explanation wrt. differences between
7  * REAL and NativeReal.
8  * Basically, both are decoders and encoders of ASN.1 REAL type, but this
9  * implementation deals with the standard (machine-specific) representation
10  * of them instead of using the platform-independent buffer.
11  */
12 #include <asn_internal.h>
13 #include <NativeReal.h>
14 #include <REAL.h>
15 #include <math.h>
16
17 #if defined(__clang__)
18 /*
19  * isnan() is defined using generic selections and won't compile in
20  * strict C89 mode because of too fancy system's standard library.
21  * However, prior to C11 the math had a perfectly working isnan()
22  * in the math library.
23  * Disable generic selection warning so we can test C89 mode with newer libc.
24  */
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wc11-extensions"
27 static int asn_isnan(double d) {
28     return isnan(d);
29 }
30 #pragma clang diagnostic pop
31 #else
32 #define asn_isnan(v)    isnan(v)
33 #endif  /* generic selections */
34
35 /*
36  * NativeReal basic type description.
37  */
38 static const ber_tlv_tag_t asn_DEF_NativeReal_tags[] = {
39     (ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
40 };
41 asn_TYPE_operation_t asn_OP_NativeReal = {
42     NativeReal_free,
43 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
44     NativeReal_print,
45 #else
46     0,
47 #endif  /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
48     NativeReal_compare,
49 #if !defined(ASN_DISABLE_BER_SUPPORT)
50     NativeReal_decode_ber,
51     NativeReal_encode_der,
52 #else
53     0,
54     0,
55 #endif  /* !defined(ASN_DISABLE_BER_SUPPORT) */
56 #if !defined(ASN_DISABLE_XER_SUPPORT)
57     NativeReal_decode_xer,
58     NativeReal_encode_xer,
59 #else
60     0,
61     0,
62 #endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
63 #if !defined(ASN_DISABLE_JER_SUPPORT)
64     NativeReal_encode_jer,
65 #else
66     0,
67 #endif  /* !defined(ASN_DISABLE_JER_SUPPORT) */
68 #if !defined(ASN_DISABLE_OER_SUPPORT)
69     NativeReal_decode_oer,
70     NativeReal_encode_oer,
71 #else
72     0,
73     0,
74 #endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
75 #if !defined(ASN_DISABLE_UPER_SUPPORT)
76     NativeReal_decode_uper,
77     NativeReal_encode_uper,
78 #else
79     0,
80     0,
81 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) */
82 #if !defined(ASN_DISABLE_APER_SUPPORT)
83     NativeReal_decode_aper,
84     NativeReal_encode_aper,
85 #else
86     0,
87     0,
88 #endif  /* !defined(ASN_DISABLE_APER_SUPPORT) */
89 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
90     NativeReal_random_fill,
91 #else
92     0,
93 #endif  /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
94     0  /* Use generic outmost tag fetcher */
95 };
96 asn_TYPE_descriptor_t asn_DEF_NativeReal = {
97     "REAL",  /* The ASN.1 type is still REAL */
98     "REAL",
99     &asn_OP_NativeReal,
100     asn_DEF_NativeReal_tags,
101     sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
102     asn_DEF_NativeReal_tags,    /* Same as above */
103     sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
104     {
105 #if !defined(ASN_DISABLE_OER_SUPPORT)
106         0,
107 #endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
108 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
109         0,
110 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
111         asn_generic_no_constraint
112     },
113     0, 0,  /* No members */
114     0  /* No specifics */
115 };
116
117 int
118 NativeReal_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
119                    const void *bptr) {
120
121     if(aptr && bptr) {
122         double a = NativeReal__get_double(td, aptr);
123         double b = NativeReal__get_double(td, bptr);
124
125         /* NaN sorted above everything else */
126         if(asn_isnan(a)) {
127             if(asn_isnan(b)) {
128                 return 0;
129             } else {
130                 return -1;
131             }
132         } else if(asn_isnan(b)) {
133             return 1;
134         }
135         /* Value comparison. */
136         if(a < b) {
137             return -1;
138         } else if(a > b) {
139             return 1;
140         } else {
141             return 0;
142         }
143     } else if(!aptr) {
144         return -1;
145     } else {
146         return 1;
147     }
148 }
149
150 void
151 NativeReal_free(const asn_TYPE_descriptor_t *td, void *ptr,
152                 enum asn_struct_free_method method) {
153     if(!td || !ptr)
154                 return;
155
156         ASN_DEBUG("Freeing %s as REAL (%d, %p, Native)",
157                 td->name, method, ptr);
158
159     switch(method) {
160     case ASFM_FREE_EVERYTHING:
161         FREEMEM(ptr);
162         break;
163     case ASFM_FREE_UNDERLYING:
164         break;
165     case ASFM_FREE_UNDERLYING_AND_RESET: {
166         const asn_NativeReal_specifics_t *specs;
167         size_t float_size;
168         specs = (const asn_NativeReal_specifics_t *)td->specifics;
169         float_size = specs ? specs->float_size : sizeof(double);
170         memset(ptr, 0, float_size);
171     } break;
172     }
173 }
174
175 /*
176  * Local helper functions.
177  */
178
179 size_t
180 NativeReal__float_size(const asn_TYPE_descriptor_t *td) {
181     const asn_NativeReal_specifics_t *specs =
182         (const asn_NativeReal_specifics_t *)td->specifics;
183     return specs ? specs->float_size : sizeof(double);
184 }
185
186 double
187 NativeReal__get_double(const asn_TYPE_descriptor_t *td, const void *ptr) {
188     size_t float_size = NativeReal__float_size(td);
189     if(float_size == sizeof(float)) {
190         return *(const float *)ptr;
191     } else {
192         return *(const double *)ptr;
193     }
194 }
195
196 ssize_t  /* Returns -1 or float size. */
197 NativeReal__set(const asn_TYPE_descriptor_t *td, void **sptr, double d) {
198     size_t float_size = NativeReal__float_size(td);
199     void *native;
200
201     if(!(native = *sptr)) {
202         native = (*sptr = CALLOC(1, float_size));
203         if(!native) {
204             return -1;
205         }
206     }
207
208     if(float_size == sizeof(float)) {
209         if(asn_double2float(d, (float *)native)) {
210             return -1;
211         }
212     } else {
213         *(double *)native = d;
214     }
215
216     return float_size;
217 }
218