SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / REAL_xer.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 <REAL.h>
8
9 asn_enc_rval_t
10 REAL_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
11                 enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
12                 void *app_key) {
13     const REAL_t *st = (const REAL_t *)sptr;
14     asn_enc_rval_t er = {0,0,0};
15     double d;
16
17     (void)ilevel;
18
19     if(!st || !st->buf || asn_REAL2double(st, &d))
20         ASN__ENCODE_FAILED;
21
22     er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key);
23     if(er.encoded < 0) ASN__ENCODE_FAILED;
24
25     ASN__ENCODED_OK(er);
26 }
27
28 /*
29  * Decode the chunk of XML text encoding REAL.
30  */
31 static enum xer_pbd_rval
32 REAL__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
33                       const void *chunk_buf, size_t chunk_size) {
34     REAL_t *st = (REAL_t *)sptr;
35     double value;
36     const char *xerdata = (const char *)chunk_buf;
37     char *endptr = 0;
38     char *b;
39
40     (void)td;
41
42     if(!chunk_size) return XPBD_BROKEN_ENCODING;
43
44     /*
45      * Decode an XMLSpecialRealValue: <MINUS-INFINITY>, etc.
46      */
47     if(xerdata[0] == 0x3c /* '<' */) {
48         size_t i;
49         for(i = 0; i < sizeof(specialRealValue) / sizeof(specialRealValue[0]); i++) {
50             struct specialRealValue_s *srv = &specialRealValue[i];
51             double dv;
52
53             if(srv->length != chunk_size
54             || memcmp(srv->string, chunk_buf, chunk_size))
55                 continue;
56
57             /*
58              * It could've been done using
59              * (double)srv->dv / real_zero,
60              * but it summons fp exception on some platforms.
61              */
62             switch(srv->dv) {
63             case -1: dv = - INFINITY; break;
64             case 0: dv = NAN;   break;
65             case 1: dv = INFINITY;      break;
66             default: return XPBD_SYSTEM_FAILURE;
67             }
68
69             if(asn_double2REAL(st, dv))
70                 return XPBD_SYSTEM_FAILURE;
71
72             return XPBD_BODY_CONSUMED;
73         }
74         ASN_DEBUG("Unknown XMLSpecialRealValue");
75         return XPBD_BROKEN_ENCODING;
76     }
77
78     /*
79      * Copy chunk into the nul-terminated string, and run strtod.
80      */
81     b = (char *)MALLOC(chunk_size + 1);
82     if(!b) return XPBD_SYSTEM_FAILURE;
83     memcpy(b, chunk_buf, chunk_size);
84     b[chunk_size] = 0;  /* nul-terminate */
85
86     value = strtod(b, &endptr);
87     FREEMEM(b);
88     if(endptr == b) return XPBD_BROKEN_ENCODING;
89
90     if(asn_double2REAL(st, value))
91         return XPBD_SYSTEM_FAILURE;
92
93     return XPBD_BODY_CONSUMED;
94 }
95
96 asn_dec_rval_t
97 REAL_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
98                 const asn_TYPE_descriptor_t *td, void **sptr,
99                 const char *opt_mname, const void *buf_ptr, size_t size) {
100     return xer_decode_primitive(opt_codec_ctx, td,
101                                 sptr, sizeof(REAL_t), opt_mname,
102                                 buf_ptr, size, REAL__xer_body_decode);
103 }