Coverage Report

Created: 2023-12-13 14:58

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