2 * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
6 * Read the NativeReal.h for the explanation wrt. differences between
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.
12 #include <asn_internal.h>
13 #include <NativeReal.h>
17 #if defined(__clang__)
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.
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wc11-extensions"
27 static int asn_isnan(double d) {
30 #pragma clang diagnostic pop
32 #define asn_isnan(v) isnan(v)
33 #endif /* generic selections */
36 * NativeReal basic type description.
38 static const ber_tlv_tag_t asn_DEF_NativeReal_tags[] = {
39 (ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
41 asn_TYPE_operation_t asn_OP_NativeReal = {
43 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
47 #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
49 #if !defined(ASN_DISABLE_BER_SUPPORT)
50 NativeReal_decode_ber,
51 NativeReal_encode_der,
55 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
56 #if !defined(ASN_DISABLE_XER_SUPPORT)
57 NativeReal_decode_xer,
58 NativeReal_encode_xer,
62 #endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
63 #if !defined(ASN_DISABLE_JER_SUPPORT)
64 NativeReal_encode_jer,
67 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
68 #if !defined(ASN_DISABLE_OER_SUPPORT)
69 NativeReal_decode_oer,
70 NativeReal_encode_oer,
74 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
75 #if !defined(ASN_DISABLE_UPER_SUPPORT)
76 NativeReal_decode_uper,
77 NativeReal_encode_uper,
81 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
82 #if !defined(ASN_DISABLE_APER_SUPPORT)
83 NativeReal_decode_aper,
84 NativeReal_encode_aper,
88 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
89 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
90 NativeReal_random_fill,
93 #endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
94 0 /* Use generic outmost tag fetcher */
96 asn_TYPE_descriptor_t asn_DEF_NativeReal = {
97 "REAL", /* The ASN.1 type is still REAL */
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]),
105 #if !defined(ASN_DISABLE_OER_SUPPORT)
107 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
108 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
110 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
111 asn_generic_no_constraint
113 0, 0, /* No members */
118 NativeReal_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
122 double a = NativeReal__get_double(td, aptr);
123 double b = NativeReal__get_double(td, bptr);
125 /* NaN sorted above everything else */
132 } else if(asn_isnan(b)) {
135 /* Value comparison. */
151 NativeReal_free(const asn_TYPE_descriptor_t *td, void *ptr,
152 enum asn_struct_free_method method) {
156 ASN_DEBUG("Freeing %s as REAL (%d, %p, Native)",
157 td->name, method, ptr);
160 case ASFM_FREE_EVERYTHING:
163 case ASFM_FREE_UNDERLYING:
165 case ASFM_FREE_UNDERLYING_AND_RESET: {
166 const asn_NativeReal_specifics_t *specs;
168 specs = (const asn_NativeReal_specifics_t *)td->specifics;
169 float_size = specs ? specs->float_size : sizeof(double);
170 memset(ptr, 0, float_size);
176 * Local helper functions.
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);
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;
192 return *(const double *)ptr;
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);
201 if(!(native = *sptr)) {
202 native = (*sptr = CALLOC(1, float_size));
208 if(float_size == sizeof(float)) {
209 if(asn_double2float(d, (float *)native)) {
213 *(double *)native = d;