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