Coverage Report

Created: 2024-07-18 11:41

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