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 | stream << "-"; |
30 | 2 | stream << "Infinity"; |
31 | 2 | } |
32 | 10 | else |
33 | 10 | { |
34 | 10 | double intPart = 1e16; |
35 | 10 | const double fractPart = std::modf(value, &intPart); |
36 | | // trying to get closer to behavior of Python |
37 | 10 | if (fractPart == 0.0 && intPart > -1e165 && intPart < 1e164 ) |
38 | 3 | { |
39 | 3 | stream << std::fixed << std::setprecision(1) << value << std::defaultfloat; |
40 | 3 | } |
41 | 7 | else |
42 | 7 | { |
43 | 7 | stream << std::setprecision(15) << value << std::defaultfloat; |
44 | 7 | } |
45 | 10 | } |
46 | 13 | } |
47 | | |
48 | | void JsonEncoder::encodeString(std::ostream& stream, StringView value) |
49 | 159 | { |
50 | 159 | static const std::array<char, 17> HEX = {"0123456789abcdef"}; |
51 | | |
52 | 159 | stream.put('"'); |
53 | 159 | for (char character : value) |
54 | 1.07k | { |
55 | 1.07k | switch (character) |
56 | 1.07k | { |
57 | 2 | case '\\': |
58 | 4 | case '"': |
59 | 4 | stream.put('\\'); |
60 | 4 | stream.put(character); |
61 | 4 | break; |
62 | 1 | case '\b': |
63 | 1 | stream.put('\\'); |
64 | 1 | stream.put('b'); |
65 | 1 | break; |
66 | 1 | case '\f': |
67 | 1 | stream.put('\\'); |
68 | 1 | stream.put('f'); |
69 | 1 | break; |
70 | 2 | case '\n': |
71 | 2 | stream.put('\\'); |
72 | 2 | stream.put('n'); |
73 | 2 | break; |
74 | 1 | case '\r': |
75 | 1 | stream.put('\\'); |
76 | 1 | stream.put('r'); |
77 | 1 | break; |
78 | 2 | case '\t': |
79 | 2 | stream.put('\\'); |
80 | 2 | stream.put('t'); |
81 | 2 | break; |
82 | 1.06k | default: |
83 | 1.06k | if (static_cast<uint8_t>(character) <= 0x1F) |
84 | 1 | { |
85 | 1 | stream.put('\\'); |
86 | 1 | stream.put('u'); |
87 | 1 | stream.put('0'); |
88 | 1 | stream.put('0'); |
89 | 1 | stream.put(HEX[static_cast<uint8_t>(static_cast<uint8_t>(character) >> 4U) & 0xFU]); |
90 | 1 | stream.put(HEX[static_cast<uint8_t>(character) & 0xFU]); |
91 | 1 | } |
92 | 1.05k | else |
93 | 1.05k | { |
94 | 1.05k | stream.put(character); |
95 | 1.05k | } |
96 | 1.06k | break; |
97 | 1.07k | } |
98 | 1.07k | } |
99 | 159 | stream.put('"'); |
100 | 159 | } |
101 | | |
102 | | } // namespace zserio |