src/zserio/JsonEncoder.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include <array> |
2 | | #include <cmath> |
3 | | #include <iomanip> |
4 | | |
5 | | #include "zserio/JsonEncoder.h" |
6 | | |
7 | | namespace zserio |
8 | | { |
9 | | |
10 | | void JsonEncoder::encodeNull(std::ostream& stream) |
11 | 2 | { |
12 | 2 | stream << "null"; |
13 | 2 | } |
14 | | |
15 | | void JsonEncoder::encodeBool(std::ostream& stream, bool value) |
16 | 3 | { |
17 | 3 | stream << std::boolalpha << value << std::noboolalpha; |
18 | 3 | } |
19 | | |
20 | | void JsonEncoder::encodeFloatingPoint(std::ostream& stream, double value) |
21 | 13 | { |
22 | 13 | if (std::isnan(value)) |
23 | 1 | { |
24 | 1 | stream << "NaN"; |
25 | 1 | } |
26 | 12 | else if (std::isinf(value)) |
27 | 2 | { |
28 | 2 | if (value < 0.0) |
29 | 1 | { |
30 | 1 | stream << "-"; |
31 | 1 | } |
32 | 2 | stream << "Infinity"; |
33 | 2 | } |
34 | 10 | else |
35 | 10 | { |
36 | 10 | double intPart = 1e16; |
37 | 10 | const double fractPart = std::modf(value, &intPart); |
38 | | // trying to get closer to behavior of Python |
39 | 10 | if (fractPart == 0.0 && intPart > -1e165 && intPart < 1e164 ) |
40 | 3 | { |
41 | 3 | stream << std::fixed << std::setprecision(1) << value << std::defaultfloat; |
42 | 3 | } |
43 | 7 | else |
44 | 7 | { |
45 | 7 | stream << std::setprecision(15) << value << std::defaultfloat; |
46 | 7 | } |
47 | 10 | } |
48 | 13 | } |
49 | | |
50 | | void JsonEncoder::encodeString(std::ostream& stream, StringView value) |
51 | 159 | { |
52 | 159 | static const std::array<char, 17> HEX = {"0123456789abcdef"}; |
53 | | |
54 | 159 | stream.put('"'); |
55 | 159 | for (char character : value) |
56 | 1.07k | { |
57 | 1.07k | switch (character) |
58 | 1.07k | { |
59 | 2 | case '\\': |
60 | 4 | case '"': |
61 | 4 | stream.put('\\'); |
62 | 4 | stream.put(character); |
63 | 4 | break; |
64 | 1 | case '\b': |
65 | 1 | stream.put('\\'); |
66 | 1 | stream.put('b'); |
67 | 1 | break; |
68 | 1 | case '\f': |
69 | 1 | stream.put('\\'); |
70 | 1 | stream.put('f'); |
71 | 1 | break; |
72 | 2 | case '\n': |
73 | 2 | stream.put('\\'); |
74 | 2 | stream.put('n'); |
75 | 2 | break; |
76 | 1 | case '\r': |
77 | 1 | stream.put('\\'); |
78 | 1 | stream.put('r'); |
79 | 1 | break; |
80 | 2 | case '\t': |
81 | 2 | stream.put('\\'); |
82 | 2 | stream.put('t'); |
83 | 2 | break; |
84 | 1.06k | default: |
85 | 1.06k | if (static_cast<uint8_t>(character) <= 0x1F) |
86 | 1 | { |
87 | 1 | stream.put('\\'); |
88 | 1 | stream.put('u'); |
89 | 1 | stream.put('0'); |
90 | 1 | stream.put('0'); |
91 | 1 | stream.put(HEX[static_cast<uint8_t>(static_cast<uint8_t>(character) >> 4U) & 0xFU]); |
92 | 1 | stream.put(HEX[static_cast<uint8_t>(character) & 0xFU]); |
93 | 1 | } |
94 | 1.05k | else |
95 | 1.05k | { |
96 | 1.05k | stream.put(character); |
97 | 1.05k | } |
98 | 1.06k | break; |
99 | 1.07k | } |
100 | 1.07k | } |
101 | 159 | stream.put('"'); |
102 | 159 | } |
103 | | |
104 | | } // namespace zserio |