blob: e61a54a05df10669fa49872730da34325c25f27c [file] [log] [blame]
vlm785435b2004-09-14 12:46:35 +00001#define EMIT_ASN_DEBUG 1
vlm785435b2004-09-14 12:46:35 +00002#include <REAL.c>
vlm6678cb12004-09-26 13:10:40 +00003#include <ber_codec_prim.c>
vlm785435b2004-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>
8#include <constraints.c>
9
vlm09a4aa52004-09-27 20:52:36 +000010static char reconstructed[2][512];
11static int reconstr_lens[2];
12
13static int
14callback(const void *buffer, size_t size, void *app_key) {
15 char *buf = reconstructed[app_key ? 1 : 0];
16 int *len = &reconstr_lens[app_key ? 1 : 0];
17
18 if(*len + size >= sizeof(reconstructed[0]))
19 return -1;
20
21 memcpy(buf + *len, buffer, size);
22 *len += size;
23
24 return 0;
25}
26
vlm785435b2004-09-14 12:46:35 +000027static void
vlm09a4aa52004-09-27 20:52:36 +000028check_str_repr(double d, const char *sample, const char *canonical_sample) {
29 ssize_t s1, s2;
30
31 reconstr_lens[1] = reconstr_lens[0] = 0;
32
33 s1 = REAL__dump(d, 0, callback, 0);
34 assert(s1 < sizeof(reconstructed[0]));
35 assert(s1 == reconstr_lens[0]);
36 reconstructed[0][s1] = '\0';
37
38 s2 = REAL__dump(d, 1, callback, (void *)1);
39 assert(s2 < sizeof(reconstructed[1]));
40 assert(s2 == reconstr_lens[1]);
41 reconstructed[1][s2] = '\0';
42
43 if(sample) {
44 printf("Checking [%s] against [%s]\n",
45 reconstructed[0], sample);
46 assert(!strcmp(reconstructed[0], sample));
47 }
48 if(canonical_sample) {
49 printf("Checking [%s] against [%s] (canonical)\n",
50 reconstructed[1], canonical_sample);
51 assert(!strcmp(reconstructed[1], canonical_sample));
52 }
53}
54
55static void
56check(REAL_t *rn, double orig_dbl, const char *sample, const char *canonical_sample) {
vlm785435b2004-09-14 12:46:35 +000057 double val;
58 uint8_t *p, *end;
59 int ret;
60
61 printf("double value %.12f [", orig_dbl);
62 for(p = (uint8_t *)&orig_dbl, end = p + sizeof(double); p < end ; p++)
63 printf("%02x", *p);
64 printf("] (ilogb %d)\n", ilogb(orig_dbl));
65
66 val = frexp(orig_dbl, &ret);
67 printf("frexp(%f, %d): [", val, ret);
68 for(p = (uint8_t *)&val, end = p + sizeof(double); p < end ; p++)
69 printf("%02x", *p);
70 printf("]\n");
71
72 ret = asn1_double2REAL(rn, orig_dbl);
73 assert(ret == 0);
74
75 printf("converted into [");
76 for(p = rn->buf, end = p + rn->size; p < end; p++)
77 printf("%02x", *p);
vlm8f6ded02004-09-27 21:36:59 +000078 printf("]: %d\n", rn->size);
vlm785435b2004-09-14 12:46:35 +000079
80 ret = asn1_REAL2double(rn, &val);
81 assert(ret == 0);
82
83 printf("and back to double: [");
84 for(p = (uint8_t *)&val, end = p + sizeof(double); p < end ; p++)
85 printf("%02x", *p);
86 printf("] (ilogb %d)\n", ilogb(val));
87
88 printf("%.12f vs %.12f\n", orig_dbl, val);
vlm8f6ded02004-09-27 21:36:59 +000089 assert(orig_dbl == val || (isnan(orig_dbl) && isnan(val)));
vlm785435b2004-09-14 12:46:35 +000090 printf("OK\n");
vlm09a4aa52004-09-27 20:52:36 +000091
92 check_str_repr(val, sample, canonical_sample);
vlm785435b2004-09-14 12:46:35 +000093}
94
95uint8_t buf_1_0[] = { 0x80, 0xcc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
96uint8_t buf_1_1[] = { 0x80, 0xcc, 0x11, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a };
97uint8_t buf_3_14[] = { 0x80, 0xcd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f };
98/* These ones are very interesting! It checks mantissa overflow! */
vlm09a4aa52004-09-27 20:52:36 +000099uint8_t buf_mo1[] = { 0xC0, 0xc5, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3};
vlm785435b2004-09-14 12:46:35 +0000100uint8_t buf_mo2[] = { 0x80, 0xbd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3,2};
101
102static void
vlm09a4aa52004-09-27 20:52:36 +0000103check_buf(uint8_t *buf, size_t bufsize, double verify, const char *sample, const char *canonical_sample) {
vlm785435b2004-09-14 12:46:35 +0000104 REAL_t rn;
105 double val;
106 uint8_t *p, *end;
107 int ret;
108
109 printf("verify double value %.12f [", verify);
110 for(p = (uint8_t *)&verify, end = p + sizeof(double); p < end ; p++)
111 printf("%02x", *p);
112 printf("] (ilogb %d)\n", ilogb(verify));
113
114 rn.buf = 0;
115 rn.size = 0;
116
117 ret = asn1_double2REAL(&rn, verify);
118 assert(ret == 0);
119
120 printf("canonical DER: [");
121 for(p = rn.buf, end = p + rn.size; p < end; p++)
122 printf("%02x", *p);
123 printf("]\n");
124
125 rn.buf = buf;
126 rn.size = bufsize;
127
128 printf("received as: [");
129 for(p = rn.buf, end = p + rn.size; p < end; p++)
130 printf("%02x", *p);
131 printf("]\n");
132
133 ret = asn1_REAL2double(&rn, &val);
134 assert(ret == 0);
135
136 printf("%.12f vs %.12f\n", verify, val);
137
138 assert(val == verify);
vlm09a4aa52004-09-27 20:52:36 +0000139
140 check_str_repr(val, sample, canonical_sample);
vlm785435b2004-09-14 12:46:35 +0000141}
142
143int
144main() {
145 REAL_t rn;
vlm8f6ded02004-09-27 21:36:59 +0000146 static const double c_NaN = 0.0;
vlm785435b2004-09-14 12:46:35 +0000147
148 memset(&rn, 0, sizeof(rn));
149
vlm8f6ded02004-09-27 21:36:59 +0000150 check(&rn, c_NaN/c_NaN, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>");
vlm09a4aa52004-09-27 20:52:36 +0000151 check(&rn, 0.0, "0", "0");
152 check(&rn, -0.0, "-0", "-0"); /* minus-zero */
153 check(&rn, 1.0, "1.0", "1.0E0");
154 check(&rn, -1.0, "-1.0", "-1.0E0");
155 check(&rn, 1.5, "1.5", "1.5E0");
156 check(&rn, 0.1, "0.1", "1.0E-1");
157 check(&rn, 0.33333, "0.33333", "3.3333E-1");
158 check(&rn, 2, "2.0", "2.0E0");
159 check(&rn, 2.1, "2.1", "2.1E0");
160 check(&rn, 3, "3.0", "3.0E0");
161 check(&rn, 3.1, "3.1", "3.1E0");
162 check(&rn, 3.14, "3.14", "3.14E0");
163 check(&rn, 3.1415, "3.1415", "3.1415E0");
164 check(&rn, 3.141592, "3.141592", "3.141592E0");
165 check(&rn, 3.14159265, "3.14159265", "3.14159265E0");
166 check(&rn, -3.14159265, "-3.14159265", "-3.14159265E0");
167 check(&rn, 14159265.0, "14159265.0", "1.4159265E7");
168 check(&rn, -123456789123456789.0, "-123456789123456784.0", "-1.234567891234568E17");
169 check(&rn, 0.00000000001, "0.0", "9.999999999999999E-12");
170 check(&rn, 0.00000000002, "0.0", "2.0E-11");
171 check(&rn, 0.00000000009, "0.0", "9.0E-11");
172 check(&rn, 0.0000000000000000000001, "0.0", "1.0E-22");
173 check(&rn, 0.000000000000000000000000000001, "0.0", "1.0E-30"); /* proved 2B a problem */
174 check(&rn,-0.000000000000000000000000000001, "-0.0", "-1.0E-30"); /* proved 2B a problem */
175 check(&rn, 0.0000000000010000000001000000000001, 0, 0);
176 check(&rn, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
177 check(&rn, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
178 check(&rn,-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
179 check(&rn,-3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
180 check(&rn, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
181 check(&rn, -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
vlm785435b2004-09-14 12:46:35 +0000182
vlm09a4aa52004-09-27 20:52:36 +0000183 check_buf(buf_1_0, sizeof(buf_1_0), 1.0, "1.0", "1.0E0");
184 check_buf(buf_1_1, sizeof(buf_1_1), 1.1, "1.1", "1.1E0");
185 check_buf(buf_3_14, sizeof(buf_3_14), 3.14, "3.14", "3.14E0");
186 check_buf(buf_mo1, sizeof(buf_mo1), -3.14, "-3.14", "-3.14E0");
187 check_buf(buf_mo2, sizeof(buf_mo2), 3.14, "3.14", "3.14E0");
vlm785435b2004-09-14 12:46:35 +0000188
189 return 0;
190}