Line data Source code
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 <string>
20 : #include <vector>
21 :
22 : /**
23 : * \file cpl_json.h
24 : *
25 : * Interface for read and write JSON documents
26 : */
27 :
28 : /*! @cond Doxygen_Suppress */
29 : typedef void *JSONObjectH;
30 :
31 : CPL_C_START
32 :
33 : class CPLJSONArray;
34 :
35 : /*! @endcond */
36 :
37 : /**
38 : * @brief The CPLJSONArray class holds JSON object from CPLJSONDocument
39 : */
40 : class CPL_DLL CPLJSONObject
41 : {
42 : friend class CPLJSONArray;
43 : friend class CPLJSONDocument;
44 :
45 : public:
46 : /**
47 : * Json object types
48 : */
49 : enum class Type
50 : {
51 : Unknown,
52 : Null,
53 : Object,
54 : Array,
55 : Boolean,
56 : String,
57 : Integer,
58 : Long,
59 : Double
60 : };
61 :
62 : /**
63 : * Json object format to string options
64 : */
65 : enum class PrettyFormat
66 : {
67 : Plain, ///< No extra whitespace or formatting applied
68 : Spaced, ///< Minimal whitespace inserted
69 : Pretty ///< Formatted output
70 : };
71 :
72 : public:
73 : /*! @cond Doxygen_Suppress */
74 : CPLJSONObject();
75 : explicit CPLJSONObject(const std::string &osName,
76 : const CPLJSONObject &oParent);
77 : explicit CPLJSONObject(std::nullptr_t);
78 : explicit CPLJSONObject(const std::string &osVal);
79 : explicit CPLJSONObject(const char *pszValue);
80 : explicit CPLJSONObject(bool bVal);
81 : explicit CPLJSONObject(int nVal);
82 : explicit CPLJSONObject(int64_t nVal);
83 : explicit CPLJSONObject(uint64_t nVal);
84 : explicit CPLJSONObject(double dfVal);
85 : ~CPLJSONObject();
86 : CPLJSONObject(const CPLJSONObject &other);
87 : CPLJSONObject(CPLJSONObject &&other);
88 : CPLJSONObject &operator=(const CPLJSONObject &other);
89 : CPLJSONObject &operator=(CPLJSONObject &&other);
90 :
91 : // This method is not thread-safe
92 : CPLJSONObject Clone() const;
93 :
94 : private:
95 : explicit CPLJSONObject(const std::string &osName, JSONObjectH poJsonObject);
96 : /*! @endcond */
97 :
98 : public:
99 : // setters
100 : void Add(const std::string &osName, const std::string &osValue);
101 : void Add(const std::string &osName, const char *pszValue);
102 : void Add(const std::string &osName, double dfValue);
103 : void Add(const std::string &osName, int nValue);
104 : void Add(const std::string &osName, GInt64 nValue);
105 : void Add(const std::string &osName, uint64_t nValue);
106 : void Add(const std::string &osName, const CPLJSONArray &oValue);
107 : void Add(const std::string &osName, const CPLJSONObject &oValue);
108 : void AddNoSplitName(const std::string &osName, const CPLJSONObject &oValue);
109 : void Add(const std::string &osName, bool bValue);
110 : void AddNull(const std::string &osName);
111 :
112 : void Set(const std::string &osName, const std::string &osValue);
113 : void Set(const std::string &osName, const char *pszValue);
114 : void Set(const std::string &osName, double dfValue);
115 : void Set(const std::string &osName, int nValue);
116 : void Set(const std::string &osName, GInt64 nValue);
117 : void Set(const std::string &osName, uint64_t nValue);
118 : void Set(const std::string &osName, bool bValue);
119 : void SetNull(const std::string &osName);
120 :
121 : /*! @cond Doxygen_Suppress */
122 1063486 : JSONObjectH GetInternalHandle() const
123 : {
124 1063486 : return m_poJsonObject;
125 : }
126 :
127 : /*! @endcond */
128 :
129 : // getters
130 : std::string GetString(const std::string &osName,
131 : const std::string &osDefault = "") const;
132 : double GetDouble(const std::string &osName, double dfDefault = 0.0) const;
133 : int GetInteger(const std::string &osName, int nDefault = 0) const;
134 : GInt64 GetLong(const std::string &osName, GInt64 nDefault = 0) const;
135 : bool GetBool(const std::string &osName, bool bDefault = false) const;
136 : std::string ToString(const std::string &osDefault = "") const;
137 : double ToDouble(double dfDefault = 0.0) const;
138 : int ToInteger(int nDefault = 0) const;
139 : GInt64 ToLong(GInt64 nDefault = 0) const;
140 : bool ToBool(bool bDefault = false) const;
141 : CPLJSONArray ToArray() const;
142 : std::string Format(PrettyFormat eFormat) const;
143 :
144 : //
145 : void Delete(const std::string &osName);
146 : void DeleteNoSplitName(const std::string &osName);
147 : CPLJSONArray GetArray(const std::string &osName) const;
148 : CPLJSONObject GetObj(const std::string &osName) const;
149 : CPLJSONObject operator[](const std::string &osName) const;
150 : Type GetType() const;
151 :
152 : /*! @cond Doxygen_Suppress */
153 252357 : std::string GetName() const
154 : {
155 252357 : return m_osKey;
156 : }
157 :
158 : /*! @endcond */
159 :
160 : std::vector<CPLJSONObject> GetChildren() const;
161 : bool IsValid() const;
162 : void Deinit();
163 :
164 : protected:
165 : /*! @cond Doxygen_Suppress */
166 : CPLJSONObject GetObjectByPath(const std::string &osPath,
167 : std::string &osName) const;
168 : /*! @endcond */
169 :
170 : private:
171 : JSONObjectH m_poJsonObject = nullptr;
172 : std::string m_osKey{};
173 : };
174 :
175 : /**
176 : * @brief The JSONArray class JSON array from JSONDocument
177 : */
178 : class CPL_DLL CPLJSONArray : public CPLJSONObject
179 : {
180 : friend class CPLJSONObject;
181 : friend class CPLJSONDocument;
182 :
183 : public:
184 : /*! @cond Doxygen_Suppress */
185 : CPLJSONArray();
186 : explicit CPLJSONArray(const std::string &osName);
187 : explicit CPLJSONArray(const CPLJSONObject &other);
188 :
189 : private:
190 : explicit CPLJSONArray(const std::string &osName, JSONObjectH poJsonObject);
191 :
192 : class CPL_DLL ConstIterator
193 : {
194 : const CPLJSONArray &m_oSelf;
195 : int m_nIdx;
196 : mutable CPLJSONObject m_oObj{};
197 :
198 : public:
199 40204 : ConstIterator(const CPLJSONArray &oSelf, bool bStart)
200 40204 : : m_oSelf(oSelf), m_nIdx(bStart ? 0 : oSelf.Size())
201 : {
202 40204 : }
203 :
204 40204 : ~ConstIterator() = default;
205 :
206 46210 : CPLJSONObject &operator*() const
207 : {
208 46210 : m_oObj = m_oSelf[m_nIdx];
209 46210 : return m_oObj;
210 : }
211 :
212 39838 : ConstIterator &operator++()
213 : {
214 39838 : m_nIdx++;
215 39838 : return *this;
216 : }
217 :
218 : bool operator==(const ConstIterator &it) const
219 : {
220 : return m_nIdx == it.m_nIdx;
221 : }
222 :
223 59940 : bool operator!=(const ConstIterator &it) const
224 : {
225 59940 : return m_nIdx != it.m_nIdx;
226 : }
227 : };
228 :
229 : /*! @endcond */
230 : public:
231 : int Size() const;
232 : void AddNull();
233 : void Add(const CPLJSONObject &oValue);
234 : void Add(const std::string &osValue);
235 : void Add(const char *pszValue);
236 : void Add(double dfValue);
237 : void Add(int nValue);
238 : void Add(GInt64 nValue);
239 : void Add(uint64_t nValue);
240 : void Add(bool bValue);
241 : CPLJSONObject operator[](int nIndex);
242 : const CPLJSONObject operator[](int nIndex) const;
243 :
244 : /** Iterator to first element */
245 20102 : ConstIterator begin() const
246 : {
247 20102 : return ConstIterator(*this, true);
248 : }
249 :
250 : /** Iterator to after last element */
251 20102 : ConstIterator end() const
252 : {
253 20102 : return ConstIterator(*this, false);
254 : }
255 : };
256 :
257 : /**
258 : * @brief The CPLJSONDocument class Wrapper class around json-c library
259 : */
260 : class CPL_DLL CPLJSONDocument
261 : {
262 : public:
263 : /*! @cond Doxygen_Suppress */
264 : CPLJSONDocument();
265 : ~CPLJSONDocument();
266 : CPLJSONDocument(const CPLJSONDocument &other);
267 : CPLJSONDocument &operator=(const CPLJSONDocument &other);
268 : CPLJSONDocument(CPLJSONDocument &&other);
269 : CPLJSONDocument &operator=(CPLJSONDocument &&other);
270 : /*! @endcond */
271 :
272 : bool Save(const std::string &osPath) const;
273 : std::string SaveAsString() const;
274 :
275 : CPLJSONObject GetRoot();
276 : const CPLJSONObject GetRoot() const;
277 : void SetRoot(const CPLJSONObject &oRoot);
278 : bool Load(const std::string &osPath);
279 : bool LoadMemory(const std::string &osStr);
280 : bool LoadMemory(const GByte *pabyData, int nLength = -1);
281 : bool LoadChunks(const std::string &osPath, size_t nChunkSize = 16384,
282 : GDALProgressFunc pfnProgress = nullptr,
283 : void *pProgressArg = nullptr);
284 : bool LoadUrl(const std::string &osUrl, const char *const *papszOptions,
285 : GDALProgressFunc pfnProgress = nullptr,
286 : void *pProgressArg = nullptr);
287 :
288 : private:
289 : mutable JSONObjectH m_poRootJsonObject;
290 : };
291 :
292 : CPL_C_END
293 :
294 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
295 : extern "C++"
296 : {
297 : CPLStringList CPLParseKeyValueJson(const char *pszJson);
298 : }
299 : #endif
300 :
301 : #endif // CPL_JSON_H_INCLUDED
|