Coverage Report

Created: 2025-06-13 06:29

/src/gdal/port/cpl_json.h
Line
Count
Source (jump to first uncovered line)
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
    JSONObjectH GetInternalHandle() const
123
0
    {
124
0
        return m_poJsonObject;
125
0
    }
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
    std::string GetName() const
154
0
    {
155
0
        return m_osKey;
156
0
    }
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
        ConstIterator(const CPLJSONArray &oSelf, bool bStart)
200
0
            : m_oSelf(oSelf), m_nIdx(bStart ? 0 : oSelf.Size())
201
0
        {
202
0
        }
203
204
0
        ~ConstIterator() = default;
205
206
        CPLJSONObject &operator*() const
207
0
        {
208
0
            m_oObj = m_oSelf[m_nIdx];
209
0
            return m_oObj;
210
0
        }
211
212
        ConstIterator &operator++()
213
0
        {
214
0
            m_nIdx++;
215
0
            return *this;
216
0
        }
217
218
        bool operator==(const ConstIterator &it) const
219
0
        {
220
0
            return m_nIdx == it.m_nIdx;
221
0
        }
222
223
        bool operator!=(const ConstIterator &it) const
224
0
        {
225
0
            return m_nIdx != it.m_nIdx;
226
0
        }
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
    ConstIterator begin() const
246
0
    {
247
0
        return ConstIterator(*this, true);
248
0
    }
249
250
    /** Iterator to after last element */
251
    ConstIterator end() const
252
0
    {
253
0
        return ConstIterator(*this, false);
254
0
    }
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