2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
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,
13 const REAL_t *st = (const REAL_t *)sptr;
14 asn_enc_rval_t er = {0,0,0};
19 if(!st || !st->buf || asn_REAL2double(st, &d))
22 er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key);
23 if(er.encoded < 0) ASN__ENCODE_FAILED;
29 * Decode the chunk of XML text encoding REAL.
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;
36 const char *xerdata = (const char *)chunk_buf;
42 if(!chunk_size) return XPBD_BROKEN_ENCODING;
45 * Decode an XMLSpecialRealValue: <MINUS-INFINITY>, etc.
47 if(xerdata[0] == 0x3c /* '<' */) {
49 for(i = 0; i < sizeof(specialRealValue) / sizeof(specialRealValue[0]); i++) {
50 struct specialRealValue_s *srv = &specialRealValue[i];
53 if(srv->length != chunk_size
54 || memcmp(srv->string, chunk_buf, chunk_size))
58 * It could've been done using
59 * (double)srv->dv / real_zero,
60 * but it summons fp exception on some platforms.
63 case -1: dv = - INFINITY; break;
64 case 0: dv = NAN; break;
65 case 1: dv = INFINITY; break;
66 default: return XPBD_SYSTEM_FAILURE;
69 if(asn_double2REAL(st, dv))
70 return XPBD_SYSTEM_FAILURE;
72 return XPBD_BODY_CONSUMED;
74 ASN_DEBUG("Unknown XMLSpecialRealValue");
75 return XPBD_BROKEN_ENCODING;
79 * Copy chunk into the nul-terminated string, and run strtod.
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 */
86 value = strtod(b, &endptr);
88 if(endptr == b) return XPBD_BROKEN_ENCODING;
90 if(asn_double2REAL(st, value))
91 return XPBD_SYSTEM_FAILURE;
93 return XPBD_BODY_CONSUMED;
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);