summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-01-25 11:48:56 +0100
committerLars Knoll <lars.knoll@nokia.com>2012-01-25 11:50:59 +0100
commit5f4aeaa8ba9f0cde5cfaf43b5faf72b4e109ea0a (patch)
treeb499c10b0b1cf6904b90150cfb127d80aabac919 /src
parent845eef94ea3c0b9cdfd996f8fdc616568794597e (diff)
One (hopefully) last commit to this repo: Mirror what's in qtbase now.
This basically updates this repo to mirror the final API that made it into QtBase now. Mainly useful to use the codebase with an older version of QtBase. Change-Id: I8a4bc689b15851323305e45f11ac215dd271873b Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qjson.cpp75
-rw-r--r--src/qjson_p.h243
-rw-r--r--src/qjsonarray.cpp65
-rw-r--r--src/qjsonarray.h39
-rw-r--r--src/qjsondocument.cpp243
-rw-r--r--src/qjsondocument.h51
-rw-r--r--src/qjsonobject.cpp131
-rw-r--r--src/qjsonobject.h42
-rw-r--r--src/qjsonparser.cpp82
-rw-r--r--src/qjsonparser_p.h25
-rw-r--r--src/qjsonvalue.cpp79
-rw-r--r--src/qjsonvalue.h48
-rw-r--r--src/qjsonwriter.cpp32
-rw-r--r--src/qjsonwriter_p.h19
14 files changed, 635 insertions, 539 deletions
diff --git a/src/qjson.cpp b/src/qjson.cpp
index 9b97eab..dedddfc 100644
--- a/src/qjson.cpp
+++ b/src/qjson.cpp
@@ -39,17 +39,22 @@
**
****************************************************************************/
-#include <qjson_p.h>
+#include "qjson_p.h"
#include <qalgorithms.h>
-namespace QtJson
-{
+QT_BEGIN_NAMESPACE
-namespace Private
+namespace QJsonPrivate
{
-static const Base emptyArray = { { qToLittleEndian(sizeof(Base)) }, { 0 }, { 0 } };
-static const Base emptyObject = { { qToLittleEndian(sizeof(Base)) }, { 0 }, { 0 } };
+#ifdef Q_LITTLE_ENDIAN
+#define Q_TO_LITTLE_ENDIAN(x) (x)
+#else
+#define Q_TO_LITTLE_ENDIAN(x) ( ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24) )
+#endif
+
+static const Base emptyArray = { { Q_TO_LITTLE_ENDIAN(sizeof(Base)) }, { 0 }, { 0 } };
+static const Base emptyObject = { { Q_TO_LITTLE_ENDIAN(sizeof(Base)) }, { 0 }, { 0 } };
void Data::compact()
@@ -98,7 +103,7 @@ void Data::compact()
int dataSize = e->value.usedStorage(o);
if (dataSize) {
memcpy((char *)no + offset, e->value.data(o), dataSize);
- ne->value.val = offset;
+ ne->value.value = offset;
offset += dataSize;
}
}
@@ -113,7 +118,7 @@ void Data::compact()
int dataSize = v.usedStorage(a);
if (dataSize) {
memcpy((char *)na + offset, v.data(a), dataSize);
- nv.val = offset;
+ nv.value = offset;
offset += dataSize;
}
}
@@ -126,15 +131,10 @@ void Data::compact()
compactionCounter = 0;
}
-void Data::validate()
+bool Data::valid() const
{
- if (valid != Unchecked)
- return;
-
- if (header->tag != QJsonDocument::BinaryFormatTag || header->version != 1u) {
- valid = Invalid;
- return;
- }
+ if (header->tag != QJsonDocument::BinaryFormatTag || header->version != 1u)
+ return false;
bool res = false;
if (header->root()->is_object)
@@ -142,7 +142,7 @@ void Data::validate()
else
res = static_cast<Array *>(header->root())->isValid();
- valid = res ? Validated : Invalid;
+ return res;
}
@@ -179,9 +179,6 @@ void Base::removeItems(int pos, int numItems)
int Object::indexOf(const QString &key, bool *exists)
{
- if (exists)
- *exists = false;
-
int min = 0;
int n = length;
while (n > 0) {
@@ -195,13 +192,11 @@ int Object::indexOf(const QString &key, bool *exists)
}
}
if (min < (int)length && *entryAt(min) == key) {
- if (exists)
- *exists = true;
+ *exists = true;
return min;
}
- if (exists)
- return min;
- return -1;
+ *exists = false;
+ return min;
}
bool Object::isValid() const
@@ -298,7 +293,7 @@ int Value::usedStorage(const Base *b) const
}
case QJsonValue::Array:
case QJsonValue::Object:
- s = objectOrArray(b)->size;
+ s = base(b)->size;
break;
case QJsonValue::Null:
case QJsonValue::Bool:
@@ -319,7 +314,7 @@ bool Value::isValid(const Base *b) const
case QJsonValue::String:
case QJsonValue::Array:
case QJsonValue::Object:
- offset = val;
+ offset = value;
break;
case QJsonValue::Null:
case QJsonValue::Bool:
@@ -338,9 +333,9 @@ bool Value::isValid(const Base *b) const
if (s < 0 || offset + s > (int)b->tableOffset)
return false;
if (type == QJsonValue::Array)
- return static_cast<Array *>(objectOrArray(b))->isValid();
+ return static_cast<Array *>(base(b))->isValid();
if (type == QJsonValue::Object)
- return static_cast<Object *>(objectOrArray(b))->isValid();
+ return static_cast<Object *>(base(b))->isValid();
return true;
}
@@ -352,19 +347,19 @@ int Value::requiredStorage(const QJsonValue &v, bool *compressed)
*compressed = false;
switch (v.t) {
case QJsonValue::Double:
- if (Private::compressedNumber(v.dbl) != INT_MAX) {
+ if (QJsonPrivate::compressedNumber(v.dbl) != INT_MAX) {
*compressed = true;
return 0;
}
return sizeof(double);
case QJsonValue::String: {
QString s = v.toString();
- *compressed = Private::useCompressed(s);
- return Private::qStringSize(s, *compressed);
+ *compressed = QJsonPrivate::useCompressed(s);
+ return QJsonPrivate::qStringSize(s, *compressed);
}
case QJsonValue::Array:
case QJsonValue::Object:
- return v.base ? v.base->size : sizeof(Private::Base);
+ return v.base ? v.base->size : sizeof(QJsonPrivate::Base);
case QJsonValue::Undefined:
case QJsonValue::Null:
case QJsonValue::Bool:
@@ -385,10 +380,11 @@ uint Value::valueToStore(const QJsonValue &v, uint offset)
case QJsonValue::Bool:
return v.b;
case QJsonValue::Double: {
- int c = Private::compressedNumber(v.dbl);
+ int c = QJsonPrivate::compressedNumber(v.dbl);
if (c != INT_MAX)
return c;
}
+ // fall through
case QJsonValue::String:
case QJsonValue::Array:
case QJsonValue::Object:
@@ -405,17 +401,17 @@ void Value::copyData(const QJsonValue &v, char *dest, bool compressed)
switch (v.t) {
case QJsonValue::Double:
if (!compressed) {
- *((quint64 *)dest) = qToLittleEndian(v.ui);
+ qToLittleEndian(v.ui, (uchar *)dest);
}
break;
case QJsonValue::String: {
QString str = v.toString();
- Private::copyString(dest, str, compressed);
+ QJsonPrivate::copyString(dest, str, compressed);
break;
}
case QJsonValue::Array:
case QJsonValue::Object: {
- const Private::Base *b = v.base;
+ const QJsonPrivate::Base *b = v.base;
if (!b)
b = (v.t == QJsonValue::Array ? &emptyArray : &emptyObject);
memcpy(dest, b, b->size);
@@ -426,7 +422,6 @@ void Value::copyData(const QJsonValue &v, char *dest, bool compressed)
}
}
+} // namespace QJsonPrivate
-}
-
-}
+QT_END_NAMESPACE
diff --git a/src/qjson_p.h b/src/qjson_p.h
index f339dd0..304aa9c 100644
--- a/src/qjson_p.h
+++ b/src/qjson_p.h
@@ -53,29 +53,35 @@
// We mean it.
//
-#include <qjsonglobal.h>
#include <qjsonobject.h>
#include <qjsonvalue.h>
#include <qjsondocument.h>
#include <qjsonarray.h>
-#include <qoldbasicatomic.h>
+#include <qatomic.h>
#include <qstring.h>
#include <qendian.h>
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
/*
- This defines a binary data structure for Json data. The data structure is optimised for fast reading and minimum allocations.
- The whole data structure can be mmap'ed and used directly.
+ This defines a binary data structure for Json data. The data structure is optimised for fast reading
+ and minimum allocations. The whole data structure can be mmap'ed and used directly.
- In most cases the binary structure is not as space efficient as a utf8 encoded text representation, but much faster to access.
+ In most cases the binary structure is not as space efficient as a utf8 encoded text representation, but
+ much faster to access.
The size requirements are:
- String: 16 bytes header + 2*(string.length())
+ String:
+ Latin1 data: 2 bytes header + string.length()
+ Full Unicode: 4 bytes header + 2*(string.length())
Values: 4 bytes + size of data (size can be 0 for some data)
bool: 0 bytes
- number: 8 bytes
- string: 4 + 2*length of string
+ double: 8 bytes (0 if integer with less than 27bits)
+ string: see above
array: size of array
object: size of object
Array: 12 bytes + 4*length + size of Value data
@@ -83,46 +89,47 @@
For an example such as
- { // object: 12 + 5*8 = 52
- "firstName": "John", // key 4+12, value 8 = 24
- "lastName" : "Smith", // key 4+8, value 8 = 20
- "age" : 25, // key 4+4, value 0 = 8
- "address" : // key 4+8, object below = 154
+ { // object: 12 + 5*8 = 52
+ "firstName": "John", // key 12, value 8 = 20
+ "lastName" : "Smith", // key 12, value 8 = 20
+ "age" : 25, // key 8, value 0 = 8
+ "address" : // key 12, object below = 140
{ // object: 12 + 4*8
- "streetAddress": "21 2nd Street", // key 4+16, value 16
- "city" : "New York", // key 4+4, value 12
- "state" : "NY", // key 4+8, value 4
- "postalCode" : "10021" // key 4+12, value 8
- }, // object total: 148
- "phoneNumber": // key: 4+12, value array below = 208
- [ // array: 12 + 2*4 + values below = 176
+ "streetAddress": "21 2nd Street", // key 16, value 16
+ "city" : "New York", // key 8, value 12
+ "state" : "NY", // key 8, value 4
+ "postalCode" : "10021" // key 12, value 8
+ }, // object total: 128
+ "phoneNumber": // key: 16, value array below = 172
+ [ // array: 12 + 2*4 + values below: 156
{ // object 12 + 2*8
- "type" : "home", // key 4+4, value 8
- "number": "212 555-1234" // key 4+8, value 16
- }, // object total: 84
+ "type" : "home", // key 8, value 8
+ "number": "212 555-1234" // key 8, value 16
+ }, // object total: 68
{ // object 12 + 2*8
- "type" : "fax", // key 4+4, value 8
- "number": "646 555-4567" // key 4+8, value 16
- } // object total: 84
- ] // array total: 248
- } // great total: 416 bytes
-
- The uncompressed text file used roughly 500 bytes, so we end up using about the same space
- as the text representation.
-*/
-namespace QtJson
-{
+ "type" : "fax", // key 8, value 8
+ "number": "646 555-4567" // key 8, value 16
+ } // object total: 68
+ ] // array total: 156
+ } // great total: 412 bytes
+
+ The uncompressed text file used roughly 500 bytes, so in this case we end up using about
+ the same space as the text representation.
-namespace Private {
+ Other measurements have shown a slightly bigger binary size than a compact text
+ representation where all possible whitespace was stripped out.
+*/
+namespace QJsonPrivate {
-struct Array;
-struct Object;
-struct Value;
-struct Entry;
+class Array;
+class Object;
+class Value;
+class Entry;
template<typename T>
-struct q_littleendian
+class q_littleendian
{
+public:
T val;
q_littleendian &operator =(T i) { val = qToLittleEndian(i); return *this; }
@@ -130,6 +137,8 @@ struct q_littleendian
bool operator ==(T i) { return qFromLittleEndian(val) == i; }
bool operator !=(T i) { return qFromLittleEndian(val) != i; }
+ bool operator ==(q_littleendian<T> i) { return val == i.val; }
+ bool operator !=(q_littleendian<T> i) { return val != i.val; }
bool operator <(T i) { return qFromLittleEndian(val) < i; }
bool operator >(T i) { return qFromLittleEndian(val) > i; }
bool operator <=(T i) { return qFromLittleEndian(val) <= i; }
@@ -146,8 +155,9 @@ typedef q_littleendian<int> qle_int;
typedef q_littleendian<unsigned int> qle_uint;
template<int pos, int width>
-struct qle_bitfield
+class qle_bitfield
{
+public:
uint val;
enum {
@@ -187,8 +197,9 @@ struct qle_bitfield
};
template<int pos, int width>
-struct qle_signedbitfield
+class qle_signedbitfield
{
+public:
uint val;
enum {
@@ -230,7 +241,8 @@ struct qle_signedbitfield
typedef qle_uint offset;
-static inline int alignedSize(int size) { return (size + 3) & ~3; }
+// round the size up to the next 4 byte boundary
+inline int alignedSize(int size) { return (size + 3) & ~3; }
static inline bool useCompressed(const QString &s)
{
@@ -254,7 +266,6 @@ static inline int qStringSize(const QString &string, bool compress)
return alignedSize(l);
}
-
// returns INT_MAX if it can't compress it into 28 bits
static inline int compressedNumber(double d)
{
@@ -263,11 +274,8 @@ static inline int compressedNumber(double d)
const quint64 fraction_mask = 0x000fffffffffffffull;
const quint64 exponent_mask = 0x7ff0000000000000ull;
- union {
- quint64 val;
- double dbl;
- };
- dbl = d;
+ quint64 val;
+ memcpy (&val, &d, sizeof(double));
int exp = (int)((val & exponent_mask) >> exponent_off) - 1023;
if (exp < 0 || exp > 25)
return INT_MAX;
@@ -283,10 +291,11 @@ static inline int compressedNumber(double d)
return neg ? -res : res;
}
-struct Latin1String;
+class Latin1String;
-struct String
+class String
{
+public:
String(const char *data) { d = (Data *)data; }
struct Data {
@@ -347,7 +356,7 @@ struct String
return QString((QChar *)d->utf16, d->length);
#else
int l = d->length;
- QString str(l, QChar());
+ QString str(l, Qt::Uninitialized);
QChar *ch = str.data();
for (int i = 0; i < l; ++i)
ch[i] = d->utf16[i];
@@ -357,8 +366,9 @@ struct String
};
-struct Latin1String
+class Latin1String
{
+public:
Latin1String(const char *data) { d = (Data *)data; }
struct Data {
@@ -475,9 +485,20 @@ static inline void copyString(char *dest, const QString &str, bool compress)
}
+/*
+ Base is the base class for both Object and Array. Both classe work more or less the same way.
+ The class starts with a header (defined by the struct below), then followed by data (the data for
+ values in the Array case and Entry's (see below) for objects.
+
+ After the data a table follows (tableOffset points to it) containing Value objects for Arrays, and
+ offsets from the beginning of the object to Entry's in the case of Object.
-struct Base
+ Entry's in the Object's table are lexicographically sorted by key in the table(). This allows the usage
+ of a binary search over the keys in an Object.
+ */
+class Base
{
+public:
qle_uint size;
union {
uint _dummy;
@@ -496,20 +517,21 @@ struct Base
void removeItems(int pos, int numItems);
};
-struct Object : public Base
+class Object : public Base
{
-
+public:
Entry *entryAt(int i) const {
return reinterpret_cast<Entry *>(((char *)this) + table()[i]);
}
- int indexOf(const QString &key, bool *exists = 0);
+ int indexOf(const QString &key, bool *exists);
bool isValid() const;
};
-struct Array : public Base
+class Array : public Base
{
+public:
inline Value at(int i) const;
inline Value &operator [](int i);
@@ -517,18 +539,19 @@ struct Array : public Base
};
-struct Value
+class Value
{
+public:
union {
uint _dummy;
qle_bitfield<0, 3> type;
qle_bitfield<3, 1> latinOrIntValue;
qle_bitfield<4, 1> latinKey;
- qle_bitfield<5, 27> val;
- qle_signedbitfield<5, 27> int_val;
+ qle_bitfield<5, 27> value;
+ qle_signedbitfield<5, 27> int_value;
};
- inline char *data(const Base *b) const { return ((char *)b) + val; }
+ inline char *data(const Base *b) const { return ((char *)b) + value; }
int usedStorage(const Base *b) const;
bool toBoolean() const;
@@ -536,7 +559,7 @@ struct Value
QString toString(const Base *b) const;
String asString(const Base *b) const;
Latin1String asLatin1String(const Base *b) const;
- Base *objectOrArray(const Base *b) const;
+ Base *base(const Base *b) const;
bool isValid(const Base *b) const;
@@ -547,17 +570,18 @@ struct Value
inline Value Array::at(int i) const
{
- return * (Value *) (((char *) this) + tableOffset + i*sizeof(Value));
+ return *(Value *) (table() + i);
}
inline Value &Array::operator [](int i)
{
- return * (Value *) (((char *) this) + tableOffset + i*sizeof(Value));
+ return *(Value *) (table() + i);
}
-struct Entry {
+class Entry {
+public:
Value value;
// key
// value data follows key
@@ -604,7 +628,8 @@ struct Entry {
inline bool operator <(const QString &key, const Entry &e)
{ return e >= key; }
-struct Header {
+class Header {
+public:
qle_uint tag; // 'qbjs'
qle_uint version; // 1
Base *root() { return (Base *)(this + 1); }
@@ -614,35 +639,21 @@ struct Header {
inline bool Value::toBoolean() const
{
Q_ASSERT(type == QJsonValue::Bool);
- return val != 0;
+ return value != 0;
}
inline double Value::toDouble(const Base *b) const
{
Q_ASSERT(type == QJsonValue::Double);
if (latinOrIntValue)
- return int_val;
+ return int_value;
- union {
- quint64 i;
- double d;
- };
- i = qFromLittleEndian<quint64>((const uchar *)b + val);
+ quint64 i = qFromLittleEndian<quint64>((const uchar *)b + value);
+ double d;
+ memcpy(&d, &i, sizeof(double));
return d;
}
-inline QString Value::toString(const Base *b) const
-{
- char *d = data(b);
- if (latinOrIntValue) {
- int l = *(ushort *)d;
- return QString::fromLatin1(d + sizeof(ushort), l);
- }
- int l = *(int *)d;
- const QChar *c = (const QChar *)(d + sizeof(int));
- return QString(c, l);
-}
-
inline String Value::asString(const Base *b) const
{
Q_ASSERT(type == QJsonValue::String && !latinOrIntValue);
@@ -655,31 +666,49 @@ inline Latin1String Value::asLatin1String(const Base *b) const
return Latin1String(data(b));
}
-inline Base *Value::objectOrArray(const Base *b) const
+inline QString Value::toString(const Base *b) const
+{
+ if (latinOrIntValue)
+ return asLatin1String(b).toString();
+ else
+ return asString(b).toString();
+}
+
+inline Base *Value::base(const Base *b) const
{
Q_ASSERT(type == QJsonValue::Array || type == QJsonValue::Object);
return reinterpret_cast<Base *>(data(b));
}
-struct Data {
+class Data {
+public:
enum Validation {
Unchecked,
Validated,
Invalid
};
+ QAtomicInt ref;
+ int alloc;
+ union {
+ char *rawData;
+ Header *header;
+ };
+ uint compactionCounter : 31;
+ uint ownsData : 1;
+
inline Data(char *raw, int a)
- : alloc(a), compactionCounter(0), valid(Unchecked), ownsData(true), rawData(raw)
+ : alloc(a), rawData(raw), compactionCounter(0), ownsData(true)
{
- ref.store(0);
}
inline Data(int reserved, QJsonValue::Type valueType)
- : compactionCounter(0), valid(Validated), ownsData(true), rawData(0)
+ : rawData(0), compactionCounter(0), ownsData(true)
{
- ref.store(0);
+ Q_ASSERT(valueType == QJsonValue::Array || valueType == QJsonValue::Object);
alloc = sizeof(Header) + sizeof(Base) + reserved + sizeof(offset);
header = (Header *)malloc(alloc);
+ Q_CHECK_PTR(header);
header->tag = QJsonDocument::BinaryFormatTag;
header->version = 1;
Base *b = header->root();
@@ -691,23 +720,7 @@ struct Data {
inline ~Data()
{ if (ownsData) free(rawData); }
- QBasicAtomicInt ref;
- int alloc;
- int compactionCounter;
- Validation valid;
- bool ownsData;
- union {
- char *rawData;
- Header *header;
- };
-
- uint offsetOf(const void *ptr) const { return ((char *)ptr - rawData); }
-
- Object *object(int offset) const { return reinterpret_cast<Object *>(rawData + offset); }
- Entry *entry(int offset) const { return reinterpret_cast<Entry *>(rawData + offset); }
- Value *value(int offset) const { return reinterpret_cast<Value *>(rawData + offset); }
- Array *array(int offset) const { return reinterpret_cast<Array *>(rawData + offset); }
-
+ uint offsetOf(const void *ptr) const { return (uint)(((char *)ptr - rawData)); }
QJsonObject toObject(Object *o) const
{
@@ -719,25 +732,29 @@ struct Data {
return QJsonArray(const_cast<Data *>(this), a);
}
- Data *detach(Base *b, int reserve = 0)
+ Data *clone(Base *b, int reserve = 0)
{
int size = sizeof(Header) + b->size + reserve;
char *raw = (char *)malloc(size);
+ Q_CHECK_PTR(raw);
memcpy(raw + sizeof(Header), b, b->size);
Header *h = (Header *)raw;
h->tag = QJsonDocument::BinaryFormatTag;
h->version = 1;
Data *d = new Data(raw, size);
- d->compactionCounter = compactionCounter;
+ d->compactionCounter = (b == header->root()) ? compactionCounter : 0;
return d;
}
void compact();
- void validate();
+ bool valid() const;
+
+private:
+ Q_DISABLE_COPY(Data)
};
}
-}
+QT_END_NAMESPACE
#endif // QJSON_P_H
diff --git a/src/qjsonarray.cpp b/src/qjsonarray.cpp
index ece6a95..d5d9e54 100644
--- a/src/qjsonarray.cpp
+++ b/src/qjsonarray.cpp
@@ -42,14 +42,14 @@
#include <qjsonobject.h>
#include <qjsonvalue.h>
#include <qjsonarray.h>
-#include <qjson_p.h>
#include <qjsonvalue.h>
-#include <qjsonwriter_p.h>
-
#include <qstringlist.h>
#include <qdebug.h>
-namespace QtJson {
+#include "qjsonwriter_p.h"
+#include "qjson_p.h"
+
+QT_BEGIN_NAMESPACE
/*!
\class QJsonArray
@@ -68,6 +68,8 @@ namespace QtJson {
QJsonArray is an implicitly shared class and shares the data with the document
it has been created from as long as it is not being modified.
+
+ You can convert the array to and from text based JSON through QJsonDocument.
*/
/*!
@@ -81,7 +83,7 @@ QJsonArray::QJsonArray()
/*!
\internal
*/
-QJsonArray::QJsonArray(Private::Data *data, Private::Array *array)
+QJsonArray::QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array)
: d(data), a(array)
{
d->ref.ref();
@@ -160,7 +162,7 @@ QJsonArray QJsonArray::fromVariantList(const QVariantList &list)
/*!
Converts this object to a QVariantList.
- \returns the created map.
+ Returns the created map.
*/
QVariantList QJsonArray::toVariantList() const
{
@@ -175,7 +177,7 @@ QVariantList QJsonArray::toVariantList() const
/*!
- \returns the number of values stored in the array.
+ Returns the number of values stored in the array.
*/
int QJsonArray::size() const
{
@@ -186,7 +188,7 @@ int QJsonArray::size() const
}
/*!
- \returns \c true if the object is empty. This is the same as size() == 0.
+ Returns \c true if the object is empty. This is the same as size() == 0.
\sa size
*/
@@ -199,7 +201,7 @@ bool QJsonArray::isEmpty() const
}
/*!
- \returns a QJsonValue representing the value for index \a i.
+ Returns a QJsonValue representing the value for index \a i.
The returned QJsonValue is \c Undefined, if \a i is out of bounds.
@@ -331,21 +333,21 @@ void QJsonArray::insert(int i, const QJsonValue &value)
Q_ASSERT (i >= 0 && i <= (int)(a ? a->length : 0));
bool compressed;
- int valueSize = Private::Value::requiredStorage(value, &compressed);
+ int valueSize = QJsonPrivate::Value::requiredStorage(value, &compressed);
- detach(valueSize + sizeof(Private::Value));
+ detach(valueSize + sizeof(QJsonPrivate::Value));
if (!a->length)
- a->tableOffset = sizeof(Private::Array);
+ a->tableOffset = sizeof(QJsonPrivate::Array);
int valueOffset = a->reserveSpace(valueSize, i, 1, false);
- Private::Value &v = (*a)[i];
+ QJsonPrivate::Value &v = (*a)[i];
v.type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
v.latinOrIntValue = compressed;
v.latinKey = false;
- v.val = Private::Value::valueToStore(value, valueOffset);
+ v.value = QJsonPrivate::Value::valueToStore(value, valueOffset);
if (valueSize)
- Private::Value::copyData(value, (char *)a + valueOffset, compressed);
+ QJsonPrivate::Value::copyData(value, (char *)a + valueOffset, compressed);
}
/*!
@@ -359,21 +361,21 @@ void QJsonArray::replace(int i, const QJsonValue &value)
Q_ASSERT (a && i >= 0 && i < (int)(a->length));
bool compressed;
- int valueSize = Private::Value::requiredStorage(value, &compressed);
+ int valueSize = QJsonPrivate::Value::requiredStorage(value, &compressed);
detach(valueSize);
if (!a->length)
- a->tableOffset = sizeof(Private::Array);
+ a->tableOffset = sizeof(QJsonPrivate::Array);
int valueOffset = a->reserveSpace(valueSize, i, 1, true);
- Private::Value &v = (*a)[i];
+ QJsonPrivate::Value &v = (*a)[i];
v.type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
v.latinOrIntValue = compressed;
v.latinKey = false;
- v.val = Private::Value::valueToStore(value, valueOffset);
+ v.value = QJsonPrivate::Value::valueToStore(value, valueOffset);
if (valueSize)
- Private::Value::copyData(value, (char *)a + valueOffset, compressed);
+ QJsonPrivate::Value::copyData(value, (char *)a + valueOffset, compressed);
++d->compactionCounter;
if (d->compactionCounter > 32 && d->compactionCounter >= (int)a->length/2)
@@ -962,52 +964,51 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
void QJsonArray::detach(uint reserve)
{
if (!d) {
- d = new Private::Data(reserve, QJsonValue::Array);
- a = static_cast<Private::Array *>(d->header->root());
+ d = new QJsonPrivate::Data(reserve, QJsonValue::Array);
+ a = static_cast<QJsonPrivate::Array *>(d->header->root());
d->ref.ref();
return;
}
if (reserve == 0 && d->ref.load() == 1)
return;
- Private::Data *x = d->detach(a, reserve);
+ QJsonPrivate::Data *x = d->clone(a, reserve);
x->ref.ref();
if (!d->ref.deref())
delete d;
d = x;
- a = static_cast<Private::Array *>(d->header->root());
+ a = static_cast<QJsonPrivate::Array *>(d->header->root());
}
/*!
\internal
*/
-void QJsonArray::compact() const
+void QJsonArray::compact()
{
if (!d || !d->compactionCounter)
return;
- const_cast<QJsonArray *>(this)->detach();
+ detach();
d->compact();
- const_cast<QJsonArray *>(this)->a = static_cast<Private::Array *>(d->header->root());
+ a = static_cast<QJsonPrivate::Array *>(d->header->root());
}
-} // namespace QtJson
-
-QT_BEGIN_NAMESPACE
-QDebug operator<<(QDebug dbg, const QtJson::QJsonArray &a)
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QJsonArray &a)
{
if (!a.a) {
dbg << "QJsonArray()";
return dbg;
}
QByteArray json;
- QtJson::QJsonWriter::arrayToJson(a.a, json, 0, true);
+ QJsonPrivate::Writer::arrayToJson(a.a, json, 0, true);
dbg.nospace() << "QJsonArray("
<< json.constData() // print as utf-8 string without extra quotation marks
<< ")";
return dbg.space();
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qjsonarray.h b/src/qjsonarray.h
index 7eb0997..e296458 100644
--- a/src/qjsonarray.h
+++ b/src/qjsonarray.h
@@ -43,17 +43,17 @@
#define QJSONARRAY_H
#include <qjsonvalue.h>
-#include <qvariant.h>
+
+QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QStringList;
-Q_JSON_EXPORT QDebug operator<<(QDebug, const QtJson::QJsonArray &);
-QT_END_NAMESPACE
-namespace QtJson
-{
+class QDebug;
+class QStringList;
+template <typename T> class QList;
+typedef QList<QVariant> QVariantList;
-class Q_JSON_EXPORT QJsonArray
+class Q_CORE_EXPORT QJsonArray
{
public:
QJsonArray();
@@ -179,7 +179,6 @@ public:
inline const_iterator constEnd() const { return const_iterator(this, size()); }
iterator insert(iterator before, const QJsonValue &value) { insert(before.i, value); return before; }
iterator erase(iterator pos) { removeAt(pos.i); return pos; }
-// iterator erase(iterator first, iterator last);
// more Qt
typedef iterator Iterator;
@@ -188,10 +187,6 @@ public:
// stl compatibility
inline void push_back(const QJsonValue &t) { append(t); }
inline void push_front(const QJsonValue &t) { prepend(t); }
-// inline T& front() { return first(); }
-// inline const T& front() const { return first(); }
-// inline T& back() { return last(); }
-// inline const T& back() const { return last(); }
inline void pop_front() { removeFirst(); }
inline void pop_back() { removeLast(); }
inline bool empty() const { return isEmpty(); }
@@ -204,19 +199,25 @@ public:
typedef int difference_type;
private:
- friend class Private::Data;
+ friend class QJsonPrivate::Data;
friend class QJsonValue;
friend class QJsonDocument;
- friend QT_PREPEND_NAMESPACE(QDebug) (QT_PREPEND_NAMESPACE(operator<<)) (QT_PREPEND_NAMESPACE(QDebug) dbg, const QJsonArray &a);
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
- QJsonArray(Private::Data *data, Private::Array *array);
- void compact() const;
+ QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array);
+ void compact();
void detach(uint reserve = 0);
- Private::Data *d;
- Private::Array *a;
+ QJsonPrivate::Data *d;
+ QJsonPrivate::Array *a;
};
-}
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
#endif // QJSONARRAY_H
diff --git a/src/qjsondocument.cpp b/src/qjsondocument.cpp
index 81787fc..e76756d 100644
--- a/src/qjsondocument.cpp
+++ b/src/qjsondocument.cpp
@@ -43,12 +43,13 @@
#include <qjsonobject.h>
#include <qjsonvalue.h>
#include <qjsonarray.h>
-#include <qjson_p.h>
-#include <qjsonwriter_p.h>
-#include <qjsonparser_p.h>
#include <qstringlist.h>
+#include <qdebug.h>
+#include "qjsonwriter_p.h"
+#include "qjsonparser_p.h"
+#include "qjson_p.h"
-namespace QtJson {
+QT_BEGIN_NAMESPACE
/*! \class QJsonDocument
\ingroup json
@@ -58,24 +59,21 @@ namespace QtJson {
\brief The QJsonDocument class provides a way to read and write JSON documents.
QJsonDocument is a class that wraps a complete JSON document and can read and
- write this document both from a utf-8 encoded text based representation as well
+ write this document both from a UTF-8 encoded text based representation as well
as Qt's own binary format.
A JSON document can be converted from its text-based representation to a QJsonDocument
using QJsonDocument::fromJson(). toJson() converts it back to text. The parser is very
fast and efficient and converts the JSON to the binary representation used by Qt.
- Validity of the parsed document can be queried with isValid()
+ Validity of the parsed document can be queried with !isNull()
A document can be queried as to whether it contains an array or an object using isArray()
and isObject(). The array or object contained in the document can be retrieved using
array() or object() and then read or manipulated.
A document can also be created from a stored binary representation using fromBinaryData() or
- fromRawData(). In this case the document is not automatically checked for validity. If the
- document comes from an untrusted source isValid() should therefore be called before using
- the document any further. isValid() will guarantee that the binary document is in a state
- that will not cause problems when using it.
+ fromRawData().
*/
/*!
@@ -106,7 +104,7 @@ QJsonDocument::QJsonDocument(const QJsonArray &array)
/*! \internal
*/
-QJsonDocument::QJsonDocument(Private::Data *data)
+QJsonDocument::QJsonDocument(QJsonPrivate::Data *data)
: d(data)
{
Q_ASSERT(d);
@@ -114,7 +112,9 @@ QJsonDocument::QJsonDocument(Private::Data *data)
}
/*!
- * Deletes the document.
+ Deletes the document.
+
+ Binary data set with fromRawData is not freed.
*/
QJsonDocument::~QJsonDocument()
{
@@ -134,7 +134,7 @@ QJsonDocument::QJsonDocument(const QJsonDocument &other)
/*!
* Assigns the \a other document to this QJsonDocument.
- * \returns a reference to this object.
+ * Returns a reference to this object.
*/
QJsonDocument &QJsonDocument::operator =(const QJsonDocument &other)
{
@@ -149,6 +149,17 @@ QJsonDocument &QJsonDocument::operator =(const QJsonDocument &other)
return *this;
}
+/*! \enum QJsonDocument::DataValidation
+
+ This value is used to tell QJsonDocument whether to validate the binary data
+ when converting to a QJsonDocument using fromBinaryData() or fromRawData().
+
+ \value Validate Validate the data before using it. This is the default.
+ \value BypassValidation Bypasses data validation. Only use if you received the
+ data from a trusted place and know it's valid, as using of invalid data can crash
+ the application.
+ */
+
/*!
Creates a QJsonDocument that uses the first \a size bytes from
\a data. It assumes \a data contains a binary encoded JSON document.
@@ -156,22 +167,36 @@ QJsonDocument &QJsonDocument::operator =(const QJsonDocument &other)
has to guarantee that \a data will not be deleted or modified as long as
any QJsonDocument, QJsonObject or QJsonArray still references the data.
- No validity checks on \a data are performed. If you are unsure about
- the validity of the binary data, call isValid
+ \a data has to be aligned to a 4 byte boundary.
- \returns a QJsonDocument representing the data
+ \a validation decides whether the data is checked for validity before being used.
+ By default the data is validated. If the \a data is not valid, the method returns
+ a null document.
- \sa rawData fromBinaryData isValid
+ Returns a QJsonDocument representing the data.
+
+ \sa rawData fromBinaryData isNull DataValidation
*/
-QJsonDocument QJsonDocument::fromRawData(const char *data, int size)
+QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation)
{
- Private::Data *d = new Private::Data((char *)data, size);
+ if (!(((quintptr)validation) & ~3)) {
+ qWarning() <<"QJsonDocumnt::fromRawData: data has to have 4 byte alignment";
+ return QJsonDocument();
+ }
+
+ QJsonPrivate::Data *d = new QJsonPrivate::Data((char *)data, size);
d->ownsData = false;
+
+ if (validation != BypassValidation && !d->valid()) {
+ delete d;
+ return QJsonDocument();
+ }
+
return QJsonDocument(d);
}
/*!
- \returns the raw binary representation of the data
+ Returns the raw binary representation of the data
\a size will contain the size of the \a data.
This method is useful to e.g. stream the JSON document
@@ -188,24 +213,38 @@ const char *QJsonDocument::rawData(int *size) const
}
/*!
- Creates a QJsonDocument from \a data. The data is expected to
- be valid, call isValid() if the data comes from an untrusted
- source before using it.
+ Creates a QJsonDocument from \a data.
- \sa toBinaryData fromRawData isValid
+ \a validation decides whether the data is checked for validity before being used.
+ By default the data is validated. If the \a data is not valid, the method returns
+ a null document.
+
+ \sa toBinaryData fromRawData isNull DataValidation
*/
-QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data)
+QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation)
{
- Private::Header *h = (Private::Header *) data.constData();
-
- if (data.size() < (int)(sizeof(Private::Header) + sizeof(Private::Base)) ||
- h->tag != QJsonDocument::BinaryFormatTag || h->version != 1u ||
- sizeof(Private::Header) + h->root()->size > (uint)data.size())
+ QJsonPrivate::Header h;
+ memcpy(&h, data.constData(), sizeof(QJsonPrivate::Header));
+ QJsonPrivate::Base root;
+ memcpy(&root, data.constData() + sizeof(QJsonPrivate::Header), sizeof(QJsonPrivate::Base));
+
+ // do basic checks here, so we don't try to allocate more memory than we can.
+ if (data.size() < (int)(sizeof(QJsonPrivate::Header) + sizeof(QJsonPrivate::Base)) ||
+ h.tag != QJsonDocument::BinaryFormatTag || h.version != 1u ||
+ sizeof(QJsonPrivate::Header) + root.size > (uint)data.size())
return QJsonDocument();
char *raw = (char *)malloc(data.size());
+ if (!raw)
+ return QJsonDocument();
+
memcpy(raw, data.constData(), data.size());
- Private::Data *d = new Private::Data(raw, data.size());
+ QJsonPrivate::Data *d = new QJsonPrivate::Data(raw, data.size());
+
+ if (validation != BypassValidation && !d->valid()) {
+ delete d;
+ return QJsonDocument();
+ }
return QJsonDocument(d);
}
@@ -233,20 +272,12 @@ QJsonDocument QJsonDocument::fromVariant(const QVariant &variant)
}
/*!
- \returns a QVariant representing the Json document.
-
- The JSON data types are mapped as follows:
+ Returns a QVariant representing the Json document.
- \list
- \o Null an empty variant
- \o Bool QVariant::Bool
- \o Double QVariant::Double
- \o String QVariant::String
- \o Array QVariant::List
- \o Object QVariant::Map
- \endlist
+ The returned variant will be a QVariantList if the document is
+ a QJsonArray and a QVariantMap if the document is a QJsonObject.
- \sa fromVariant.
+ \sa fromVariant, QJsonValue::toVariant()
*/
QVariant QJsonDocument::toVariant() const
{
@@ -254,9 +285,9 @@ QVariant QJsonDocument::toVariant() const
return QVariant();
if (d->header->root()->isArray())
- return QJsonArray(d, static_cast<Private::Array *>(d->header->root())).toVariantList();
+ return QJsonArray(d, static_cast<QJsonPrivate::Array *>(d->header->root())).toVariantList();
else
- return QJsonObject(d, static_cast<Private::Object *>(d->header->root())).toVariantMap();
+ return QJsonObject(d, static_cast<QJsonPrivate::Object *>(d->header->root())).toVariantMap();
}
/*!
@@ -272,28 +303,28 @@ QByteArray QJsonDocument::toJson() const
QByteArray json;
if (d->header->root()->isArray())
- QJsonWriter::arrayToJson(static_cast<Private::Array *>(d->header->root()), json, 0);
+ QJsonPrivate::Writer::arrayToJson(static_cast<QJsonPrivate::Array *>(d->header->root()), json, 0);
else
- QJsonWriter::objectToJson(static_cast<Private::Object *>(d->header->root()), json, 0);
+ QJsonPrivate::Writer::objectToJson(static_cast<QJsonPrivate::Object *>(d->header->root()), json, 0);
return json;
}
/*!
Parses a UTF-8 encoded JSON document and creates a QJsonDocument
- from it. isValid will return \c true if no error was encountered during
+ from it. isNull() will return \c false if no error was encountered during
parsing.
\sa toJson
*/
QJsonDocument QJsonDocument::fromJson(const QByteArray &json)
{
- QJsonParser parser(json.constData(), json.length());
+ QJsonPrivate::Parser parser(json.constData(), json.length());
return parser.parse();
}
/*!
- \returns true if the document doesn't contain any data.
+ Returns true if the document doesn't contain any data.
*/
bool QJsonDocument::isEmpty() const
{
@@ -304,7 +335,7 @@ bool QJsonDocument::isEmpty() const
}
/*!
- \returns a binary representation of the document.
+ Returns a binary representation of the document.
The binary representation is also the native format used internally in Qt,
and is very efficient and fast to convert to and from.
@@ -320,11 +351,11 @@ QByteArray QJsonDocument::toBinaryData() const
if (!d || !d->rawData)
return QByteArray();
- return QByteArray(d->rawData, d->header->root()->size + sizeof(Private::Header));
+ return QByteArray(d->rawData, d->header->root()->size + sizeof(QJsonPrivate::Header));
}
/*!
- \returns true if the document contains an array.
+ Returns true if the document contains an array.
\sa array() isObject()
*/
@@ -333,12 +364,12 @@ bool QJsonDocument::isArray() const
if (!d)
return false;
- Private::Header *h = (Private::Header *)d->rawData;
+ QJsonPrivate::Header *h = (QJsonPrivate::Header *)d->rawData;
return h->root()->isArray();
}
/*!
- \returns true if the document contains an object.
+ Returns true if the document contains an object.
\sa object() isArray()
*/
@@ -347,12 +378,12 @@ bool QJsonDocument::isObject() const
if (!d)
return false;
- Private::Header *h = (Private::Header *)d->rawData;
+ QJsonPrivate::Header *h = (QJsonPrivate::Header *)d->rawData;
return h->root()->isObject();
}
/*!
- \returns the QJsonObject contained in the document.
+ Returns the QJsonObject contained in the document.
Returns an empty object if the document contains an
array.
@@ -362,15 +393,15 @@ bool QJsonDocument::isObject() const
QJsonObject QJsonDocument::object() const
{
if (d) {
- Private::Base *b = d->header->root();
+ QJsonPrivate::Base *b = d->header->root();
if (b->isObject())
- return QJsonObject(d, static_cast<Private::Object *>(b));
+ return QJsonObject(d, static_cast<QJsonPrivate::Object *>(b));
}
return QJsonObject();
}
/*!
- \returns the QJsonArray contained in the document.
+ Returns the QJsonArray contained in the document.
Returns an empty array if the document contains an
object.
@@ -380,9 +411,9 @@ QJsonObject QJsonDocument::object() const
QJsonArray QJsonDocument::array() const
{
if (d) {
- Private::Base *b = d->header->root();
+ QJsonPrivate::Base *b = d->header->root();
if (b->isArray())
- return QJsonArray(d, static_cast<Private::Array *>(b));
+ return QJsonArray(d, static_cast<QJsonPrivate::Array *>(b));
}
return QJsonArray();
}
@@ -400,14 +431,14 @@ void QJsonDocument::setObject(const QJsonObject &object)
d = object.d;
if (!d) {
- d = new Private::Data(0, QJsonValue::Object);
- } else if (d->compactionCounter) {
- object.compact();
- d = object.d;
- } else if (object.o != d->header->root()) {
- QJsonObject detached(object);
- detached.detach();
- d = detached.d;
+ d = new QJsonPrivate::Data(0, QJsonValue::Object);
+ } else if (d->compactionCounter || object.o != d->header->root()) {
+ QJsonObject o(object);
+ if (d->compactionCounter)
+ o.compact();
+ else
+ o.detach();
+ d = o.d;
d->ref.ref();
return;
}
@@ -427,14 +458,14 @@ void QJsonDocument::setArray(const QJsonArray &array)
d = array.d;
if (!d) {
- d = new Private::Data(0, QJsonValue::Array);
- } else if (d->compactionCounter) {
- array.compact();
- d = array.d;
- } else if (array.a != d->header->root()) {
- QJsonArray detached(array);
- detached.detach();
- d = detached.d;
+ d = new QJsonPrivate::Data(0, QJsonValue::Array);
+ } else if (d->compactionCounter || array.a != d->header->root()) {
+ QJsonArray a(array);
+ if (d->compactionCounter)
+ a.compact();
+ else
+ a.detach();
+ d = a.d;
d->ref.ref();
return;
}
@@ -442,7 +473,7 @@ void QJsonDocument::setArray(const QJsonArray &array)
}
/*!
- returns \c true if \a other is equal to this document
+ Returns \c true if the \a other document is equal to this document.
*/
bool QJsonDocument::operator==(const QJsonDocument &other) const
{
@@ -456,54 +487,35 @@ bool QJsonDocument::operator==(const QJsonDocument &other) const
return false;
if (d->header->root()->isObject())
- return QJsonObject(d, static_cast<Private::Object *>(d->header->root()))
- == QJsonObject(other.d, static_cast<Private::Object *>(other.d->header->root()));
+ return QJsonObject(d, static_cast<QJsonPrivate::Object *>(d->header->root()))
+ == QJsonObject(other.d, static_cast<QJsonPrivate::Object *>(other.d->header->root()));
else
- return QJsonArray(d, static_cast<Private::Array *>(d->header->root()))
- == QJsonArray(other.d, static_cast<Private::Array *>(other.d->header->root()));
+ return QJsonArray(d, static_cast<QJsonPrivate::Array *>(d->header->root()))
+ == QJsonArray(other.d, static_cast<QJsonPrivate::Array *>(other.d->header->root()));
}
/*!
+ \fn bool QJsonDocument::operator!=(const QJsonDocument &other) const
+
returns \c true if \a other is not equal to this document
*/
-bool QJsonDocument::operator!=(const QJsonDocument &other) const
-{
- return !(*this == other);
-}
/*!
- returns true if this document is valid.
+ returns true if this document is null.
- Documents created from UTF-8 encoded text are validated during
- parsing.
+ Null documents are documents created through the default constructor.
- Documents created from binary data are however not validated, and
- an explicit call to isValid is required to perform the validation.
- This allow for optimised access to documents that are stored in binary
- format and originate from trusted sources.
+ Documents created from UTF-8 encoded text or the binary format are
+ validated during parsing. If validation fails, the returned document
+ will also be null.
*/
-bool QJsonDocument::isValid()
+bool QJsonDocument::isNull() const
{
- if (!d)
- return false;
-
- if (d->valid == Private::Data::Unchecked)
- // Unchecked, check for validity
- d->validate();
-
- if (d->valid != Private::Data::Validated) {
- if (!d->ref.deref())
- delete d;
- d = 0;
- }
- return d != 0;
+ return (d == 0);
}
-} // namespace QtJson
-
-QT_BEGIN_NAMESPACE
-
-QDebug operator<<(QDebug dbg, const QtJson::QJsonDocument &o)
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QJsonDocument &o)
{
if (!o.d) {
dbg << "QJsonDocument()";
@@ -511,13 +523,14 @@ QDebug operator<<(QDebug dbg, const QtJson::QJsonDocument &o)
}
QByteArray json;
if (o.d->header->root()->isArray())
- QtJson::QJsonWriter::arrayToJson(static_cast<QtJson::Private::Array *>(o.d->header->root()), json, 0, true);
+ QJsonPrivate::Writer::arrayToJson(static_cast<QJsonPrivate::Array *>(o.d->header->root()), json, 0, true);
else
- QtJson::QJsonWriter::objectToJson(static_cast<QtJson::Private::Object *>(o.d->header->root()), json, 0, true);
+ QJsonPrivate::Writer::objectToJson(static_cast<QJsonPrivate::Object *>(o.d->header->root()), json, 0, true);
dbg.nospace() << "QJsonDocument("
<< json.constData() // print as utf-8 string without extra quotation marks
<< ")";
return dbg.space();
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qjsondocument.h b/src/qjsondocument.h
index e29d107..0994a80 100644
--- a/src/qjsondocument.h
+++ b/src/qjsondocument.h
@@ -42,20 +42,26 @@
#ifndef QJSONDOCUMENT_H
#define QJSONDOCUMENT_H
-#include <qjsonglobal.h>
#include <qjsonvalue.h>
-#include <qvariant.h>
+
+QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-Q_JSON_EXPORT QDebug operator<<(QDebug, const QtJson::QJsonDocument &);
-QT_END_NAMESPACE
-namespace QtJson {
+class QDebug;
+
+namespace QJsonPrivate {
+ class Parser;
+}
-class Q_JSON_EXPORT QJsonDocument
+class Q_CORE_EXPORT QJsonDocument
{
public:
+#ifdef Q_LITTLE_ENDIAN
static const uint BinaryFormatTag = ('q') | ('b' << 8) | ('j' << 16) | ('s' << 24);
+#else
+ static const uint BinaryFormatTag = ('q' << 24) | ('b' << 16) | ('j' << 8) | ('s');
+#endif
QJsonDocument();
explicit QJsonDocument(const QJsonObject &object);
@@ -65,17 +71,22 @@ public:
QJsonDocument(const QJsonDocument &other);
QJsonDocument &operator =(const QJsonDocument &other);
- static QJsonDocument fromRawData(const char *data, int size);
+ enum DataValidation {
+ Validate,
+ BypassValidation
+ };
+
+ static QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate);
const char *rawData(int *size) const;
- static QJsonDocument fromBinaryData(const QByteArray &data);
+ static QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
QByteArray toBinaryData() const;
static QJsonDocument fromVariant(const QVariant &variant);
QVariant toVariant() const;
- QByteArray toJson() const;
static QJsonDocument fromJson(const QByteArray &json);
+ QByteArray toJson() const;
bool isEmpty() const;
bool isArray() const;
@@ -88,21 +99,27 @@ public:
void setArray(const QJsonArray &array);
bool operator==(const QJsonDocument &other) const;
- bool operator!=(const QJsonDocument &other) const;
+ bool operator!=(const QJsonDocument &other) const { return !(*this == other); }
- bool isValid();
+ bool isNull() const;
private:
- friend class Private::Data;
friend class QJsonValue;
- friend class QJsonParser;
- friend QT_PREPEND_NAMESPACE(QDebug) (QT_PREPEND_NAMESPACE(operator<<)) (QT_PREPEND_NAMESPACE(QDebug) dbg, const QJsonDocument &a);
+ friend class QJsonPrivate::Data;
+ friend class QJsonPrivate::Parser;
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
- QJsonDocument(Private::Data *data);
+ QJsonDocument(QJsonPrivate::Data *data);
- Private::Data *d;
+ QJsonPrivate::Data *d;
};
-}
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
#endif // QJSONDOCUMENT_H
diff --git a/src/qjsonobject.cpp b/src/qjsonobject.cpp
index 27a1173..4252f80 100644
--- a/src/qjsonobject.cpp
+++ b/src/qjsonobject.cpp
@@ -42,12 +42,12 @@
#include <qjsonobject.h>
#include <qjsonvalue.h>
#include <qjsonarray.h>
-#include <qjson_p.h>
-#include <qjsonwriter_p.h>
#include <qstringlist.h>
#include <qdebug.h>
+#include "qjson_p.h"
+#include "qjsonwriter_p.h"
-namespace QtJson {
+QT_BEGIN_NAMESPACE
/*!
\class QJsonObject
@@ -66,6 +66,8 @@ namespace QtJson {
QJsonObject is an implicitly shared class, and shares the data with the document
it has been created from as long as it is not being modified.
+
+ You can convert the array to and from text based JSON through QJsonDocument.
*/
/*!
@@ -81,7 +83,7 @@ QJsonObject::QJsonObject()
/*!
\internal
*/
-QJsonObject::QJsonObject(Private::Data *data, Private::Object *object)
+QJsonObject::QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object)
: d(data), o(object)
{
Q_ASSERT(d);
@@ -151,20 +153,20 @@ QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map)
/*!
Converts this object to a QVariantMap.
- \returns the created map.
+ Returns the created map.
*/
QVariantMap QJsonObject::toVariantMap() const
{
QVariantMap map;
for (uint i = 0; i < o->length; ++i) {
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
map.insert(e->key(), QJsonValue(d, o, e->value).toVariant());
}
return map;
}
/*!
- \returns a list of all keys in this object.
+ Returns a list of all keys in this object.
*/
QStringList QJsonObject::keys() const
{
@@ -174,7 +176,7 @@ QStringList QJsonObject::keys() const
QStringList keys;
for (uint i = 0; i < o->length; ++i) {
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
keys.append(e->key());
}
@@ -182,7 +184,7 @@ QStringList QJsonObject::keys() const
}
/*!
- \returns the the number of (key, value) pairs stored in the object.
+ Returns the the number of (key, value) pairs stored in the object.
*/
int QJsonObject::size() const
{
@@ -193,7 +195,7 @@ int QJsonObject::size() const
}
/*!
- \returns \c true if the object is empty. This is the same as size() == 0.
+ Returns \c true if the object is empty. This is the same as size() == 0.
\sa size
*/
@@ -206,7 +208,7 @@ bool QJsonObject::isEmpty() const
}
/*!
- \returns a QJsonValue representing the value for the key \a key.
+ Returns a QJsonValue representing the value for the key \a key.
The returned QJsonValue is \c Undefined, if the key does not exist.
@@ -217,14 +219,15 @@ QJsonValue QJsonObject::value(const QString &key) const
if (!d)
return QJsonValue();
- int i = o->indexOf(key);
- if (i < 0)
+ bool keyExists;
+ int i = o->indexOf(key, &keyExists);
+ if (!keyExists)
return QJsonValue(QJsonValue::Undefined);
return QJsonValue(d, o, o->entryAt(i)->value);
}
/*!
- \returns a QJsonValue representing the value for the key \a key.
+ Returns a QJsonValue representing the value for the key \a key.
This does the same as value().
@@ -238,7 +241,7 @@ QJsonValue QJsonObject::operator [](const QString &key) const
}
/*!
- \returns a reference to the value for \a key.
+ Returns a reference to the value for \a key.
The return value is of type QJsonValueRef, a helper class for QJsonArray
and QJsonObject. When you get an object of type QJsonValueRef, you can
@@ -266,7 +269,7 @@ QJsonValueRef QJsonObject::operator [](const QString &key)
If there is already an item with the key \a key then that item's value
is replaced with \a value.
- \returns an iterator pointing to the inserted item.
+ Returns an iterator pointing to the inserted item.
If the value is QJsonValue::Undefined, it will cause the key to get removed
from the object. The returned iterator will then point to end()
@@ -281,16 +284,16 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &
}
bool latinOrIntValue;
- int valueSize = Private::Value::requiredStorage(value, &latinOrIntValue);
+ int valueSize = QJsonPrivate::Value::requiredStorage(value, &latinOrIntValue);
- bool latinKey = Private::useCompressed(key);
- int valueOffset = sizeof(Private::Entry) + Private::qStringSize(key, latinKey);
+ bool latinKey = QJsonPrivate::useCompressed(key);
+ int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey);
int requiredSize = valueOffset + valueSize;
- detach(requiredSize + sizeof(Private::offset)); // offset for the new index entry
+ detach(requiredSize + sizeof(QJsonPrivate::offset)); // offset for the new index entry
if (!o->length)
- o->tableOffset = sizeof(Private::Object);
+ o->tableOffset = sizeof(QJsonPrivate::Object);
bool keyExists = false;
int pos = o->indexOf(key, &keyExists);
@@ -299,14 +302,14 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &
o->reserveSpace(requiredSize, pos, 1, keyExists);
- Private::Entry *e = o->entryAt(pos);
+ QJsonPrivate::Entry *e = o->entryAt(pos);
e->value.type = value.t;
e->value.latinKey = latinKey;
e->value.latinOrIntValue = latinOrIntValue;
- e->value.val = Private::Value::valueToStore(value, (char *)e - (char *)o + valueOffset);
- Private::copyString((char *)(e + 1), key, latinKey);
+ e->value.value = QJsonPrivate::Value::valueToStore(value, (char *)e - (char *)o + valueOffset);
+ QJsonPrivate::copyString((char *)(e + 1), key, latinKey);
if (valueSize)
- Private::Value::copyData(value, (char *)e + valueOffset, latinOrIntValue);
+ QJsonPrivate::Value::copyData(value, (char *)e + valueOffset, latinOrIntValue);
return iterator(this, pos);
}
@@ -321,8 +324,9 @@ void QJsonObject::remove(const QString &key)
if (!d)
return;
- int index = o->indexOf(key);
- if (index < 0)
+ bool keyExists;
+ int index = o->indexOf(key, &keyExists);
+ if (!keyExists)
return;
detach();
@@ -335,7 +339,7 @@ void QJsonObject::remove(const QString &key)
/*!
Removes \a key from the object.
- \returns a QJsonValue containing the value referenced by \a key.
+ Returns a QJsonValue containing the value referenced by \a key.
If \a key was not contained in the object, the returned QJsonValue
is Undefined.
@@ -346,11 +350,12 @@ QJsonValue QJsonObject::take(const QString &key)
if (!o)
return QJsonValue(QJsonValue::Undefined);
- int index = o->indexOf(key);
- if (index < 0)
+ bool keyExists;
+ int index = o->indexOf(key, &keyExists);
+ if (!keyExists)
return QJsonValue(QJsonValue::Undefined);
- Private::Entry *e = o->entryAt(index);
+ QJsonPrivate::Entry *e = o->entryAt(index);
o->removeItems(index, 1);
++d->compactionCounter;
if (d->compactionCounter > 32 && d->compactionCounter >= (int)o->length/2)
@@ -360,7 +365,7 @@ QJsonValue QJsonObject::take(const QString &key)
}
/*!
- \returns \c true if the object contains key \a key.
+ Returns \c true if the object contains key \a key.
\sa insert, remove, take
*/
@@ -369,11 +374,13 @@ bool QJsonObject::contains(const QString &key) const
if (!o)
return false;
- return o->indexOf(key) >= 0;
+ bool keyExists;
+ o->indexOf(key, &keyExists);
+ return keyExists;
}
/*!
- \returns \c true if \a other is equal to this object
+ Returns \c true if \a other is equal to this object
*/
bool QJsonObject::operator==(const QJsonObject &other) const
{
@@ -388,7 +395,7 @@ bool QJsonObject::operator==(const QJsonObject &other) const
return false;
for (uint i = 0; i < o->length; ++i) {
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
QJsonValue v(d, o, e->value);
if (other.value(e->key()) != v)
return false;
@@ -398,7 +405,7 @@ bool QJsonObject::operator==(const QJsonObject &other) const
}
/*!
- \returns \c true if \a other is not equal to this object
+ Returns \c true if \a other is not equal to this object
*/
bool QJsonObject::operator!=(const QJsonObject &other) const
{
@@ -438,9 +445,10 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it)
*/
QJsonObject::iterator QJsonObject::find(const QString &key)
{
- int index = o ? o->indexOf(key) : 0;
- if (index < 0)
- index = o->length;
+ bool keyExists = false;
+ int index = o ? o->indexOf(key, &keyExists) : 0;
+ if (!keyExists)
+ return end();
return iterator(this, index);
}
@@ -458,9 +466,10 @@ QJsonObject::iterator QJsonObject::find(const QString &key)
*/
QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
{
- int index = o ? o->indexOf(key) : 0;
- if (index < 0)
- index = o->length;
+ bool keyExists = false;
+ int index = o ? o->indexOf(key, &keyExists) : 0;
+ if (!keyExists)
+ return end();
return const_iterator(this, index);
}
@@ -471,6 +480,13 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
Same as size().
*/
+/*! \fn int QJsonObject::length() const
+
+ \overload
+
+ Same as size().
+*/
+
/*! \fn QJsonObject::iterator QJsonObject::begin()
Returns an \l{STL-style iterator} pointing to the first item in
@@ -895,33 +911,33 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
void QJsonObject::detach(uint reserve)
{
if (!d) {
- d = new Private::Data(reserve, QJsonValue::Object);
- o = static_cast<Private::Object *>(d->header->root());
+ d = new QJsonPrivate::Data(reserve, QJsonValue::Object);
+ o = static_cast<QJsonPrivate::Object *>(d->header->root());
d->ref.ref();
return;
}
if (reserve == 0 && d->ref.load() == 1)
return;
- Private::Data *x = d->detach(o, reserve);
+ QJsonPrivate::Data *x = d->clone(o, reserve);
x->ref.ref();
if (!d->ref.deref())
delete d;
d = x;
- o = static_cast<Private::Object *>(d->header->root());
+ o = static_cast<QJsonPrivate::Object *>(d->header->root());
}
/*!
\internal
*/
-void QJsonObject::compact() const
+void QJsonObject::compact()
{
if (!d || !d->compactionCounter)
return;
- const_cast<QJsonObject *>(this)->detach();
+ detach();
d->compact();
- const_cast<QJsonObject *>(this)->o = static_cast<Private::Object *>(d->header->root());
+ o = static_cast<QJsonPrivate::Object *>(d->header->root());
}
/*!
@@ -931,7 +947,7 @@ QString QJsonObject::keyAt(int i) const
{
Q_ASSERT(o && i >= 0 && i < (int)o->length);
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
return e->key();
}
@@ -943,7 +959,7 @@ QJsonValue QJsonObject::valueAt(int i) const
if (!o || i < 0 || i >= (int)o->length)
return QJsonValue(QJsonValue::Undefined);
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
return QJsonValue(d, o, e->value);
}
@@ -954,7 +970,7 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
{
Q_ASSERT(o && i >= 0 && i < (int)o->length);
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
insert(e->key(), val);
}
@@ -979,23 +995,20 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
*/
-
-} // namespace QtJson
-
-QT_BEGIN_NAMESPACE
-
-QDebug operator<<(QDebug dbg, const QtJson::QJsonObject &o)
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QJsonObject &o)
{
if (!o.o) {
dbg << "QJsonObject()";
return dbg;
}
QByteArray json;
- QtJson::QJsonWriter::objectToJson(o.o, json, 0, true);
+ QJsonPrivate::Writer::objectToJson(o.o, json, 0, true);
dbg.nospace() << "QJsonObject("
<< json.constData() // print as utf-8 string without extra quotation marks
<< ")";
return dbg.space();
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qjsonobject.h b/src/qjsonobject.h
index d048f15..12e2bca 100644
--- a/src/qjsonobject.h
+++ b/src/qjsonobject.h
@@ -43,16 +43,16 @@
#define QJSONOBJECT_H
#include <qjsonvalue.h>
-#include <qvariant.h>
-#include <qdebug.h>
+
+QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-Q_JSON_EXPORT QDebug operator<<(QDebug, const QtJson::QJsonObject &);
-QT_END_NAMESPACE
-namespace QtJson {
+class QDebug;
+template <class Key, class T> class QMap;
+typedef QMap<QString, QVariant> QVariantMap;
-class Q_JSON_EXPORT QJsonObject
+class Q_CORE_EXPORT QJsonObject
{
public:
QJsonObject();
@@ -67,6 +67,7 @@ public:
QStringList keys() const;
int size() const;
inline int count() const { return size(); }
+ inline int length() const { return size(); }
bool isEmpty() const;
QJsonValue value(const QString &key) const;
@@ -96,8 +97,8 @@ public:
// typedef T *pointer;
typedef QJsonValueRef reference;
- inline iterator() : o(0), i(0) {}
- explicit inline iterator(QJsonObject *obj, int index) : o(obj), i(index) {}
+ Q_DECL_CONSTEXPR inline iterator() : o(0), i(0) {}
+ Q_DECL_CONSTEXPR inline iterator(QJsonObject *obj, int index) : o(obj), i(index) {}
inline QString key() const { return o->keyAt(i); }
inline QJsonValueRef value() const { return QJsonValueRef(o, i); }
@@ -134,8 +135,8 @@ public:
typedef QJsonValue value_type;
typedef QJsonValue reference;
- inline const_iterator() : o(0), i(0) {}
- explicit inline const_iterator(const QJsonObject *obj, int index)
+ Q_DECL_CONSTEXPR inline const_iterator() : o(0), i(0) {}
+ Q_DECL_CONSTEXPR inline const_iterator(const QJsonObject *obj, int index)
: o(obj), i(index) {}
inline const_iterator(const iterator &other)
: o(other.o), i(other.i) {}
@@ -187,26 +188,31 @@ public:
inline bool empty() const { return isEmpty(); }
private:
- friend class Private::Data;
+ friend class QJsonPrivate::Data;
friend class QJsonValue;
friend class QJsonDocument;
- friend class QJsonParser;
friend class QJsonValueRef;
- friend QT_PREPEND_NAMESPACE(QDebug) (QT_PREPEND_NAMESPACE(operator<<)) (QT_PREPEND_NAMESPACE(QDebug) dbg, const QJsonObject &o);
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
- QJsonObject(Private::Data *data, Private::Object *object);
+ QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object);
void detach(uint reserve = 0);
- void compact() const;
+ void compact();
QString keyAt(int i) const;
QJsonValue valueAt(int i) const;
void setValueAt(int i, const QJsonValue &val);
- Private::Data *d;
- Private::Object *o;
+ QJsonPrivate::Data *d;
+ QJsonPrivate::Object *o;
};
-}
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
#endif // QJSONOBJECT_H
diff --git a/src/qjsonparser.cpp b/src/qjsonparser.cpp
index bd0b4fe..d071e35 100644
--- a/src/qjsonparser.cpp
+++ b/src/qjsonparser.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include <qjsonparser_p.h>
-#include <qjson_p.h>
#include <qdebug.h>
+#include "qjsonparser_p.h"
+#include "qjson_p.h"
//#define PARSER_DEBUG
#ifdef PARSER_DEBUG
@@ -55,10 +55,11 @@ static int indent = 0;
#define DEBUG if (1) ; else qDebug()
#endif
+QT_BEGIN_NAMESPACE
-using namespace QtJson;
+using namespace QJsonPrivate;
-QJsonParser::QJsonParser(const char *json, int length)
+Parser::Parser(const char *json, int length)
: json(json), data(0), dataLength(0), current(0)
{
end = json + length;
@@ -108,7 +109,7 @@ enum {
-bool QJsonParser::eatSpace()
+bool Parser::eatSpace()
{
while (json < end) {
if (*json > Space)
@@ -123,7 +124,7 @@ bool QJsonParser::eatSpace()
return (json < end);
}
-char QJsonParser::nextToken()
+char Parser::nextToken()
{
if (!eatSpace())
return 0;
@@ -150,7 +151,7 @@ char QJsonParser::nextToken()
/*
JSON-text = object / array
*/
-QtJson::QJsonDocument QJsonParser::parse()
+QJsonDocument Parser::parse()
{
#ifdef PARSER_DEBUG
indent = 0;
@@ -161,11 +162,11 @@ QtJson::QJsonDocument QJsonParser::parse()
data = (char *)malloc(dataLength);
// fill in Header data
- Private::Header *h = (Private::Header *)data;
+ QJsonPrivate::Header *h = (QJsonPrivate::Header *)data;
h->tag = QJsonDocument::BinaryFormatTag;
h->version = 1u;
- current = sizeof(Private::Header);
+ current = sizeof(QJsonPrivate::Header);
char token = nextToken();
DEBUG << token;
@@ -181,7 +182,7 @@ QtJson::QJsonDocument QJsonParser::parse()
END;
{
- Private::Data *d = new Private::Data(data, current);
+ QJsonPrivate::Data *d = new QJsonPrivate::Data(data, current);
return QJsonDocument(d);
}
@@ -194,8 +195,8 @@ error:
}
-void QJsonParser::ParsedObject::insert(uint offset) {
- const Private::Entry *newEntry = reinterpret_cast<const Private::Entry *>(parser->data + objectPosition + offset);
+void Parser::ParsedObject::insert(uint offset) {
+ const QJsonPrivate::Entry *newEntry = reinterpret_cast<const QJsonPrivate::Entry *>(parser->data + objectPosition + offset);
int min = 0;
int n = offsets.size();
while (n > 0) {
@@ -220,9 +221,9 @@ void QJsonParser::ParsedObject::insert(uint offset) {
end-object
*/
-bool QJsonParser::parseObject()
+bool Parser::parseObject()
{
- int objectOffset = reserveSpace(sizeof(Private::Object));
+ int objectOffset = reserveSpace(sizeof(QJsonPrivate::Object));
BEGIN << "parseObject pos=" << objectOffset << current << json;
ParsedObject parsedObject(this, objectOffset);
@@ -259,7 +260,7 @@ bool QJsonParser::parseObject()
#endif
}
- Private::Object *o = (Private::Object *)(data + objectOffset);
+ QJsonPrivate::Object *o = (QJsonPrivate::Object *)(data + objectOffset);
o->tableOffset = table - objectOffset;
o->size = current - objectOffset;
o->is_object = true;
@@ -273,9 +274,9 @@ bool QJsonParser::parseObject()
/*
member = string name-separator value
*/
-bool QJsonParser::parseMember(int baseOffset)
+bool Parser::parseMember(int baseOffset)
{
- int entryOffset = reserveSpace(sizeof(Private::Entry));
+ int entryOffset = reserveSpace(sizeof(QJsonPrivate::Entry));
BEGIN << "parseMember pos=" << entryOffset;
bool latin1;
@@ -284,12 +285,12 @@ bool QJsonParser::parseMember(int baseOffset)
char token = nextToken();
if (token != NameSeparator)
return false;
- Private::Value val;
+ QJsonPrivate::Value val;
if (!parseValue(&val, baseOffset))
return false;
// finalize the entry
- Private::Entry *e = (Private::Entry *)(data + entryOffset);
+ QJsonPrivate::Entry *e = (QJsonPrivate::Entry *)(data + entryOffset);
e->value = val;
e->value.latinKey = latin1;
@@ -300,12 +301,12 @@ bool QJsonParser::parseMember(int baseOffset)
/*
array = begin-array [ value *( value-separator value ) ] end-array
*/
-bool QJsonParser::parseArray()
+bool Parser::parseArray()
{
BEGIN << "parseArray";
- int arrayOffset = reserveSpace(sizeof(Private::Array));
+ int arrayOffset = reserveSpace(sizeof(QJsonPrivate::Array));
- QVarLengthArray<Private::Value> values;
+ QVarLengthArray<QJsonPrivate::Value> values;
if (!eatSpace())
return false;
@@ -313,7 +314,7 @@ bool QJsonParser::parseArray()
nextToken();
} else {
while (1) {
- Private::Value val;
+ QJsonPrivate::Value val;
if (!parseValue(&val, arrayOffset))
return false;
values.append(val);
@@ -329,12 +330,12 @@ bool QJsonParser::parseArray()
int table = arrayOffset;
// finalize the object
if (values.size()) {
- int tableSize = values.size()*sizeof(Private::Value);
+ int tableSize = values.size()*sizeof(QJsonPrivate::Value);
table = reserveSpace(tableSize);
memcpy(data + table, values.constData(), tableSize);
}
- Private::Array *a = (Private::Array *)(data + arrayOffset);
+ QJsonPrivate::Array *a = (QJsonPrivate::Array *)(data + arrayOffset);
a->tableOffset = table - arrayOffset;
a->size = current - arrayOffset;
a->is_object = false;
@@ -350,7 +351,7 @@ value = false / null / true / object / array / number / string
*/
-bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
+bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset)
{
BEGIN << "parse Value" << json;
val->_dummy = 0;
@@ -375,7 +376,7 @@ bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
*json++ == 'u' &&
*json++ == 'e') {
val->type = QJsonValue::Bool;
- val->val = true;
+ val->value = true;
DEBUG << "value: true";
END;
return true;
@@ -389,7 +390,7 @@ bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
*json++ == 's' &&
*json++ == 'e') {
val->type = QJsonValue::Bool;
- val->val = false;
+ val->value = false;
DEBUG << "value: false";
END;
return true;
@@ -397,7 +398,7 @@ bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
return false;
case Quote: {
val->type = QJsonValue::String;
- val->val = current - baseOffset;
+ val->value = current - baseOffset;
bool latin1;
if (!parseString(&latin1))
return false;
@@ -408,7 +409,7 @@ bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
}
case BeginArray:
val->type = QJsonValue::Array;
- val->val = current - baseOffset;
+ val->value = current - baseOffset;
if (!parseArray())
return false;
DEBUG << "value: array";
@@ -416,7 +417,7 @@ bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
return true;
case BeginObject:
val->type = QJsonValue::Object;
- val->val = current - baseOffset;
+ val->value = current - baseOffset;
if (!parseObject())
return false;
DEBUG << "value: object";
@@ -451,7 +452,7 @@ bool QJsonParser::parseValue(Private::Value *val, int baseOffset)
*/
-bool QJsonParser::parseNumber(Private::Value *val, int baseOffset)
+bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset)
{
BEGIN << "parseNumber" << json;
val->type = QJsonValue::Double;
@@ -499,7 +500,7 @@ bool QJsonParser::parseNumber(Private::Value *val, int baseOffset)
bool ok;
int n = number.toInt(&ok);
if (ok && n < (1<<25) && n > -(1<<25)) {
- val->int_val = n;
+ val->int_value = n;
val->latinOrIntValue = true;
END;
return true;
@@ -518,7 +519,7 @@ bool QJsonParser::parseNumber(Private::Value *val, int baseOffset)
int pos = reserveSpace(sizeof(double));
*(quint64 *)(data + pos) = qToLittleEndian(ui);
- val->val = pos - baseOffset;
+ val->value = pos - baseOffset;
val->latinOrIntValue = false;
END;
@@ -662,7 +663,7 @@ static inline bool scanUtf8Char(const char *&json, const char *end, uint *result
return true;
}
-bool QJsonParser::parseString(bool *latin1)
+bool Parser::parseString(bool *latin1)
{
*latin1 = true;
@@ -700,7 +701,7 @@ bool QJsonParser::parseString(bool *latin1)
// no unicode string, we are done
if (*latin1) {
// write string length
- *(Private::qle_ushort *)(data + stringPos) = current - outStart - sizeof(ushort);
+ *(QJsonPrivate::qle_ushort *)(data + stringPos) = current - outStart - sizeof(ushort);
int pos = reserveSpace((4 - current) & 3);
while (pos & 3)
data[pos++] = 0;
@@ -727,11 +728,11 @@ bool QJsonParser::parseString(bool *latin1)
}
if (ch > 0xffff) {
int pos = reserveSpace(4);
- *(Private::qle_ushort *)(data + pos) = QChar::highSurrogate(ch);
- *(Private::qle_ushort *)(data + pos + 2) = QChar::lowSurrogate(ch);
+ *(QJsonPrivate::qle_ushort *)(data + pos) = QChar::highSurrogate(ch);
+ *(QJsonPrivate::qle_ushort *)(data + pos + 2) = QChar::lowSurrogate(ch);
} else {
int pos = reserveSpace(2);
- *(Private::qle_ushort *)(data + pos) = (ushort)ch;
+ *(QJsonPrivate::qle_ushort *)(data + pos) = (ushort)ch;
}
}
++json;
@@ -740,7 +741,7 @@ bool QJsonParser::parseString(bool *latin1)
return false;
// write string length
- *(Private::qle_int *)(data + stringPos) = (current - outStart - sizeof(int))/2;
+ *(QJsonPrivate::qle_int *)(data + stringPos) = (current - outStart - sizeof(int))/2;
int pos = reserveSpace((4 - current) & 3);
while (pos & 3)
data[pos++] = 0;
@@ -748,3 +749,4 @@ bool QJsonParser::parseString(bool *latin1)
return true;
}
+QT_END_NAMESPACE
diff --git a/src/qjsonparser_p.h b/src/qjsonparser_p.h
index fa08ed5..ab8c82f 100644
--- a/src/qjsonparser_p.h
+++ b/src/qjsonparser_p.h
@@ -56,27 +56,29 @@
#include <qjsondocument.h>
#include <qvarlengtharray.h>
-namespace QtJson {
+QT_BEGIN_NAMESPACE
-class QJsonParser
+namespace QJsonPrivate {
+
+class Parser
{
public:
- QJsonParser(const char *json, int length);
+ Parser(const char *json, int length);
- QtJson::QJsonDocument parse();
+ QJsonDocument parse();
class ParsedObject
{
public:
- ParsedObject(QJsonParser *p, int pos) : parser(p), objectPosition(pos) {}
+ ParsedObject(Parser *p, int pos) : parser(p), objectPosition(pos) {}
void insert(uint offset);
- QJsonParser *parser;
+ Parser *parser;
int objectPosition;
QVarLengthArray<uint> offsets;
- inline Private::Entry *entryAt(int i) const {
- return reinterpret_cast<Private::Entry *>(parser->data + objectPosition + offsets[i]);
+ inline QJsonPrivate::Entry *entryAt(int i) const {
+ return reinterpret_cast<QJsonPrivate::Entry *>(parser->data + objectPosition + offsets[i]);
}
};
@@ -89,8 +91,8 @@ private:
bool parseArray();
bool parseMember(int baseOffset);
bool parseString(bool *latin1);
- bool parseValue(Private::Value *val, int baseOffset);
- bool parseNumber(Private::Value *val, int baseOffset);
+ bool parseValue(QJsonPrivate::Value *val, int baseOffset);
+ bool parseNumber(QJsonPrivate::Value *val, int baseOffset);
const char *json;
const char *end;
@@ -110,4 +112,7 @@ private:
};
}
+
+QT_END_NAMESPACE
+
#endif
diff --git a/src/qjsonvalue.cpp b/src/qjsonvalue.cpp
index 50208f8..bd93cbf 100644
--- a/src/qjsonvalue.cpp
+++ b/src/qjsonvalue.cpp
@@ -42,14 +42,14 @@
#include <qjsonobject.h>
#include <qjsonvalue.h>
#include <qjsonarray.h>
-#include <qjson_p.h>
#include <qjsonarray.h>
-
#include <qvariant.h>
#include <qstringlist.h>
#include <qdebug.h>
-namespace QtJson {
+#include "qjson_p.h"
+
+QT_BEGIN_NAMESPACE
/*!
\class QJsonValue
@@ -89,14 +89,14 @@ namespace QtJson {
The default is to create a Null value.
*/
QJsonValue::QJsonValue(Type type)
- : t(type), d(0), dbl(0.)
+ : ui(0), d(0), t(type)
{
}
/*!
\internal
*/
-QJsonValue::QJsonValue(Private::Data *data, Private::Base *base, const Private::Value &v)
+QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base, const QJsonPrivate::Value &v)
: d(0)
{
t = (Type)(uint)v.type;
@@ -113,14 +113,14 @@ QJsonValue::QJsonValue(Private::Data *data, Private::Base *base, const Private::
break;
case String: {
QString s = v.toString(base);
- stringData = *reinterpret_cast<QStringData **>(&s);
+ stringData = s.data_ptr();
stringData->ref.ref();
break;
}
case Array:
case Object:
d = data;
- this->base = v.objectOrArray(base);
+ this->base = v.base(base);
break;
}
if (d)
@@ -131,7 +131,7 @@ QJsonValue::QJsonValue(Private::Data *data, Private::Base *base, const Private::
Creates a value of type Bool, with value \a b.
*/
QJsonValue::QJsonValue(bool b)
- : t(Bool), d(0)
+ : d(0), t(Bool)
{
this->b = b;
}
@@ -140,7 +140,7 @@ QJsonValue::QJsonValue(bool b)
Creates a value of type Double, with value \a n.
*/
QJsonValue::QJsonValue(double n)
- : t(Double), d(0)
+ : d(0), t(Double)
{
this->dbl = n;
}
@@ -150,7 +150,7 @@ QJsonValue::QJsonValue(double n)
Creates a value of type Double, with value \a n.
*/
QJsonValue::QJsonValue(int n)
- : t(Double), d(0)
+ : d(0), t(Double)
{
this->dbl = n;
}
@@ -159,7 +159,7 @@ QJsonValue::QJsonValue(int n)
Creates a value of type String, with value \a s.
*/
QJsonValue::QJsonValue(const QString &s)
- : t(String), d(0)
+ : d(0), t(String)
{
stringData = *(QStringData **)(&s);
stringData->ref.ref();
@@ -169,7 +169,7 @@ QJsonValue::QJsonValue(const QString &s)
Creates a value of type String, with value \a s.
*/
QJsonValue::QJsonValue(const QLatin1String &s)
- : t(String), d(0)
+ : d(0), t(String)
{
// ### FIXME: Avoid creating the temp QString below
QString str(s);
@@ -181,9 +181,8 @@ QJsonValue::QJsonValue(const QLatin1String &s)
Creates a value of type Array, with value \a a.
*/
QJsonValue::QJsonValue(const QJsonArray &a)
- : t(Array), d(a.d)
+ : d(a.d), t(Array)
{
- a.compact();
base = a.a;
if (d)
d->ref.ref();
@@ -193,9 +192,8 @@ QJsonValue::QJsonValue(const QJsonArray &a)
Creates a value of type Object, with value \a o.
*/
QJsonValue::QJsonValue(const QJsonObject &o)
- : t(Object), d(o.d)
+ : d(o.d), t(Object)
{
- o.compact();
base = o.o;
if (d)
d->ref.ref();
@@ -332,9 +330,9 @@ QVariant QJsonValue::toVariant() const
case String:
return toString();
case Array:
- return QJsonArray(d, static_cast<Private::Array *>(base)).toVariantList();
+ return QJsonArray(d, static_cast<QJsonPrivate::Array *>(base)).toVariantList();
case Object:
- return QJsonObject(d, static_cast<Private::Object *>(base)).toVariantMap();
+ return QJsonObject(d, static_cast<QJsonPrivate::Object *>(base)).toVariantMap();
case Null:
case Undefined:
break;
@@ -415,7 +413,7 @@ QJsonArray QJsonValue::toArray() const
if (!d || t != Array)
return QJsonArray();
- return QJsonArray(d, static_cast<Private::Array *>(base));
+ return QJsonArray(d, static_cast<QJsonPrivate::Array *>(base));
}
/*!
@@ -428,7 +426,7 @@ QJsonObject QJsonValue::toObject() const
if (!d || t != Object)
return QJsonObject();
- return QJsonObject(d, static_cast<Private::Object *>(base));
+ return QJsonObject(d, static_cast<QJsonPrivate::Object *>(base));
}
/*!
@@ -450,11 +448,11 @@ bool QJsonValue::operator==(const QJsonValue &other) const
case String:
return toString() == other.toString();
case Array:
- return QJsonArray(d, static_cast<Private::Array *>(base))
- == QJsonArray(other.d, static_cast<Private::Array *>(other.base));
+ return QJsonArray(d, static_cast<QJsonPrivate::Array *>(base))
+ == QJsonArray(other.d, static_cast<QJsonPrivate::Array *>(other.base));
case Object:
- return QJsonObject(d, static_cast<Private::Object *>(base))
- == QJsonObject(other.d, static_cast<Private::Object *>(other.base));
+ return QJsonObject(d, static_cast<QJsonPrivate::Object *>(base))
+ == QJsonObject(other.d, static_cast<QJsonPrivate::Object *>(other.base));
}
return true;
}
@@ -475,12 +473,12 @@ void QJsonValue::detach()
if (!d)
return;
- Private::Data *x = d->detach(base);
+ QJsonPrivate::Data *x = d->clone(base);
x->ref.ref();
if (!d->ref.deref())
delete d;
d = x;
- base = static_cast<Private::Object *>(d->header->root());
+ base = static_cast<QJsonPrivate::Object *>(d->header->root());
}
@@ -509,11 +507,11 @@ void QJsonValue::detach()
QJsonValueRef &QJsonValueRef::operator =(const QJsonValue &val)
{
- if (is_object) {
+ if (is_object)
o->setValueAt(index, val);
- } else {
+ else
a->replace(index, val);
- }
+
return *this;
}
@@ -534,35 +532,31 @@ QJsonValue QJsonValueRef::toValue() const
return o->valueAt(index);
}
-
-} // namespace QtJson
-
-QT_BEGIN_NAMESPACE
-
-QDebug operator<<(QDebug dbg, const QtJson::QJsonValue &o)
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QJsonValue &o)
{
switch (o.t) {
- case QtJson::QJsonValue::Undefined:
+ case QJsonValue::Undefined:
dbg.nospace() << "QJsonValue(undefined)";
break;
- case QtJson::QJsonValue::Null:
+ case QJsonValue::Null:
dbg.nospace() << "QJsonValue(null)";
break;
- case QtJson::QJsonValue::Bool:
+ case QJsonValue::Bool:
dbg.nospace() << "QJsonValue(bool, " << o.toBool() << ")";
break;
- case QtJson::QJsonValue::Double:
+ case QJsonValue::Double:
dbg.nospace() << "QJsonValue(double, " << o.toDouble() << ")";
break;
- case QtJson::QJsonValue::String:
+ case QJsonValue::String:
dbg.nospace() << "QJsonValue(string, " << o.toString() << ")";
break;
- case QtJson::QJsonValue::Array:
+ case QJsonValue::Array:
dbg.nospace() << "QJsonValue(array, ";
dbg.nospace() << o.toArray();
dbg.nospace() << ")";
break;
- case QtJson::QJsonValue::Object:
+ case QJsonValue::Object:
dbg.nospace() << "QJsonValue(object, ";
dbg.nospace() << o.toObject();
dbg.nospace() << ")";
@@ -570,5 +564,6 @@ QDebug operator<<(QDebug dbg, const QtJson::QJsonValue &o)
}
return dbg.space();
}
+#endif
QT_END_NAMESPACE
diff --git a/src/qjsonvalue.h b/src/qjsonvalue.h
index ddc1054..6efb50b 100644
--- a/src/qjsonvalue.h
+++ b/src/qjsonvalue.h
@@ -42,16 +42,30 @@
#ifndef QJSONVALUE_H
#define QJSONVALUE_H
-#include <qjsonglobal.h>
+#include <qglobal.h>
+#include <qstring.h>
+
+QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QVariant;
-Q_JSON_EXPORT QDebug operator<<(QDebug, const QtJson::QJsonValue &);
-QT_END_NAMESPACE
-namespace QtJson {
+class QDebug;
+class QVariant;
+class QJsonArray;
+class QJsonObject;
+
+namespace QJsonPrivate {
+ class Data;
+ class Base;
+ class Object;
+ class Header;
+ class Array;
+ class Value;
+ class Entry;
+};
-class Q_JSON_EXPORT QJsonValue {
+class Q_CORE_EXPORT QJsonValue
+{
public:
enum Type {
Null = 0x0,
@@ -101,27 +115,27 @@ public:
private:
// avoid implicit conversions from char * to bool
inline QJsonValue(const void *) {}
- friend class Private::Value;
+ friend class QJsonPrivate::Value;
friend class QJsonArray;
friend class QJsonObject;
- friend QT_PREPEND_NAMESPACE(QDebug) (QT_PREPEND_NAMESPACE(operator<<)) (QT_PREPEND_NAMESPACE(QDebug), const QJsonValue &);
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
- QJsonValue(Private::Data *d, Private::Base *b, const Private::Value& v);
+ QJsonValue(QJsonPrivate::Data *d, QJsonPrivate::Base *b, const QJsonPrivate::Value& v);
void detach();
- Type t;
- Private::Data *d; // needed for Objects and Arrays
union {
quint64 ui;
bool b;
double dbl;
QStringData *stringData;
- Private::Base *base;
+ QJsonPrivate::Base *base;
};
+ QJsonPrivate::Data *d; // needed for Objects and Arrays
+ Type t;
};
-class Q_JSON_EXPORT QJsonValueRef
+class Q_CORE_EXPORT QJsonValueRef
{
public:
QJsonValueRef(QJsonArray *array, int idx)
@@ -161,6 +175,12 @@ private:
uint index : 31;
};
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
-}
#endif // QJSONVALUE_H
diff --git a/src/qjsonwriter.cpp b/src/qjsonwriter.cpp
index d709cbc..1911b49 100644
--- a/src/qjsonwriter.cpp
+++ b/src/qjsonwriter.cpp
@@ -39,13 +39,15 @@
**
****************************************************************************/
-#include <qjsonwriter_p.h>
-#include <qjson_p.h>
+#include "qjsonwriter_p.h"
+#include "qjson_p.h"
-using namespace QtJson;
+QT_BEGIN_NAMESPACE
-static void objectContentToJson(const Private::Object *o, QByteArray &json, int indent, bool compact);
-static void arrayContentToJson(const Private::Array *a, QByteArray &json, int indent, bool compact);
+using namespace QJsonPrivate;
+
+static void objectContentToJson(const QJsonPrivate::Object *o, QByteArray &json, int indent, bool compact);
+static void arrayContentToJson(const QJsonPrivate::Array *a, QByteArray &json, int indent, bool compact);
// some code from qutfcodec.cpp, inlined here for performance reasons
// to allow fast escaping of strings
@@ -83,7 +85,7 @@ static QByteArray escapedString(const QString &s)
while (ch < end) {
if (cursor >= ba_end - 6) {
// ensure we have enough space
- int pos = cursor - (uchar *)ba.constData();
+ int pos = cursor - (const uchar *)ba.constData();
ba.resize(ba.size()*2);
cursor = (uchar *)ba.data() + pos;
ba_end = (const uchar *)ba.constData() + ba.length();
@@ -175,7 +177,7 @@ static QByteArray escapedString(const QString &s)
return ba;
}
-static void valueToJson(const Private::Base *b, const Private::Value &v, QByteArray &json, int indent, bool compact)
+static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &v, QByteArray &json, int indent, bool compact)
{
QJsonValue::Type type = (QJsonValue::Type)(uint)v.type;
switch (type) {
@@ -192,13 +194,13 @@ static void valueToJson(const Private::Base *b, const Private::Value &v, QByteAr
break;
case QJsonValue::Array:
json += compact ? "[" : "[\n";
- arrayContentToJson(static_cast<Private::Array *>(v.objectOrArray(b)), json, indent + (compact ? 0 : 1), compact);
+ arrayContentToJson(static_cast<QJsonPrivate::Array *>(v.base(b)), json, indent + (compact ? 0 : 1), compact);
json += QByteArray(4*indent, ' ');
json += "]";
break;
case QJsonValue::Object:
json += compact ? "{" : "{\n";
- objectContentToJson(static_cast<Private::Object *>(v.objectOrArray(b)), json, indent + (compact ? 0 : 1), compact);
+ objectContentToJson(static_cast<QJsonPrivate::Object *>(v.base(b)), json, indent + (compact ? 0 : 1), compact);
json += QByteArray(4*indent, ' ');
json += "}";
break;
@@ -208,7 +210,7 @@ static void valueToJson(const Private::Base *b, const Private::Value &v, QByteAr
}
}
-static void arrayContentToJson(const Private::Array *a, QByteArray &json, int indent, bool compact)
+static void arrayContentToJson(const QJsonPrivate::Array *a, QByteArray &json, int indent, bool compact)
{
if (!a || !a->length)
return;
@@ -231,7 +233,7 @@ static void arrayContentToJson(const Private::Array *a, QByteArray &json, int in
}
-static void objectContentToJson(const Private::Object *o, QByteArray &json, int indent, bool compact)
+static void objectContentToJson(const QJsonPrivate::Object *o, QByteArray &json, int indent, bool compact)
{
if (!o || !o->length)
return;
@@ -240,7 +242,7 @@ static void objectContentToJson(const Private::Object *o, QByteArray &json, int
uint i = 0;
while (1) {
- Private::Entry *e = o->entryAt(i);
+ QJsonPrivate::Entry *e = o->entryAt(i);
json += indentString;
json += '"';
json += escapedString(e->key());
@@ -257,7 +259,7 @@ static void objectContentToJson(const Private::Object *o, QByteArray &json, int
}
}
-void QJsonWriter::objectToJson(const Private::Object *o, QByteArray &json, int indent, bool compact)
+void Writer::objectToJson(const QJsonPrivate::Object *o, QByteArray &json, int indent, bool compact)
{
json.reserve(json.size() + (o ? o->size : 16));
json += compact ? "{" : "{\n";
@@ -266,7 +268,7 @@ void QJsonWriter::objectToJson(const Private::Object *o, QByteArray &json, int i
json += compact ? "}" : "}\n";
}
-void QJsonWriter::arrayToJson(const Private::Array *a, QByteArray &json, int indent, bool compact)
+void Writer::arrayToJson(const QJsonPrivate::Array *a, QByteArray &json, int indent, bool compact)
{
json.reserve(json.size() + (a ? a->size : 16));
json += compact ? "[" : "[\n";
@@ -274,3 +276,5 @@ void QJsonWriter::arrayToJson(const Private::Array *a, QByteArray &json, int ind
json += QByteArray(4*indent, ' ');
json += compact ? "]" : "]\n";
}
+
+QT_END_NAMESPACE
diff --git a/src/qjsonwriter_p.h b/src/qjsonwriter_p.h
index 65b7eb6..f517b8e 100644
--- a/src/qjsonwriter_p.h
+++ b/src/qjsonwriter_p.h
@@ -39,7 +39,8 @@
**
****************************************************************************/
-#include <qjsonglobal.h>
+#ifndef QJSONWRITER_P_H
+#define QJSONWRITER_P_H
//
// W A R N I N G
@@ -51,16 +52,22 @@
//
// We mean it.
//
-#include <qjsonglobal.h>
+#include <qjsonvalue.h>
-namespace QtJson
+QT_BEGIN_NAMESPACE
+
+namespace QJsonPrivate
{
-class QJsonWriter
+class Writer
{
public:
- static void objectToJson(const Private::Object *o, QByteArray &json, int indent, bool compact = false);
- static void arrayToJson(const Private::Array *a, QByteArray &json, int indent, bool compact = false);
+ static void objectToJson(const QJsonPrivate::Object *o, QByteArray &json, int indent, bool compact = false);
+ static void arrayToJson(const QJsonPrivate::Array *a, QByteArray &json, int indent, bool compact = false);
};
}
+
+QT_END_NAMESPACE
+
+#endif