tdf#143148 Use pragma once instead of include guards
[LibreOffice.git] / include / tools / json_writer.hxx
blob2977f7f8c23171a5f94921821b1d889223878201
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.
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
11 #include <sal/config.h>
13 #include <tools/toolsdllapi.h>
14 #include <rtl/string.hxx>
15 #include <rtl/ustring.hxx>
17 #include <string_view>
19 /** Simple JSON encoder designed specifically for LibreOfficeKit purposes.
21 * (1) Minimal allocations/re-allocations/copying
22 * (2) Small/simple JSON documents
23 * (3) ascii property names
25 namespace tools
27 class TOOLS_DLLPUBLIC JsonWriter
29 // Auto-closes the node.
30 template <char closing> struct ScopedJsonWriterNode
32 JsonWriter& mrWriter;
33 ~ScopedJsonWriterNode() { mrWriter.endNode(closing); }
36 rtl_String* mpBuffer;
37 char* mPos;
38 int mSpaceAllocated;
39 int mStartNodeCount;
40 bool mbFirstFieldInNode;
41 bool mbClosed; // cannot add to it anymore
43 public:
44 JsonWriter();
45 ~JsonWriter();
47 [[nodiscard]] ScopedJsonWriterNode<'}'> startNode(std::string_view nodeName);
48 [[nodiscard]] ScopedJsonWriterNode<']'> startArray(std::string_view nodeName);
49 [[nodiscard]] ScopedJsonWriterNode<']'> startAnonArray();
50 [[nodiscard]] ScopedJsonWriterNode<'}'> startStruct();
52 void put(std::u16string_view pPropName, std::u16string_view rPropValue);
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)
59 put(pPropName, std::string_view(pPropVal));
61 template <size_t N> void put(std::string_view pPropName, const char (&pPropVal)[N])
63 put(pPropName, std::string_view(pPropVal, N));
66 template <typename N, std::enable_if_t<std::is_arithmetic_v<N>, int> = 0>
67 void put(std::string_view pPropName, N n)
69 putLiteral(pPropName, OString::number(n));
71 void put(std::string_view pPropName, bool);
73 void putSimpleValue(std::u16string_view rPropValue);
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);
78 /** Closes the tags, and returns data.
79 * After this no more document modifications may be written. */
80 OString finishAndGetAsOString();
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);
91 // overflow validation in debug mode
92 static constexpr unsigned char JSON_WRITER_DEBUG_MARKER = 0xde;
94 inline void addValidationMark()
96 #ifndef NDEBUG
97 *(mpBuffer->buffer + mSpaceAllocated - 1) = JSON_WRITER_DEBUG_MARKER;
98 #endif
101 inline void validate()
103 #ifndef NDEBUG
104 unsigned char c = *(mpBuffer->buffer + mSpaceAllocated - 1);
105 assert(c == JSON_WRITER_DEBUG_MARKER);
106 #endif
110 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */