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
18#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
19
20#include <cstdint>
21#include <vector>
22#include <string>
23#include "cpl_port.h"
24
25class CPL_DLL CPLJSonStreamingWriter
26{
27 public:
28 typedef void (*SerializationFuncType)(const char *pszTxt, void *pUserData);
29
30 private:
31 CPLJSonStreamingWriter(const CPLJSonStreamingWriter &) = delete;
32 CPLJSonStreamingWriter &operator=(const CPLJSonStreamingWriter &) = delete;
33
34 std::string m_osStr{};
35 SerializationFuncType m_pfnSerializationFunc = nullptr;
36 void *m_pUserData = nullptr;
37 bool m_bPretty = true;
38 std::string m_osIndent = std::string(" ");
39 std::string m_osIndentAcc{};
40 int m_nLevel = 0;
41 bool m_bNewLineEnabled = true;
42
43 struct State
44 {
45 bool bIsObj = false;
46 bool bFirstChild = true;
47
48 explicit State(bool bIsObjIn) : bIsObj(bIsObjIn)
49 {
50 }
51 };
52
53 std::vector<State> m_states{};
54 bool m_bWaitForValue = false;
55
56 void Print(const std::string &text);
57 void IncIndent();
58 void DecIndent();
59 static std::string FormatString(const std::string &str);
60 void EmitCommaIfNeeded();
61
62 public:
63 CPLJSonStreamingWriter(SerializationFuncType pfnSerializationFunc,
64 void *pUserData);
65 ~CPLJSonStreamingWriter();
66
67 void SetPrettyFormatting(bool bPretty)
68 {
69 m_bPretty = bPretty;
70 }
71
72 void SetIndentationSize(int nSpaces);
73
74 // cppcheck-suppress functionStatic
75 const std::string &GetString() const
76 {
77 return m_osStr;
78 }
79
80 void Add(const std::string &str);
81 void Add(const char *pszStr);
82 void Add(bool bVal);
83
84 void Add(int nVal)
85 {
86 Add(static_cast<std::int64_t>(nVal));
87 }
88
89 void Add(unsigned int nVal)
90 {
91 Add(static_cast<std::int64_t>(nVal));
92 }
93
94 void Add(std::int64_t nVal);
95 void Add(std::uint64_t nVal);
96 void Add(float fVal, int nPrecision = 9);
97 void Add(double dfVal, int nPrecision = 18);
98 void AddNull();
99
100 void StartObj();
101 void EndObj();
102 void AddObjKey(const std::string &key);
103
104 struct CPL_DLL ObjectContext
105 {
106 CPLJSonStreamingWriter &m_serializer;
107
108 ObjectContext(const ObjectContext &) = delete;
109 ObjectContext(ObjectContext &&) = default;
110
111 explicit inline ObjectContext(CPLJSonStreamingWriter &serializer)
112 : m_serializer(serializer)
113 {
114 m_serializer.StartObj();
115 }
116
117 ~ObjectContext()
118 {
119 m_serializer.EndObj();
120 }
121 };
122
123 inline ObjectContext MakeObjectContext()
124 {
125 return ObjectContext(*this);
126 }
127
128 void StartArray();
129 void EndArray();
130
131 struct CPL_DLL ArrayContext
132 {
133 CPLJSonStreamingWriter &m_serializer;
134 bool m_bForceSingleLine;
135 bool m_bNewLineEnabledBackup;
136
137 ArrayContext(const ArrayContext &) = delete;
138 ArrayContext(ArrayContext &&) = default;
139
140 inline explicit ArrayContext(CPLJSonStreamingWriter &serializer,
141 bool bForceSingleLine = false)
142 : m_serializer(serializer), m_bForceSingleLine(bForceSingleLine),
143 m_bNewLineEnabledBackup(serializer.GetNewLine())
144 {
145 if (m_bForceSingleLine)
146 serializer.SetNewline(false);
147 m_serializer.StartArray();
148 }
149
150 ~ArrayContext()
151 {
152 m_serializer.EndArray();
153 if (m_bForceSingleLine)
154 m_serializer.SetNewline(m_bNewLineEnabledBackup);
155 }
156 };
157
158 inline ArrayContext MakeArrayContext(bool bForceSingleLine = false)
159 {
160 return ArrayContext(*this, bForceSingleLine);
161 }
162
163 bool GetNewLine() const
164 {
165 return m_bNewLineEnabled;
166 }
167
168 void SetNewline(bool bEnabled)
169 {
170 m_bNewLineEnabled = bEnabled;
171 }
172};
173
174#endif // __cplusplus
175
178#endif // CPL_JSON_STREAMING_WRITER_H
Core portability definitions for CPL.