Line data Source code
1 : #define _USE_MATH_DEFINES 1
2 : #undef __STRICT_ANSI__
3 : #include <math.h>
4 : #include <stdio.h>
5 : #include <string.h>
6 : #include <pb_decode.h>
7 : #include <pb_encode.h>
8 : #include "doublemsg.pb.h"
9 : #include "unittests.h"
10 :
11 : /* This message mimics how DoubleMsg would appear on e.g. AVR. */
12 : typedef struct {
13 : float value;
14 : } FloatMsg;
15 : PB_BIND(DoubleMsg, FloatMsg, AUTO)
16 :
17 : static const double testvalues[] = {
18 : 0.0, -0.0, 0.1, -0.1,
19 : M_PI, -M_PI, 123456.789, -123456.789,
20 : #if defined(NAN) && defined(INFINITY)
21 : INFINITY, -INFINITY, NAN, INFINITY - INFINITY,
22 : #endif
23 : 1e38, -1e38, 1e39, -1e39,
24 : 1e-38, -1e-38, 1e-39, -1e-39,
25 : 3.14159e-37,-3.14159e-37, 3.14159e-43, -3.14159e-43,
26 : 1e-60, -1e-60, 1e-45, -1e-45,
27 : 0.99999999999999, -0.99999999999999, 127.999999999999, -127.999999999999
28 : };
29 :
30 : #define TESTVALUES_COUNT (sizeof(testvalues)/sizeof(testvalues[0]))
31 :
32 1 : int main()
33 : {
34 : uint8_t buf[16];
35 : size_t msglen;
36 1 : int status = 0;
37 : int i;
38 33 : for (i = 0; i < TESTVALUES_COUNT; i++)
39 : {
40 32 : double orig_double = testvalues[i];
41 32 : float expected_float = (float)orig_double;
42 32 : double expected_double = (double)expected_float;
43 :
44 32 : printf("\n---- Testcase: %f ----\n", expected_float);
45 :
46 : {
47 : /* Encode the original double */
48 32 : pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
49 32 : DoubleMsg msg = { 0.0 };
50 32 : msg.value = orig_double;
51 32 : TEST(pb_encode(&stream, &DoubleMsg_msg, &msg));
52 32 : msglen = stream.bytes_written;
53 32 : TEST(msglen == 9);
54 : }
55 :
56 : {
57 : /* Decode as float */
58 : pb_ostream_t ostream;
59 32 : pb_istream_t stream = pb_istream_from_buffer(buf, msglen);
60 32 : FloatMsg msg = { 0.0f };
61 32 : TEST(pb_decode(&stream, &FloatMsg_msg, &msg));
62 32 : TEST(memcmp(&msg.value, &expected_float, sizeof(float)) == 0);
63 :
64 : /* Re-encode */
65 32 : ostream = pb_ostream_from_buffer(buf, sizeof(buf));
66 32 : TEST(pb_encode(&ostream, &FloatMsg_msg, &msg));
67 32 : msglen = ostream.bytes_written;
68 32 : TEST(msglen == 9);
69 : }
70 :
71 : {
72 : /* Decode as double */
73 32 : pb_istream_t stream = pb_istream_from_buffer(buf, msglen);
74 32 : DoubleMsg msg = { 0.0 };
75 32 : TEST(pb_decode(&stream, &DoubleMsg_msg, &msg));
76 :
77 32 : if (isnan(expected_double))
78 : {
79 : /* Bottom bits of NAN converted to double can vary */
80 2 : TEST(isnan(msg.value));
81 : }
82 : else
83 : {
84 30 : TEST(memcmp(&msg.value, &expected_double, sizeof(double)) == 0);
85 : }
86 : }
87 : }
88 :
89 1 : return status;
90 : }
|