GDAL
cpl_json_streaming_writer.h
1/******************************************************************************
2 *
3 * Project: CPL - Common Portability Library
4 * Purpose: JSon streaming writer
5 * Author: Even Rouault, even.rouault at spatialys.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
9 *
10 * SPDX-License-Identifier: MIT
11 ****************************************************************************/
12
13#ifndef CPL_JSON_STREAMING_WRITER_H
14#define CPL_JSON_STREAMING_WRITER_H
15
17
18#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
19
20#include <cstdint>
21#include <vector>
22#include <string>
23
24#include "cpl_float.h"
25#include "cpl_port.h"
26
27class CPL_DLL CPLJSonStreamingWriter /* non final */
28{
29 public:
30 typedef void (*SerializationFuncType)(const char *pszTxt, void *pUserData);
31
32 private:
33 CPLJSonStreamingWriter(const CPLJSonStreamingWriter &) = delete;
34 CPLJSonStreamingWriter &operator=(const CPLJSonStreamingWriter &) = delete;
35
36 std::string m_osStr{};
37 SerializationFuncType m_pfnSerializationFunc = nullptr;
38 void *m_pUserData = nullptr;
39 bool m_bPretty = true;
40 std::string m_osIndent = std::string(" ");
41 std::string m_osIndentAcc{};
42 int m_nLevel = 0;
43 bool m_bNewLineEnabled = true;
44 std::string m_osTmpForSerialize{};
45 std::string m_osTmpForFormatString{};
46
47 struct State
48 {
49 bool bIsObj = false;
50 bool bFirstChild = true;
51
52 explicit State(bool bIsObjIn) : bIsObj(bIsObjIn)
53 {
54 }
55 };
56
57 std::vector<State> m_states{};
58 bool m_bWaitForValue = false;
59
60 void IncIndent();
61 void DecIndent();
62 const std::string &FormatString(const std::string_view &str);
63 void EmitCommaIfNeeded();
64
65 void Serialize(const char *pszStr, size_t nLength);
66
67 protected:
68 virtual void Serialize(const std::string_view &str);
69
70 public:
71 CPLJSonStreamingWriter(SerializationFuncType pfnSerializationFunc,
72 void *pUserData);
73 virtual ~CPLJSonStreamingWriter();
74
75 void clear();
76
77 void SetPrettyFormatting(bool bPretty)
78 {
79 m_bPretty = bPretty;
80 }
81
82 void SetIndentationSize(int nSpaces);
83
84 // cppcheck-suppress functionStatic
85 const std::string &GetString() const
86 {
87 return m_osStr;
88 }
89
90 void Add(const char *pszStr);
91 void Add(const std::string &str);
92 void Add(const std::string_view &str);
93 void Add(bool bVal);
94
95 void AddSerializedValue(const std::string_view &str);
96
97 void Add(int nVal)
98 {
99 Add(static_cast<std::int64_t>(nVal));
100 }
101
102 void Add(unsigned int nVal)
103 {
104 Add(static_cast<std::int64_t>(nVal));
105 }
106
107 void Add(std::int64_t nVal);
108 void Add(std::uint64_t nVal);
109 void Add(GFloat16 hfVal, int nPrecision = 5);
110 void Add(float fVal, int nPrecision = 9);
111 void Add(double dfVal, int nPrecision = 17);
112 void AddNull();
113
114 void StartObj();
115 void EndObj();
116 void AddObjKey(const std::string_view &key);
117
118 struct CPL_DLL ObjectContext
119 {
120 CPLJSonStreamingWriter &m_serializer;
121
122 ObjectContext(const ObjectContext &) = delete;
123 ObjectContext(ObjectContext &&) = default;
124
125 explicit inline ObjectContext(CPLJSonStreamingWriter &serializer)
126 : m_serializer(serializer)
127 {
128 m_serializer.StartObj();
129 }
130
131 ~ObjectContext()
132 {
133 m_serializer.EndObj();
134 }
135 };
136
137 inline ObjectContext MakeObjectContext()
138 {
139 return ObjectContext(*this);
140 }
141
142 void StartArray();
143 void EndArray();
144
145 struct CPL_DLL ArrayContext
146 {
147 CPLJSonStreamingWriter &m_serializer;
148 bool m_bForceSingleLine;
149 bool m_bNewLineEnabledBackup;
150
151 ArrayContext(const ArrayContext &) = delete;
152 ArrayContext(ArrayContext &&) = default;
153
154 inline explicit ArrayContext(CPLJSonStreamingWriter &serializer,
155 bool bForceSingleLine = false)
156 : m_serializer(serializer), m_bForceSingleLine(bForceSingleLine),
157 m_bNewLineEnabledBackup(serializer.GetNewLine())
158 {
159 if (m_bForceSingleLine)
160 serializer.SetNewline(false);
161 m_serializer.StartArray();
162 }
163
164 ~ArrayContext()
165 {
166 m_serializer.EndArray();
167 if (m_bForceSingleLine)
168 m_serializer.SetNewline(m_bNewLineEnabledBackup);
169 }
170 };
171
172 inline ArrayContext MakeArrayContext(bool bForceSingleLine = false)
173 {
174 return ArrayContext(*this, bForceSingleLine);
175 }
176
177 bool GetNewLine() const
178 {
179 return m_bNewLineEnabled;
180 }
181
182 void SetNewline(bool bEnabled)
183 {
184 m_bNewLineEnabled = bEnabled;
185 }
186};
187
188#endif // __cplusplus
189
191
192#endif // CPL_JSON_STREAMING_WRITER_H
Core portability definitions for CPL.