Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/tools/json_writer.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
#pragma once
10
11
#include <sal/config.h>
12
13
#include <tools/toolsdllapi.h>
14
#include <rtl/string.hxx>
15
#include <rtl/ustring.hxx>
16
17
#include <string_view>
18
19
/** Simple JSON encoder designed specifically for LibreOfficeKit purposes.
20
 *
21
 * (1) Minimal allocations/re-allocations/copying
22
 * (2) Small/simple JSON documents
23
 * (3) ascii property names
24
 */
25
namespace tools
26
{
27
class TOOLS_DLLPUBLIC JsonWriter
28
{
29
    // Auto-closes the node.
30
    template <char closing> struct ScopedJsonWriterNode
31
    {
32
        JsonWriter& mrWriter;
33
0
        ~ScopedJsonWriterNode() { mrWriter.endNode(closing); }
Unexecuted instantiation: tools::JsonWriter::ScopedJsonWriterNode<(char)125>::~ScopedJsonWriterNode()
Unexecuted instantiation: tools::JsonWriter::ScopedJsonWriterNode<(char)93>::~ScopedJsonWriterNode()
34
    };
35
36
    rtl_String* mpBuffer;
37
    char* mPos;
38
    int mSpaceAllocated;
39
    int mStartNodeCount;
40
    bool mbFirstFieldInNode;
41
    bool mbClosed; // cannot add to it anymore
42
43
public:
44
    JsonWriter();
45
    ~JsonWriter();
46
47
    [[nodiscard]] ScopedJsonWriterNode<'}'> startNode(std::string_view nodeName);
48
    [[nodiscard]] ScopedJsonWriterNode<']'> startArray(std::string_view nodeName);
49
    [[nodiscard]] ScopedJsonWriterNode<']'> startAnonArray();
50
    [[nodiscard]] ScopedJsonWriterNode<'}'> startStruct();
51
52
    void put(std::u16string_view pPropName, std::u16string_view rPropValue);
53
54
    void put(std::string_view pPropName, const OUString& rPropValue);
55
    // Assumes utf-8 property value encoding
56
    void put(std::string_view pPropName, std::string_view rPropValue);
57
    void put(std::string_view pPropName, const char* pPropVal)
58
0
    {
59
0
        put(pPropName, std::string_view(pPropVal));
60
0
    }
61
    template <size_t N> void put(std::string_view pPropName, const char (&pPropVal)[N])
62
0
    {
63
0
        put(pPropName, std::string_view(pPropVal, N));
64
0
    }
65
66
    template <typename N, std::enable_if_t<std::is_arithmetic_v<N>, int> = 0>
67
    void put(std::string_view pPropName, N n)
68
0
    {
69
0
        putLiteral(pPropName, OString::number(n));
70
0
    }
Unexecuted instantiation: _ZN5tools10JsonWriter3putIlTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putIjTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putIiTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putItTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putIsTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putIdTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putImTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
Unexecuted instantiation: _ZN5tools10JsonWriter3putIfTnNSt3__19enable_ifIXsr3stdE15is_arithmetic_vIT_EEiE4typeELi0EEEvNS2_17basic_string_viewIcNS2_11char_traitsIcEEEES4_
71
    void put(std::string_view pPropName, bool);
72
73
    void putSimpleValue(std::u16string_view rPropValue);
74
75
    /// This assumes that this data belongs at this point in the stream, and is valid, and properly encoded
76
    void putRaw(std::string_view);
77
78
    /** Closes the tags, and returns data.
79
     * After this no more document modifications may be written. */
80
    OString finishAndGetAsOString();
81
82
private:
83
    void endNode(char closing);
84
    void addCommaBeforeField();
85
    void writeEscapedOUString(std::u16string_view rPropVal);
86
    void closeDocument();
87
    void ensureSpace(int noMoreBytesRequired);
88
    void ensureSpaceAndWriteNameColon(std::string_view name, int valSize);
89
    void putLiteral(std::string_view propName, std::string_view propValue);
90
91
    // overflow validation in debug mode
92
    static constexpr unsigned char JSON_WRITER_DEBUG_MARKER = 0xde;
93
94
    inline void addValidationMark()
95
0
    {
96
#ifndef NDEBUG
97
        *(mpBuffer->buffer + mSpaceAllocated - 1) = JSON_WRITER_DEBUG_MARKER;
98
#endif
99
0
    }
100
101
    inline void validate()
102
0
    {
103
#ifndef NDEBUG
104
        unsigned char c = *(mpBuffer->buffer + mSpaceAllocated - 1);
105
        assert(c == JSON_WRITER_DEBUG_MARKER);
106
#endif
107
0
    }
108
};
109
}
110
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */