1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <tools/toolsdllapi.h>
#include <rtl/ustring.hxx>
#include <algorithm>
namespace rtl
{
class OStringBuffer;
}
/** Simple JSON encoder designed specifically for LibreOfficeKit purposes.
*
* (1) Minimal allocations/re-allocations/copying
* (2) Small/simple JSON documents
* (3) ascii property names
*/
namespace tools
{
class ScopedJsonWriterNode;
class ScopedJsonWriterArray;
class ScopedJsonWriterStruct;
class TOOLS_DLLPUBLIC JsonWriter
{
friend class ScopedJsonWriterNode;
friend class ScopedJsonWriterArray;
friend class ScopedJsonWriterStruct;
int mSpaceAllocated;
char* mpBuffer;
int mStartNodeCount;
char* mPos;
bool mbFirstFieldInNode;
public:
JsonWriter();
~JsonWriter();
[[nodiscard]] ScopedJsonWriterNode startNode(const char*);
[[nodiscard]] ScopedJsonWriterArray startArray(const char*);
[[nodiscard]] ScopedJsonWriterStruct startStruct();
void put(const char* pPropName, const OUString& rPropValue);
void put(const char* pPropName, const OString& rPropValue);
void put(const char* pPropName, const char* pPropVal);
void put(const char* pPropName, const std::string& rPropValue)
{
put(pPropName, rPropValue.data());
}
void put(const char* pPropName, sal_uInt16 nPropVal) { put(pPropName, sal_Int64(nPropVal)); }
void put(const char* pPropName, sal_Int16 nPropVal) { put(pPropName, sal_Int64(nPropVal)); }
void put(const char* pPropName, sal_Int32 nPropVal) { put(pPropName, sal_Int64(nPropVal)); }
void put(const char* pPropName, sal_uInt32 nPropVal) { put(pPropName, sal_Int64(nPropVal)); }
void put(const char* pPropName, sal_Int64);
void put(const char* pPropName, bool);
void put(const char* pPropName, double);
/// This assumes that this data belongs at this point in the stream, and is valid, and properly encoded
void putRaw(const rtl::OStringBuffer&);
/** Hands ownership of the underlying storage buffer to the caller,
* after this no more document modifications may be written. */
char* extractData();
OString extractAsOString();
std::string extractAsStdString();
/** returns true if the current JSON data matches the string */
bool isDataEquals(const std::string&);
private:
void endNode();
void endArray();
void endStruct();
void addCommaBeforeField();
void reallocBuffer(int noMoreBytesRequired);
// this part inline to speed up the fast path
inline void ensureSpace(int noMoreBytesRequired)
{
assert(mpBuffer && "already extracted data");
int currentUsed = mPos - mpBuffer;
if (currentUsed + noMoreBytesRequired >= mSpaceAllocated)
reallocBuffer(noMoreBytesRequired);
}
};
/**
* Auto-closes the node.
*/
class ScopedJsonWriterNode
{
friend class JsonWriter;
JsonWriter& mrWriter;
ScopedJsonWriterNode(JsonWriter& rWriter)
: mrWriter(rWriter)
{
}
public:
~ScopedJsonWriterNode() { mrWriter.endNode(); }
};
/**
* Auto-closes the node.
*/
class ScopedJsonWriterArray
{
friend class JsonWriter;
JsonWriter& mrWriter;
ScopedJsonWriterArray(JsonWriter& rWriter)
: mrWriter(rWriter)
{
}
public:
~ScopedJsonWriterArray() { mrWriter.endArray(); }
};
/**
* Auto-closes the node.
*/
class ScopedJsonWriterStruct
{
friend class JsonWriter;
JsonWriter& mrWriter;
ScopedJsonWriterStruct(JsonWriter& rWriter)
: mrWriter(rWriter)
{
}
public:
~ScopedJsonWriterStruct() { mrWriter.endStruct(); }
};
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|