blob: dc8de2672666d38e640aa7b5671cfd34332c193a [file] [log] [blame]
Lev Walkin41ba1f22004-09-14 12:46:35 +00001#define EMIT_ASN_DEBUG 1
Lev Walkin41ba1f22004-09-14 12:46:35 +00002#include <REAL.c>
Lev Walkinb2cb57c2004-10-21 12:23:47 +00003#include <asn_codecs_prim.c>
Lev Walkin41ba1f22004-09-14 12:46:35 +00004#include <ber_decoder.c>
5#include <ber_tlv_length.c>
6#include <ber_tlv_tag.c>
7#include <der_encoder.c>
Lev Walkinb2cb57c2004-10-21 12:23:47 +00008#include <xer_decoder.c>
9#include <xer_support.c>
Lev Walkin5f560912004-10-21 13:37:57 +000010#include <xer_encoder.c>
Lev Walkin41ba1f22004-09-14 12:46:35 +000011#include <constraints.c>
12
Lev Walkined465432004-09-27 20:52:36 +000013static char reconstructed[2][512];
14static int reconstr_lens[2];
15
16static int
17callback(const void *buffer, size_t size, void *app_key) {
18 char *buf = reconstructed[app_key ? 1 : 0];
19 int *len = &reconstr_lens[app_key ? 1 : 0];
20
21 if(*len + size >= sizeof(reconstructed[0]))
22 return -1;
23
24 memcpy(buf + *len, buffer, size);
25 *len += size;
26
27 return 0;
28}
29
Lev Walkin41ba1f22004-09-14 12:46:35 +000030static void
Lev Walkined465432004-09-27 20:52:36 +000031check_str_repr(double d, const char *sample, const char *canonical_sample) {
32 ssize_t s1, s2;
33
34 reconstr_lens[1] = reconstr_lens[0] = 0;
35
36 s1 = REAL__dump(d, 0, callback, 0);
37 assert(s1 < sizeof(reconstructed[0]));
38 assert(s1 == reconstr_lens[0]);
39 reconstructed[0][s1] = '\0';
40
41 s2 = REAL__dump(d, 1, callback, (void *)1);
42 assert(s2 < sizeof(reconstructed[1]));
43 assert(s2 == reconstr_lens[1]);
44 reconstructed[1][s2] = '\0';
45
46 if(sample) {
47 printf("Checking [%s] against [%s]\n",
48 reconstructed[0], sample);
49 assert(!strcmp(reconstructed[0], sample));
50 }
51 if(canonical_sample) {
52 printf("Checking [%s] against [%s] (canonical)\n",
53 reconstructed[1], canonical_sample);
54 assert(!strcmp(reconstructed[1], canonical_sample));
55 }
56}
57
58static void
59check(REAL_t *rn, double orig_dbl, const char *sample, const char *canonical_sample) {
Lev Walkin41ba1f22004-09-14 12:46:35 +000060 double val;
61 uint8_t *p, *end;
62 int ret;
63
64 printf("double value %.12f [", orig_dbl);
65 for(p = (uint8_t *)&orig_dbl, end = p + sizeof(double); p < end ; p++)
66 printf("%02x", *p);
67 printf("] (ilogb %d)\n", ilogb(orig_dbl));
68
69 val = frexp(orig_dbl, &ret);
70 printf("frexp(%f, %d): [", val, ret);
71 for(p = (uint8_t *)&val, end = p + sizeof(double); p < end ; p++)
72 printf("%02x", *p);
73 printf("]\n");
74
Lev Walkin5e033762004-09-29 13:26:15 +000075 ret = asn_double2REAL(rn, orig_dbl);
Lev Walkin41ba1f22004-09-14 12:46:35 +000076 assert(ret == 0);
77
78 printf("converted into [");
79 for(p = rn->buf, end = p + rn->size; p < end; p++)
80 printf("%02x", *p);
Lev Walkin2a789d92004-09-27 21:36:59 +000081 printf("]: %d\n", rn->size);
Lev Walkin41ba1f22004-09-14 12:46:35 +000082
Lev Walkin5e033762004-09-29 13:26:15 +000083 ret = asn_REAL2double(rn, &val);
Lev Walkin41ba1f22004-09-14 12:46:35 +000084 assert(ret == 0);
85
86 printf("and back to double: [");
87 for(p = (uint8_t *)&val, end = p + sizeof(double); p < end ; p++)
88 printf("%02x", *p);
89 printf("] (ilogb %d)\n", ilogb(val));
90
Lev Walkin1aea6982004-10-26 09:35:25 +000091 printf("%.12f vs %.12f\n", val, orig_dbl);
92 assert((isnan(orig_dbl) && isnan(val)) || val == orig_dbl);
Lev Walkin41ba1f22004-09-14 12:46:35 +000093 printf("OK\n");
Lev Walkined465432004-09-27 20:52:36 +000094
95 check_str_repr(val, sample, canonical_sample);
Lev Walkin41ba1f22004-09-14 12:46:35 +000096}
97
98uint8_t buf_1_0[] = { 0x80, 0xcc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
99uint8_t buf_1_1[] = { 0x80, 0xcc, 0x11, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a };
100uint8_t buf_3_14[] = { 0x80, 0xcd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f };
Lev Walkin1aea6982004-10-26 09:35:25 +0000101/* These ones are very interesting! They check mantissa overflow! */
Lev Walkined465432004-09-27 20:52:36 +0000102uint8_t buf_mo1[] = { 0xC0, 0xc5, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3};
Lev Walkin41ba1f22004-09-14 12:46:35 +0000103uint8_t buf_mo2[] = { 0x80, 0xbd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3,2};
104
105static void
Lev Walkined465432004-09-27 20:52:36 +0000106check_buf(uint8_t *buf, size_t bufsize, double verify, const char *sample, const char *canonical_sample) {
Lev Walkin41ba1f22004-09-14 12:46:35 +0000107 REAL_t rn;
108 double val;
109 uint8_t *p, *end;
110 int ret;
111
112 printf("verify double value %.12f [", verify);
113 for(p = (uint8_t *)&verify, end = p + sizeof(double); p < end ; p++)
114 printf("%02x", *p);
115 printf("] (ilogb %d)\n", ilogb(verify));
116
117 rn.buf = 0;
118 rn.size = 0;
119
Lev Walkin5e033762004-09-29 13:26:15 +0000120 ret = asn_double2REAL(&rn, verify);
Lev Walkin41ba1f22004-09-14 12:46:35 +0000121 assert(ret == 0);
122
123 printf("canonical DER: [");
124 for(p = rn.buf, end = p + rn.size; p < end; p++)
125 printf("%02x", *p);
126 printf("]\n");
127
128 rn.buf = buf;
129 rn.size = bufsize;
130
131 printf("received as: [");
132 for(p = rn.buf, end = p + rn.size; p < end; p++)
133 printf("%02x", *p);
134 printf("]\n");
135
Lev Walkin5e033762004-09-29 13:26:15 +0000136 ret = asn_REAL2double(&rn, &val);
Lev Walkin41ba1f22004-09-14 12:46:35 +0000137 assert(ret == 0);
138
139 printf("%.12f vs %.12f\n", verify, val);
140
141 assert(val == verify);
Lev Walkined465432004-09-27 20:52:36 +0000142
143 check_str_repr(val, sample, canonical_sample);
Lev Walkin41ba1f22004-09-14 12:46:35 +0000144}
145
Lev Walkin5f560912004-10-21 13:37:57 +0000146static void
147check_xer(int fuzzy, double orig_value) {
148 asn_enc_rval_t er;
149 asn_dec_rval_t rc;
150 REAL_t st;
151 REAL_t *newst0 = 0;
152 REAL_t *newst1 = 0;
153 double value0, value1;
154 int ret;
155
156 memset(&st, 0, sizeof(st));
157 ret = asn_double2REAL(&st, orig_value);
158 assert(ret == 0);
159
160 reconstr_lens[0] = 0;
161 reconstr_lens[1] = 0;
162 er = xer_encode(&asn_DEF_REAL, &st,
163 XER_F_BASIC, callback, 0);
164 assert(er.encoded == reconstr_lens[0]);
165 er = xer_encode(&asn_DEF_REAL, &st,
166 XER_F_CANONICAL, callback, (void *)1);
167 assert(er.encoded == reconstr_lens[1]);
168 reconstructed[0][reconstr_lens[0]] = 0;
169 reconstructed[1][reconstr_lens[1]] = 0;
170
171 printf("%f vs (%d)[%s] & (%d)%s",
172 orig_value,
173 reconstr_lens[1], reconstructed[1],
174 reconstr_lens[0], reconstructed[0]
175 );
176
177 rc = xer_decode(0, &asn_DEF_REAL, (void **)&newst0,
178 reconstructed[0], reconstr_lens[0]);
179 assert(rc.code == RC_OK);
180 assert(rc.consumed < reconstr_lens[0]);
181
182 rc = xer_decode(0, &asn_DEF_REAL, (void **)&newst1,
183 reconstructed[1], reconstr_lens[1]);
184 assert(rc.code == RC_OK);
185 assert(rc.consumed == reconstr_lens[1]);
186
187 ret = asn_REAL2double(newst0, &value0);
188 assert(ret == 0);
189 ret = asn_REAL2double(newst1, &value1);
190 assert(ret == 0);
191
Lev Walkin1aea6982004-10-26 09:35:25 +0000192 assert((isnan(value0) && isnan(orig_value))
193 || value0 == orig_value
Lev Walkin5f560912004-10-21 13:37:57 +0000194 || fuzzy);
Lev Walkin1aea6982004-10-26 09:35:25 +0000195 assert((isnan(value1) && isnan(orig_value))
196 || value1 == orig_value);
Lev Walkin5f560912004-10-21 13:37:57 +0000197
198 assert(newst0->size == st.size || fuzzy);
199 assert(newst1->size == st.size);
200 assert(fuzzy || memcmp(newst0->buf, st.buf, st.size) == 0);
201 assert(memcmp(newst1->buf, st.buf, st.size) == 0);
202}
203
Lev Walkin41ba1f22004-09-14 12:46:35 +0000204int
205main() {
206 REAL_t rn;
Lev Walkinc51e7d62004-09-27 22:16:18 +0000207 static const double zero = 0.0;
Lev Walkin41ba1f22004-09-14 12:46:35 +0000208
209 memset(&rn, 0, sizeof(rn));
210
Lev Walkined465432004-09-27 20:52:36 +0000211 check(&rn, 0.0, "0", "0");
212 check(&rn, -0.0, "-0", "-0"); /* minus-zero */
Lev Walkinc51e7d62004-09-27 22:16:18 +0000213 check(&rn, zero/zero, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>");
214 check(&rn, 1.0/zero, "<PLUS-INFINITY/>", "<PLUS-INFINITY/>");
215 check(&rn, -1.0/zero, "<MINUS-INFINITY/>", "<MINUS-INFINITY/>");
Lev Walkined465432004-09-27 20:52:36 +0000216 check(&rn, 1.0, "1.0", "1.0E0");
217 check(&rn, -1.0, "-1.0", "-1.0E0");
218 check(&rn, 1.5, "1.5", "1.5E0");
219 check(&rn, 0.1, "0.1", "1.0E-1");
220 check(&rn, 0.33333, "0.33333", "3.3333E-1");
221 check(&rn, 2, "2.0", "2.0E0");
222 check(&rn, 2.1, "2.1", "2.1E0");
223 check(&rn, 3, "3.0", "3.0E0");
224 check(&rn, 3.1, "3.1", "3.1E0");
225 check(&rn, 3.14, "3.14", "3.14E0");
226 check(&rn, 3.1415, "3.1415", "3.1415E0");
227 check(&rn, 3.141592, "3.141592", "3.141592E0");
228 check(&rn, 3.14159265, "3.14159265", "3.14159265E0");
229 check(&rn, -3.14159265, "-3.14159265", "-3.14159265E0");
230 check(&rn, 14159265.0, "14159265.0", "1.4159265E7");
231 check(&rn, -123456789123456789.0, "-123456789123456784.0", "-1.234567891234568E17");
232 check(&rn, 0.00000000001, "0.0", "9.999999999999999E-12");
233 check(&rn, 0.00000000002, "0.0", "2.0E-11");
234 check(&rn, 0.00000000009, "0.0", "9.0E-11");
235 check(&rn, 0.0000000000000000000001, "0.0", "1.0E-22");
236 check(&rn, 0.000000000000000000000000000001, "0.0", "1.0E-30"); /* proved 2B a problem */
237 check(&rn,-0.000000000000000000000000000001, "-0.0", "-1.0E-30"); /* proved 2B a problem */
238 check(&rn, 0.0000000000010000000001000000000001, 0, 0);
239 check(&rn, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
240 check(&rn, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
241 check(&rn,-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
242 check(&rn,-3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
243 check(&rn, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
244 check(&rn, -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
Lev Walkin41ba1f22004-09-14 12:46:35 +0000245
Lev Walkined465432004-09-27 20:52:36 +0000246 check_buf(buf_1_0, sizeof(buf_1_0), 1.0, "1.0", "1.0E0");
247 check_buf(buf_1_1, sizeof(buf_1_1), 1.1, "1.1", "1.1E0");
248 check_buf(buf_3_14, sizeof(buf_3_14), 3.14, "3.14", "3.14E0");
249 check_buf(buf_mo1, sizeof(buf_mo1), -3.14, "-3.14", "-3.14E0");
250 check_buf(buf_mo2, sizeof(buf_mo2), 3.14, "3.14", "3.14E0");
Lev Walkin41ba1f22004-09-14 12:46:35 +0000251
Lev Walkin5f560912004-10-21 13:37:57 +0000252
Lev Walkin1aea6982004-10-26 09:35:25 +0000253#ifdef NAN
254 check_xer(0, NAN); /* "<NOT-A-NUMBER/>" */
255#else
Lev Walkin5f560912004-10-21 13:37:57 +0000256 check_xer(0, zero/zero); /* "<NOT-A-NUMBER/>" */
Lev Walkin1aea6982004-10-26 09:35:25 +0000257#endif
258#ifdef INFINITY
259 check_xer(0, INFINITY); /* "<PLUS-INFINITY/>" */
260 check_xer(0, -INFINITY); /* "<MINUS-INFINITY/>" */
261#else
Lev Walkin5f560912004-10-21 13:37:57 +0000262 check_xer(0, 1.0/zero); /* "<PLUS-INFINITY/>" */
263 check_xer(0, -1.0/zero); /* "<MINUS-INFINITY/>" */
Lev Walkin1aea6982004-10-26 09:35:25 +0000264#endif
Lev Walkin5f560912004-10-21 13:37:57 +0000265 check_xer(0, 1.0);
266 check_xer(0, -1.0);
267 check_xer(0, 1.5);
268 check_xer(0, 123);
269 check_xer(1, 0.0000000000000000000001);
270 check_xer(1, -0.0000000000000000000001);
271
Lev Walkin41ba1f22004-09-14 12:46:35 +0000272 return 0;
273}