1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qbs.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef JSON_H
41 #define JSON_H
42 
43 #include <cstdint>
44 #include <initializer_list>
45 #include <string>
46 #include <vector>
47 
48 namespace Json {
49 
50 class JsonArray;
51 class JsonObject;
52 
53 namespace Internal {
54 class Data;
55 class Base;
56 class Object;
57 class Header;
58 class Array;
59 class Value;
60 class Entry;
61 class SharedString;
62 class Parser;
63 }
64 
65 class JsonValue
66 {
67 public:
68     enum Type {
69         Null =  0x0,
70         Bool = 0x1,
71         Double = 0x2,
72         String = 0x3,
73         Array = 0x4,
74         Object = 0x5,
75         Undefined = 0x80
76     };
77 
78     JsonValue(Type = Null);
79     JsonValue(bool b);
80     JsonValue(double n);
81     JsonValue(int n);
82     JsonValue(int64_t n);
83     JsonValue(const std::string &s);
84     JsonValue(const char *s);
85     JsonValue(const JsonArray &a);
86     JsonValue(const JsonObject &o);
87 
88     ~JsonValue();
89 
90     JsonValue(const JsonValue &other);
91     JsonValue &operator =(const JsonValue &other);
92 
type()93     Type type() const { return t; }
isNull()94     bool isNull() const { return t == Null; }
isBool()95     bool isBool() const { return t == Bool; }
isDouble()96     bool isDouble() const { return t == Double; }
isString()97     bool isString() const { return t == String; }
isArray()98     bool isArray() const { return t == Array; }
isObject()99     bool isObject() const { return t == Object; }
isUndefined()100     bool isUndefined() const { return t == Undefined; }
101 
102     bool toBool(bool defaultValue = false) const;
103     int toInt(int defaultValue = 0) const;
104     double toDouble(double defaultValue = 0) const;
105     std::string toString(const std::string &defaultValue = std::string()) const;
106     JsonArray toArray() const;
107     JsonArray toArray(const JsonArray &defaultValue) const;
108     JsonObject toObject() const;
109     JsonObject toObject(const JsonObject &defaultValue) const;
110 
111     bool operator==(const JsonValue &other) const;
112     bool operator!=(const JsonValue &other) const;
113 
114 private:
115     // avoid implicit conversions from char * to bool
JsonValue(const void *)116     JsonValue(const void *) : t(Null) {}
117     friend class Internal::Value;
118     friend class JsonArray;
119     friend class JsonObject;
120 
121     JsonValue(Internal::Data *d, Internal::Base *b, const Internal::Value& v);
122 
123     void detach();
124 
125     union {
126         uint64_t ui;
127         bool b;
128         double dbl;
129         Internal::SharedString *stringData;
130         Internal::Base *base;
131     };
132     Internal::Data *d; // needed for Objects and Arrays
133     Type t;
134 };
135 
136 class JsonValueRef
137 {
138 public:
JsonValueRef(JsonArray * array,int idx)139     JsonValueRef(JsonArray *array, int idx)
140         : a(array), is_object(false), index(idx) {}
JsonValueRef(JsonObject * object,int idx)141     JsonValueRef(JsonObject *object, int idx)
142         : o(object), is_object(true), index(idx) {}
143 
JsonValue()144     operator JsonValue() const { return toValue(); }
145     JsonValueRef &operator=(const JsonValue &val);
146     JsonValueRef &operator=(const JsonValueRef &val);
147 
type()148     JsonValue::Type type() const { return toValue().type(); }
isNull()149     bool isNull() const { return type() == JsonValue::Null; }
isBool()150     bool isBool() const { return type() == JsonValue::Bool; }
isDouble()151     bool isDouble() const { return type() == JsonValue::Double; }
isString()152     bool isString() const { return type() == JsonValue::String; }
isArray()153     bool isArray() const { return type() == JsonValue::Array; }
isObject()154     bool isObject() const { return type() == JsonValue::Object; }
isUndefined()155     bool isUndefined() const { return type() == JsonValue::Undefined; }
156 
toString()157     std::string toString() const { return toValue().toString(); }
158     JsonArray toArray() const;
159     JsonObject toObject() const;
160 
161     bool toBool(bool defaultValue = false) const { return toValue().toBool(defaultValue); }
162     int toInt(int defaultValue = 0) const { return toValue().toInt(defaultValue); }
163     double toDouble(double defaultValue = 0) const { return toValue().toDouble(defaultValue); }
toString(const std::string & defaultValue)164     std::string toString(const std::string &defaultValue) const { return toValue().toString(defaultValue); }
165 
166     bool operator==(const JsonValue &other) const { return toValue() == other; }
167     bool operator!=(const JsonValue &other) const { return toValue() != other; }
168 
169 private:
170     JsonValue toValue() const;
171 
172     union {
173         JsonArray *a;
174         JsonObject *o;
175     };
176     uint32_t is_object : 1;
177     uint32_t index : 31;
178 };
179 
180 class JsonValuePtr
181 {
182     JsonValue value;
183 public:
JsonValuePtr(const JsonValue & val)184     explicit JsonValuePtr(const JsonValue& val)
185         : value(val) {}
186 
187     JsonValue& operator*() { return value; }
188     JsonValue* operator->() { return &value; }
189 };
190 
191 class JsonValueRefPtr
192 {
193     JsonValueRef valueRef;
194 public:
JsonValueRefPtr(JsonArray * array,int idx)195     JsonValueRefPtr(JsonArray *array, int idx)
196         : valueRef(array, idx) {}
JsonValueRefPtr(JsonObject * object,int idx)197     JsonValueRefPtr(JsonObject *object, int idx)
198         : valueRef(object, idx)  {}
199 
200     JsonValueRef& operator*() { return valueRef; }
201     JsonValueRef* operator->() { return &valueRef; }
202 };
203 
204 
205 
206 class JsonArray
207 {
208 public:
209     JsonArray();
210     JsonArray(std::initializer_list<JsonValue> args);
211 
212     ~JsonArray();
213 
214     JsonArray(const JsonArray &other);
215     JsonArray &operator=(const JsonArray &other);
216 
217     int size() const;
count()218     int count() const { return size(); }
219 
220     bool isEmpty() const;
221     JsonValue at(int i) const;
222     JsonValue first() const;
223     JsonValue last() const;
224 
225     void prepend(const JsonValue &value);
226     void append(const JsonValue &value);
227     void removeAt(int i);
228     JsonValue takeAt(int i);
removeFirst()229     void removeFirst() { removeAt(0); }
removeLast()230     void removeLast() { removeAt(size() - 1); }
231 
232     void insert(int i, const JsonValue &value);
233     void replace(int i, const JsonValue &value);
234 
235     bool contains(const JsonValue &element) const;
236     JsonValueRef operator[](int i);
237     JsonValue operator[](int i) const;
238 
239     bool operator==(const JsonArray &other) const;
240     bool operator!=(const JsonArray &other) const;
241 
242     class const_iterator;
243 
244     class iterator {
245     public:
246         JsonArray *a;
247         int i;
248         using iterator_category = std::random_access_iterator_tag;
249         using difference_type = int;
250         using value_type = JsonValue;
251         using reference = JsonValueRef;
252         using pointer = JsonValueRefPtr;
253 
iterator()254         iterator() : a(nullptr), i(0) { }
iterator(JsonArray * array,int index)255         explicit iterator(JsonArray *array, int index) : a(array), i(index) { }
256 
257         JsonValueRef operator*() const { return JsonValueRef(a, i); }
258         JsonValueRefPtr operator->() const { return JsonValueRefPtr(a, i); }
259         JsonValueRef operator[](int j) const { return JsonValueRef(a, i + j); }
260 
261         bool operator==(const iterator &o) const { return i == o.i; }
262         bool operator!=(const iterator &o) const { return i != o.i; }
263         bool operator<(const iterator& other) const { return i < other.i; }
264         bool operator<=(const iterator& other) const { return i <= other.i; }
265         bool operator>(const iterator& other) const { return i > other.i; }
266         bool operator>=(const iterator& other) const { return i >= other.i; }
267         bool operator==(const const_iterator &o) const { return i == o.i; }
268         bool operator!=(const const_iterator &o) const { return i != o.i; }
269         bool operator<(const const_iterator& other) const { return i < other.i; }
270         bool operator<=(const const_iterator& other) const { return i <= other.i; }
271         bool operator>(const const_iterator& other) const { return i > other.i; }
272         bool operator>=(const const_iterator& other) const { return i >= other.i; }
273         iterator &operator++() { ++i; return *this; }
274         iterator operator++(int) { iterator n = *this; ++i; return n; }
275         iterator &operator--() { i--; return *this; }
276         iterator operator--(int) { iterator n = *this; i--; return n; }
277         iterator &operator+=(int j) { i+=j; return *this; }
278         iterator &operator-=(int j) { i-=j; return *this; }
279         iterator operator+(int j) const { return iterator(a, i+j); }
280         iterator operator-(int j) const { return iterator(a, i-j); }
281         int operator-(iterator j) const { return i - j.i; }
282     };
283     friend class iterator;
284 
285     class const_iterator {
286     public:
287         const JsonArray *a;
288         int i;
289         using iterator_category = std::random_access_iterator_tag;
290         using difference_type = std::ptrdiff_t;
291         using value_type = JsonValue;
292         using reference = JsonValue;
293         using pointer = JsonValuePtr;
294 
const_iterator()295         const_iterator() : a(nullptr), i(0) { }
const_iterator(const JsonArray * array,int index)296         explicit const_iterator(const JsonArray *array, int index) : a(array), i(index) { }
const_iterator(const iterator & o)297         const_iterator(const iterator &o) : a(o.a), i(o.i) {}
298 
299         JsonValue operator*() const { return a->at(i); }
300         JsonValuePtr operator->() const { return JsonValuePtr(a->at(i)); }
301         JsonValue operator[](int j) const { return a->at(i+j); }
302         bool operator==(const const_iterator &o) const { return i == o.i; }
303         bool operator!=(const const_iterator &o) const { return i != o.i; }
304         bool operator<(const const_iterator& other) const { return i < other.i; }
305         bool operator<=(const const_iterator& other) const { return i <= other.i; }
306         bool operator>(const const_iterator& other) const { return i > other.i; }
307         bool operator>=(const const_iterator& other) const { return i >= other.i; }
308         const_iterator &operator++() { ++i; return *this; }
309         const_iterator operator++(int) { const_iterator n = *this; ++i; return n; }
310         const_iterator &operator--() { i--; return *this; }
311         const_iterator operator--(int) { const_iterator n = *this; i--; return n; }
312         const_iterator &operator+=(int j) { i+=j; return *this; }
313         const_iterator &operator-=(int j) { i-=j; return *this; }
314         const_iterator operator+(int j) const { return const_iterator(a, i+j); }
315         const_iterator operator-(int j) const { return const_iterator(a, i-j); }
316         int operator-(const_iterator j) const { return i - j.i; }
317     };
318     friend class const_iterator;
319 
320     // stl style
begin()321     iterator begin() { detach(); return iterator(this, 0); }
begin()322     const_iterator begin() const { return const_iterator(this, 0); }
constBegin()323     const_iterator constBegin() const { return const_iterator(this, 0); }
end()324     iterator end() { detach(); return iterator(this, size()); }
end()325     const_iterator end() const { return const_iterator(this, size()); }
constEnd()326     const_iterator constEnd() const { return const_iterator(this, size()); }
insert(iterator before,const JsonValue & value)327     iterator insert(iterator before, const JsonValue &value) { insert(before.i, value); return before; }
erase(iterator it)328     iterator erase(iterator it) { removeAt(it.i); return it; }
329 
push_back(const JsonValue & t)330     void push_back(const JsonValue &t) { append(t); }
push_front(const JsonValue & t)331     void push_front(const JsonValue &t) { prepend(t); }
pop_front()332     void pop_front() { removeFirst(); }
pop_back()333     void pop_back() { removeLast(); }
empty()334     bool empty() const { return isEmpty(); }
335     using size_type = int ;
336     using value_type = JsonValue;
337     using pointer = value_type *;
338     using const_pointer = const value_type *;
339     using reference = JsonValueRef;
340     using const_reference = JsonValue;
341     using difference_type = int;
342 
343 private:
344     friend class Internal::Data;
345     friend class JsonValue;
346     friend class JsonDocument;
347 
348     JsonArray(Internal::Data *data, Internal::Array *array);
349     void compact();
350     void detach(uint32_t reserve = 0);
351 
352     Internal::Data *d;
353     Internal::Array *a;
354 };
355 
356 
357 class JsonObject
358 {
359 public:
360     JsonObject();
361     JsonObject(std::initializer_list<std::pair<std::string, JsonValue> > args);
362     ~JsonObject();
363 
364     JsonObject(const JsonObject &other);
365     JsonObject &operator =(const JsonObject &other);
366 
367     using Keys = std::vector<std::string>;
368     Keys keys() const;
369     int size() const;
count()370     int count() const { return size(); }
length()371     int length() const { return size(); }
372     bool isEmpty() const;
373 
374     JsonValue value(const std::string &key) const;
375     JsonValue operator[] (const std::string &key) const;
376     JsonValueRef operator[] (const std::string &key);
377 
378     void remove(const std::string &key);
379     JsonValue take(const std::string &key);
380     bool contains(const std::string &key) const;
381 
382     bool operator==(const JsonObject &other) const;
383     bool operator!=(const JsonObject &other) const;
384 
385     class const_iterator;
386 
387     class iterator
388     {
389         friend class const_iterator;
390         friend class JsonObject;
391         JsonObject *o;
392         int i;
393 
394     public:
395         using iterator_category = std::bidirectional_iterator_tag;
396         using difference_type = int;
397         using value_type = JsonValue;
398         using reference = JsonValueRef;
399 
iterator()400         iterator() : o(nullptr), i(0) {}
iterator(JsonObject * obj,int index)401         iterator(JsonObject *obj, int index) : o(obj), i(index) {}
402 
key()403         std::string key() const { return o->keyAt(i); }
value()404         JsonValueRef value() const { return JsonValueRef(o, i); }
405         JsonValueRef operator*() const { return JsonValueRef(o, i); }
406         JsonValueRefPtr operator->() const { return JsonValueRefPtr(o, i); }
407         bool operator==(const iterator &other) const { return i == other.i; }
408         bool operator!=(const iterator &other) const { return i != other.i; }
409 
410         iterator &operator++() { ++i; return *this; }
411         iterator operator++(int) { iterator r = *this; ++i; return r; }
412         iterator &operator--() { --i; return *this; }
413         iterator operator--(int) { iterator r = *this; --i; return r; }
414         iterator operator+(int j) const
415         { iterator r = *this; r.i += j; return r; }
416         iterator operator-(int j) const { return operator+(-j); }
417         iterator &operator+=(int j) { i += j; return *this; }
418         iterator &operator-=(int j) { i -= j; return *this; }
419 
420     public:
421         bool operator==(const const_iterator &other) const { return i == other.i; }
422         bool operator!=(const const_iterator &other) const { return i != other.i; }
423     };
424     friend class iterator;
425 
426     class const_iterator
427     {
428         friend class iterator;
429         const JsonObject *o;
430         int i;
431 
432     public:
433         using iterator_category = std::bidirectional_iterator_tag;
434         using difference_type = int;
435         using value_type = JsonValue;
436         using reference = JsonValue;
437 
const_iterator()438         const_iterator() : o(nullptr), i(0) {}
const_iterator(const JsonObject * obj,int index)439         const_iterator(const JsonObject *obj, int index)
440             : o(obj), i(index) {}
const_iterator(const iterator & other)441         const_iterator(const iterator &other)
442             : o(other.o), i(other.i) {}
443 
key()444         std::string key() const { return o->keyAt(i); }
value()445         JsonValue value() const { return o->valueAt(i); }
446         JsonValue operator*() const { return o->valueAt(i); }
447         JsonValuePtr operator->() const { return JsonValuePtr(o->valueAt(i)); }
448         bool operator==(const const_iterator &other) const { return i == other.i; }
449         bool operator!=(const const_iterator &other) const { return i != other.i; }
450 
451         const_iterator &operator++() { ++i; return *this; }
452         const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
453         const_iterator &operator--() { --i; return *this; }
454         const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
455         const_iterator operator+(int j) const
456         { const_iterator r = *this; r.i += j; return r; }
457         const_iterator operator-(int j) const { return operator+(-j); }
458         const_iterator &operator+=(int j) { i += j; return *this; }
459         const_iterator &operator-=(int j) { i -= j; return *this; }
460 
461         bool operator==(const iterator &other) const { return i == other.i; }
462         bool operator!=(const iterator &other) const { return i != other.i; }
463     };
464     friend class const_iterator;
465 
466     // STL style
begin()467     iterator begin() { detach(); return iterator(this, 0); }
begin()468     const_iterator begin() const { return const_iterator(this, 0); }
constBegin()469     const_iterator constBegin() const { return const_iterator(this, 0); }
end()470     iterator end() { detach(); return iterator(this, size()); }
end()471     const_iterator end() const { return const_iterator(this, size()); }
constEnd()472     const_iterator constEnd() const { return const_iterator(this, size()); }
473     iterator erase(iterator it);
474 
475     // more Qt
476     iterator find(const std::string &key);
find(const std::string & key)477     const_iterator find(const std::string &key) const { return constFind(key); }
478     const_iterator constFind(const std::string &key) const;
479     iterator insert(const std::string &key, const JsonValue &value);
480 
481     // STL compatibility
482     using mapped_type = JsonValue;
483     using key_type = std::string;
484     using size_type = int;
485 
empty()486     bool empty() const { return isEmpty(); }
487 
488 private:
489     friend class Internal::Data;
490     friend class JsonValue;
491     friend class JsonDocument;
492     friend class JsonValueRef;
493 
494     JsonObject(Internal::Data *data, Internal::Object *object);
495     void detach(uint32_t reserve = 0);
496     void compact();
497 
498     std::string keyAt(int i) const;
499     JsonValue valueAt(int i) const;
500     void setValueAt(int i, const JsonValue &val);
501 
502     Internal::Data *d;
503     Internal::Object *o;
504 };
505 
506 struct JsonParseError
507 {
508     enum ParseError {
509         NoError = 0,
510         UnterminatedObject,
511         MissingNameSeparator,
512         UnterminatedArray,
513         MissingValueSeparator,
514         IllegalValue,
515         TerminationByNumber,
516         IllegalNumber,
517         IllegalEscapeSequence,
518         IllegalUTF8String,
519         UnterminatedString,
520         MissingObject,
521         DeepNesting,
522         DocumentTooLarge,
523         GarbageAtEnd
524     };
525 
526     int        offset;
527     ParseError error;
528 };
529 
530 class JsonDocument
531 {
532 public:
533     static const uint32_t BinaryFormatTag = ('q') | ('b' << 8) | ('j' << 16) | ('s' << 24);
534     JsonDocument();
535     explicit JsonDocument(const JsonObject &object);
536     explicit JsonDocument(const JsonArray &array);
537     ~JsonDocument();
538 
539     JsonDocument(const JsonDocument &other);
540     JsonDocument &operator =(const JsonDocument &other);
541 
542     enum DataValidation {
543         Validate,
544         BypassValidation
545     };
546 
547     static JsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate);
548     const char *rawData(int *size) const;
549 
550     static JsonDocument fromBinaryData(const std::string &data, DataValidation validation  = Validate);
551     std::string toBinaryData() const;
552 
553     enum JsonFormat {
554         Indented,
555         Compact
556     };
557 
558     static JsonDocument fromJson(const std::string &json, JsonParseError *error = nullptr);
559 
560     std::string toJson(JsonFormat format = Indented) const;
561 
562     bool isEmpty() const;
563     bool isArray() const;
564     bool isObject() const;
565 
566     JsonObject object() const;
567     JsonArray array() const;
568 
569     void setObject(const JsonObject &object);
570     void setArray(const JsonArray &array);
571 
572     bool operator==(const JsonDocument &other) const;
573     bool operator!=(const JsonDocument &other) const { return !(*this == other); }
574 
575     bool isNull() const;
576 
577 private:
578     friend class JsonValue;
579     friend class Internal::Data;
580     friend class Internal::Parser;
581 
582     JsonDocument(Internal::Data *data);
583 
584     Internal::Data *d;
585 };
586 
587 } // namespace Json
588 
589 #endif // JSON_H
590