forked from eranif/codelite
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJSON.h
More file actions
298 lines (258 loc) · 9.82 KB
/
JSON.h
File metadata and controls
298 lines (258 loc) · 9.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright : (C) 2014 Eran Ifrah
// file name : json_node.h
//
// -------------------------------------------------------------------------
// A
// _____ _ _ _ _
// / __ \ | | | | (_) |
// | / \/ ___ __| | ___| | _| |_ ___
// | | / _ \ / _ |/ _ \ | | | __/ _ )
// | \__/\ (_) | (_| | __/ |___| | || __/
// \____/\___/ \__,_|\___\_____/_|\__\___|
//
// F i l e
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#ifndef ZJSONNODE_H
#define ZJSONNODE_H
// clang-format off
#include <wx/vector.h>
#include <wx/string.h>
#include <wx/variant.h>
#include <wx/filename.h>
#include <string_view>
#include <wx/gdicmn.h>
#include "codelite_exports.h"
#include <map>
#include <cJSON.h>
#if wxUSE_GUI
#include <wx/arrstr.h>
#include <wx/colour.h>
#include <wx/font.h>
#endif
#include "macros.h"
#include <vector>
#include <type_traits>
// clang-format on
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class WXDLLIMPEXP_CL JSONItem
{
protected:
cJSON* m_json = nullptr;
cJSON* m_walker = nullptr;
wxString m_propertyName;
int m_type = wxNOT_FOUND;
// Values
wxString m_valueString;
double m_valueNumer = 0;
public:
JSONItem(cJSON* json);
JSONItem(const wxString& name, double val);
JSONItem(const wxString& name, const std::string& val);
JSONItem(const wxString& name, const char* pval, size_t len);
JSONItem(const wxString& name, bool val);
JSONItem() = default;
virtual ~JSONItem() = default;
// Walkers
JSONItem firstChild();
JSONItem nextChild();
// Setters
////////////////////////////////////////////////
void setType(int m_type) { this->m_type = m_type; }
int getType() const { return m_type; }
const wxString& GetPropertyName() const { return m_propertyName; }
void SetPropertyName(const wxString& name) { m_propertyName = name; }
// Readers
////////////////////////////////////////////////
JSONItem namedObject(const wxString& name) const;
bool hasNamedObject(const wxString& name) const;
/// If your array is big (hundred of entries) use
/// `GetAsVector` and iterate it instead
JSONItem operator[](int index) const;
JSONItem operator[](const wxString& name) const;
/// the C implementation for accessing large arrays, is the sum of an arithmetic progression.
/// Use this method to get an array with `O(1)` access
/// This call is `O(n)`
std::vector<JSONItem> GetAsVector() const;
/// the C implementation for accessing by name is by `O(n)`
/// Use this method when you have large number of items and
/// `O(1)` is required
std::unordered_map<std::string_view, JSONItem> GetAsMap() const;
bool toBool(bool defaultValue = false) const;
wxString toString(const wxString& defaultValue = wxEmptyString) const;
wxArrayString toArrayString(const wxArrayString& defaultValue = wxArrayString()) const;
std::vector<double> toDoubleArray(const std::vector<double>& defaultValue = {}) const;
std::vector<int> toIntArray(const std::vector<int>& defaultValue = {}) const;
JSONItem arrayItem(int pos) const;
// Return the object type
bool isNull() const;
bool isBool() const;
bool isString() const;
bool isNumber() const;
bool isArray() const;
bool isObject() const;
wxString format(bool formatted = true) const;
/**
* @brief format the JSON into a raw c string
* The caller should free the pointer (using free())
*/
char* FormatRawString(bool formatted = true) const;
int arraySize() const;
int toInt(int defaultVal = -1) const;
/// Convert the value into `T` from
template <typename T>
T fromNumber(T default_value) const
{
return static_cast<T>(toInt((int)default_value));
}
template <typename T>
inline T GetValue() const
{
if constexpr (std::is_same_v<T, bool>) {
return toBool();
} else if constexpr (std::is_same_v<T, int>) {
return toInt();
} else if constexpr (std::is_same_v<T, size_t>) {
return toSize_t();
} else if constexpr (std::is_same_v<T, double>) {
return toDouble();
} else if constexpr (std::is_same_v<T, std::string>) {
return toString().ToStdString(wxConvUTF8);
} else if constexpr (std::is_same_v<T, wxString>) {
return toString();
} else if constexpr (std::is_same_v<T, wxArrayString>) {
return toArrayString();
} else {
static_assert(!std::is_same_v<T, T>, "GetValue called with unsupported type.");
}
}
size_t toSize_t(size_t defaultVal = 0) const;
double toDouble(double defaultVal = -1.0) const;
wxFileName toFileName() const;
wxColour toColour(const wxColour& defaultColour = wxNullColour) const;
wxFont toFont(const wxFont& defaultFont = wxNullFont) const;
wxSize toSize() const;
wxPoint toPoint() const;
wxStringMap_t toStringMap(const wxStringMap_t& default_map = {}) const;
// Writers
////////////////////////////////////////////////
/**
* @brief create new named object and append it to this json element
* @return the newly created object
*/
static JSONItem createObject(const wxString& name = wxT(""));
/**
* @brief create new array
* @return the newly created array
*/
static JSONItem createArray();
/**
* @brief add array to this json and return a reference to the newly added array
*/
JSONItem AddArray(const wxString& name);
/**
* @brief add object to this json and return a reference to the newly added object
*/
JSONItem AddObject(const wxString& name);
/**
* @brief append new element to this json element
*/
void append(const JSONItem& element);
JSONItem& addProperty(const wxString& name, const wxString& value);
JSONItem& addProperty(const wxString& name, const std::string& value);
JSONItem& addProperty(const wxString& name, const wxChar* value);
JSONItem& addProperty(const wxString& name, int value) { return addProperty(name, (long)value); }
JSONItem& addProperty(const wxString& name, long value);
JSONItem& addProperty(const wxString& name, size_t value);
JSONItem& addProperty(const wxString& name, bool value);
JSONItem& addProperty(const wxString& name, cJSON* pjson);
JSONItem& addProperty(const wxString& name, const wxFileName& filename);
JSONItem& addProperty(const wxString& name, const std::vector<int>& arr_int);
template <class T = int>
typename std::enable_if<!std::is_same<wxVector<T>, std::vector<T>>::value, JSONItem&>::type
addProperty(const wxString& name, const wxVector<T>& arr_int)
{
return addProperty(name, std::vector<T>(arr_int.begin(), arr_int.end()));
}
JSONItem& addProperty(const wxString& name, const wxSize& sz);
JSONItem& addProperty(const wxString& name, const wxPoint& pt);
JSONItem& addProperty(const wxString& name, const wxColour& colour);
JSONItem& addProperty(const wxString& name, const wxFont& font);
JSONItem& addProperty(const wxString& name, const wxArrayString& arr);
JSONItem& addProperty(const wxString& name, const wxStringMap_t& stringMap);
JSONItem& addProperty(const wxString& name, const JSONItem& element);
JSONItem& addProperty(const wxString& name, const char* value, const wxMBConv& conv = wxConvUTF8);
/**
* @brief delete property by name
*/
void removeProperty(const wxString& name);
/**
* @brief detach element from json. Return the detached element
*/
JSONItem detachProperty(const wxString& name);
//////////////////////////////////////////////////
// Array operations
//////////////////////////////////////////////////
/**
* @brief append new number
* @return the newly added property
*/
void arrayAppend(const JSONItem& element);
void arrayAppend(const wxString& value);
void arrayAppend(const char* value);
void arrayAppend(const std::string& value);
void arrayAppend(int number);
void arrayAppend(double number);
bool isOk() const { return m_json != NULL; }
/**
* @brief release the internal pointer
*/
cJSON* release()
{
cJSON* temp = m_json;
m_json = nullptr;
return temp;
}
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
enum class JsonType
{
Array,
Null,
Object,
};
class WXDLLIMPEXP_CL JSON
{
protected:
cJSON* m_json;
wxString _errorString;
public:
explicit JSON(JsonType type);
explicit JSON(const wxString& text);
explicit JSON(const wxFileName& filename);
explicit JSON(JSONItem item);
explicit JSON(cJSON* json);
virtual ~JSON();
void save(const wxFileName& fn) const;
wxString errorString() const;
bool isOk() const { return m_json != NULL; }
JSONItem toElement() const;
void clear();
cJSON* release();
private:
// Make this class not copyable
JSON(const JSON&) = delete;
JSON& operator=(const JSON&) = delete;
};
#endif // ZJSONNODE_H