GDAL
cpl_json.h
Go to the documentation of this file.
1/******************************************************************************
2 * Project: Common Portability Library
3 * Purpose: Function wrapper for libjson-c access.
4 * Author: Dmitry Baryshnikov, dmitry.baryshnikov@nextgis.com
5 *
6 ******************************************************************************
7 * Copyright (c) 2017-2018 NextGIS, <info@nextgis.com>
8 *
9 * SPDX-License-Identifier: MIT
10 ****************************************************************************/
11
12#ifndef CPL_JSON_H_INCLUDED
13#define CPL_JSON_H_INCLUDED
14
15#include "cpl_progress.h"
16#include "cpl_string.h"
17
18#include <cstdint>
19#include <initializer_list>
20#include <string>
21#include <vector>
22
28
30typedef void *JSONObjectH;
31
32class CPLJSONObject;
33class CPLJSONArray;
34
35class CPLJSONObjectProxy
36{
37 CPLJSONObject &oObj;
38 const std::string osName;
39
40 public:
41 explicit inline CPLJSONObjectProxy(CPLJSONObject &oObjIn,
42 const std::string &osNameIn)
43 : oObj(oObjIn), osName(osNameIn)
44 {
45 }
46
47 template <class T> inline CPLJSONObjectProxy &operator=(const T &val);
48};
49
51
55class CPL_DLL CPLJSONObject
56{
57 friend class CPLJSONArray;
58 friend class CPLJSONDocument;
59
60 public:
64 enum class Type
65 {
66 Unknown,
67 Null,
68 Object,
69 Array,
70 Boolean,
71 String,
72 Integer,
73 Long,
74 Double
75 };
76
80 enum class PrettyFormat
81 {
82 Plain,
83 Spaced,
84 Pretty
85 };
86
87 public:
90 explicit CPLJSONObject(const std::string &osName,
91 const CPLJSONObject &oParent);
92 explicit CPLJSONObject(std::nullptr_t);
93 explicit CPLJSONObject(const std::string &osVal);
94 explicit CPLJSONObject(const char *pszValue);
95 explicit CPLJSONObject(bool bVal);
96 explicit CPLJSONObject(int nVal);
97 explicit CPLJSONObject(int64_t nVal);
98 explicit CPLJSONObject(uint64_t nVal);
99 explicit CPLJSONObject(double dfVal);
101 CPLJSONObject(const CPLJSONObject &other);
103 CPLJSONObject &operator=(const CPLJSONObject &other);
104 CPLJSONObject &operator=(CPLJSONObject &&other);
105 CPLJSONObject &operator=(CPLJSONArray &&other);
106
107 // This method is not thread-safe
108 CPLJSONObject Clone() const;
109
110 private:
111 explicit CPLJSONObject(const std::string &osName, JSONObjectH poJsonObject);
113
114 public:
115 // setters
116 void Add(const std::string &osName, const std::string &osValue);
117 void Add(const std::string &osName, const char *pszValue);
118 void Add(const std::string &osName, double dfValue);
119 void Add(const std::string &osName, int nValue);
120 void Add(const std::string &osName, GInt64 nValue);
121 void Add(const std::string &osName, uint64_t nValue);
122 void Add(const std::string &osName, const CPLJSONArray &oValue);
123 void Add(const std::string &osName, const CPLJSONObject &oValue);
124 void AddNoSplitName(const std::string &osName, const CPLJSONObject &oValue);
125 void Add(const std::string &osName, bool bValue);
126 void AddNull(const std::string &osName);
127
129 template <class T> void Set(const std::string &osName, const T &val)
130 {
131 Delete(osName);
132 Add(osName, val);
133 }
134
135 void SetNull(const std::string &osName);
136
137 CPLJSONObject operator[](const std::string &osName);
138
140
141// GCC 9.4 seems to be confused by the template and doesn't realize it
142// returns *this
143#ifdef __GNUC__
144#pragma GCC diagnostic push
145#pragma GCC diagnostic ignored "-Weffc++"
146#endif
147 template <class T> inline CPLJSONObject &operator=(const T &val)
148 {
149 CPLAssert(!m_osKeyForSet.empty());
150 std::string osKeyForSet = m_osKeyForSet;
151 m_osKeyForSet.clear();
152 Set(osKeyForSet, val);
153 return *this;
154 }
155#ifdef __GNUC__
156#pragma GCC diagnostic pop
157#endif
158
159 template <class T>
160 inline CPLJSONObject &operator=(std::initializer_list<T> list);
161
162 JSONObjectH GetInternalHandle() const
163 {
164 return m_poJsonObject;
165 }
166
168
169 // getters
170 std::string GetString(const std::string &osName,
171 const std::string &osDefault = "") const;
172 double GetDouble(const std::string &osName, double dfDefault = 0.0) const;
173 int GetInteger(const std::string &osName, int nDefault = 0) const;
174 GInt64 GetLong(const std::string &osName, GInt64 nDefault = 0) const;
175 bool GetBool(const std::string &osName, bool bDefault = false) const;
176 std::string ToString(const std::string &osDefault = "") const;
177 double ToDouble(double dfDefault = 0.0) const;
178 int ToInteger(int nDefault = 0) const;
179 GInt64 ToLong(GInt64 nDefault = 0) const;
180 bool ToBool(bool bDefault = false) const;
181 CPLJSONArray ToArray() const;
182 std::string Format(PrettyFormat eFormat) const;
183
184 //
185 void Delete(const std::string &osName);
186 void DeleteNoSplitName(const std::string &osName);
187 CPLJSONArray GetArray(const std::string &osName) const;
188 CPLJSONObject GetObj(const std::string &osName) const;
189 CPLJSONObject operator[](const std::string &osName) const;
190 Type GetType() const;
191
193 std::string GetName() const
194 {
195 return m_osKey;
196 }
197
199
200 std::vector<CPLJSONObject> GetChildren() const;
201 bool IsValid() const;
202 void Deinit();
203
204 protected:
206 CPLJSONObject GetObjectByPath(const std::string &osPath,
207 std::string &osName) const;
209
210 private:
211 JSONObjectH m_poJsonObject = nullptr;
212 std::string m_osKey{};
213 std::string m_osKeyForSet{};
214};
215
219class CPL_DLL CPLJSONArray : public CPLJSONObject
220{
221 friend class CPLJSONObject;
222 friend class CPLJSONDocument;
223
224 public:
226 CPLJSONArray();
227 explicit CPLJSONArray(const std::string &osName);
228 explicit CPLJSONArray(const CPLJSONObject &other);
229
231 template <class T> static CPLJSONArray Build(std::initializer_list<T> list)
232 {
233 CPLJSONArray oArray;
234 for (const auto &val : list)
235 oArray.Add(val);
236 return oArray;
237 }
238
239 private:
240 explicit CPLJSONArray(const std::string &osName, JSONObjectH poJsonObject);
241
242 class CPL_DLL ConstIterator
243 {
244 const CPLJSONArray &m_oSelf;
245 int m_nIdx;
246 mutable CPLJSONObject m_oObj{};
247
248 public:
249 ConstIterator(const CPLJSONArray &oSelf, bool bStart)
250 : m_oSelf(oSelf), m_nIdx(bStart ? 0 : oSelf.Size())
251 {
252 }
253
254 ~ConstIterator() = default;
255
256 CPLJSONObject &operator*() const
257 {
258 m_oObj = m_oSelf[m_nIdx];
259 return m_oObj;
260 }
261
262 ConstIterator &operator++()
263 {
264 m_nIdx++;
265 return *this;
266 }
267
268 bool operator==(const ConstIterator &it) const
269 {
270 return m_nIdx == it.m_nIdx;
271 }
272
273 bool operator!=(const ConstIterator &it) const
274 {
275 return m_nIdx != it.m_nIdx;
276 }
277 };
278
280 public:
281 int Size() const;
282 void AddNull();
283 void Add(const CPLJSONObject &oValue);
284 void Add(const std::string &osValue);
285 void Add(const char *pszValue);
286 void Add(double dfValue);
287 void Add(int nValue);
288 void Add(GInt64 nValue);
289 void Add(uint64_t nValue);
290 void Add(bool bValue);
291
292 CPLJSONObject operator[](int nIndex);
293 const CPLJSONObject operator[](int nIndex) const;
294
296 ConstIterator begin() const
297 {
298 return ConstIterator(*this, true);
299 }
300
302 ConstIterator end() const
303 {
304 return ConstIterator(*this, false);
305 }
306};
307
311class CPL_DLL CPLJSONDocument
312{
313 public:
317 CPLJSONDocument(const CPLJSONDocument &other);
318 CPLJSONDocument &operator=(const CPLJSONDocument &other);
320 CPLJSONDocument &operator=(CPLJSONDocument &&other);
322
323 bool Save(const std::string &osPath) const;
324 std::string SaveAsString() const;
325
327 const CPLJSONObject GetRoot() const;
328 void SetRoot(const CPLJSONObject &oRoot);
329 bool Load(const std::string &osPath);
330 bool LoadMemory(const std::string &osStr);
331 bool LoadMemory(const GByte *pabyData, int nLength = -1);
332 bool LoadChunks(const std::string &osPath, size_t nChunkSize = 16384,
333 GDALProgressFunc pfnProgress = nullptr,
334 void *pProgressArg = nullptr);
335 bool LoadUrl(const std::string &osUrl, const char *const *papszOptions,
336 GDALProgressFunc pfnProgress = nullptr,
337 void *pProgressArg = nullptr);
338
339 private:
340 mutable JSONObjectH m_poRootJsonObject;
341};
342
344template <class T>
345inline CPLJSONObject &CPLJSONObject::operator=(std::initializer_list<T> list)
346{
347 return operator=(CPLJSONArray::Build(list));
348}
349
351
352CPLStringList CPLParseKeyValueJson(const char *pszJson);
353
354#endif // CPL_JSON_H_INCLUDED
The JSONArray class JSON array from JSONDocument.
Definition cpl_json.h:220
int Size() const
Get array size.
Definition cpl_json.cpp:1385
void Add(const CPLJSONObject &oValue)
Add json object to array.
Definition cpl_json.cpp:1409
void AddNull()
Add null object to array.
Definition cpl_json.cpp:1398
ConstIterator begin() const
Iterator to first element.
Definition cpl_json.h:296
CPLJSONObject operator[](int nIndex)
Get array item by index.
Definition cpl_json.cpp:1512
ConstIterator end() const
Iterator to after last element.
Definition cpl_json.h:302
The CPLJSONDocument class Wrapper class around json-c library.
Definition cpl_json.h:312
bool Load(const std::string &osPath)
Load json document from file by provided path.
Definition cpl_json.cpp:196
CPLJSONObject GetRoot()
Get json document root object.
Definition cpl_json.cpp:159
bool LoadChunks(const std::string &osPath, size_t nChunkSize=16384, GDALProgressFunc pfnProgress=nullptr, void *pProgressArg=nullptr)
Load json document from file using small chunks of data.
Definition cpl_json.cpp:292
bool Save(const std::string &osPath) const
Save json document at specified path.
Definition cpl_json.cpp:113
bool LoadMemory(const std::string &osStr)
Load json document from memory buffer.
Definition cpl_json.cpp:274
void SetRoot(const CPLJSONObject &oRoot)
Set json document root object.
Definition cpl_json.cpp:182
bool LoadUrl(const std::string &osUrl, const char *const *papszOptions, GDALProgressFunc pfnProgress=nullptr, void *pProgressArg=nullptr)
Load json document from web.
Definition cpl_json.cpp:410
std::string SaveAsString() const
Return the json document as a serialized string.
Definition cpl_json.cpp:137
The CPLJSONArray class holds JSON object from CPLJSONDocument.
Definition cpl_json.h:56
void Add(const std::string &osName, const std::string &osValue)
Add new key - value pair to json object.
Definition cpl_json.cpp:620
void Delete(const std::string &osName)
Delete json object by key.
Definition cpl_json.cpp:956
Type
Json object types.
Definition cpl_json.h:65
PrettyFormat
Json object format to string options.
Definition cpl_json.h:81
void Set(const std::string &osName, const T &val)
Change value by key.
Definition cpl_json.h:129
String list class designed around our use of C "char**" string lists.
Definition cpl_string.h:454
#define CPLAssert(expr)
Assert on an expression.
Definition cpl_error.h:330
CPLStringList CPLParseKeyValueJson(const char *pszJson)
Return a string list of key/value pairs extracted from a JSON doc.
Definition cpl_json.cpp:1553
GIntBig GInt64
Signed 64 bit integer type.
Definition cpl_port.h:226
unsigned char GByte
Unsigned byte type.
Definition cpl_port.h:175
Various convenience functions for working with strings and string lists.