GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/zserio/JsonEncoder.cpp Lines: 52 52 100.0 %
Date: 2023-12-13 14:51:09 Branches: 30 37 81.1 %

Line Branch Exec Source
1
#include <iomanip>
2
#include <cmath>
3
#include <array>
4
5
#include "zserio/JsonEncoder.h"
6
7
namespace zserio
8
{
9
10
2
void JsonEncoder::encodeNull(std::ostream& os)
11
{
12
2
    os << "null";
13
2
}
14
15
3
void JsonEncoder::encodeBool(std::ostream& os, bool value)
16
{
17
3
    os << std::boolalpha << value << std::noboolalpha;
18
3
}
19
20
13
void JsonEncoder::encodeFloatingPoint(std::ostream& os, double value)
21
{
22
13
    if (std::isnan(value))
23
    {
24
1
        os << "NaN";
25
    }
26
12
    else if (std::isinf(value))
27
    {
28
2
        if (value < 0.0)
29
1
            os << "-";
30
2
        os << "Infinity";
31
    }
32
    else
33
    {
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 > -1e16 && intPart < 1e16)
38
        {
39


3
            os << std::fixed << std::setprecision(1) << value << std::defaultfloat;
40
        }
41
        else
42
        {
43

7
            os << std::setprecision(15) << value << std::defaultfloat;
44
        }
45
    }
46
13
}
47
48
159
void JsonEncoder::encodeString(std::ostream& os, StringView value)
49
{
50
    static const std::array<char, 17> HEX = {"0123456789abcdef"};
51
52
159
    os.put('"');
53
1230
    for (char ch : value)
54
    {
55

1071
        switch (ch)
56
        {
57
        case '\\':
58
        case '"':
59
4
            os.put('\\');
60
4
            os.put(ch);
61
4
            break;
62
        case '\b':
63
1
            os.put('\\');
64
1
            os.put('b');
65
1
            break;
66
        case '\f':
67
1
            os.put('\\');
68
1
            os.put('f');
69
1
            break;
70
        case '\n':
71
2
            os.put('\\');
72
2
            os.put('n');
73
2
            break;
74
        case '\r':
75
1
            os.put('\\');
76
1
            os.put('r');
77
1
            break;
78
        case '\t':
79
2
            os.put('\\');
80
2
            os.put('t');
81
2
            break;
82
        default:
83
1060
            if (static_cast<uint8_t>(ch) <= 0x1F)
84
            {
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
            }
92
            else
93
            {
94
1059
                os.put(ch);
95
            }
96
1060
            break;
97
        }
98
    }
99
159
    os.put('"');
100
159
}
101
102
} // namespace zserio