Debugger: Fix QJson dumper for Qt >= 5.15

Storage is internally based on QCbor now.

Since this works better when having dumpers for QCbor values,
add those, too, for Numbers, Strings, Arrays, Maps for now.
None of the custom types.

Fixes: QTCREATORBUG-23827
Change-Id: Idf281d859aaf8556d9895646bbc091af85b34157
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2020-05-29 13:08:55 +02:00
parent 63bb91f0b7
commit 28d34d196e
3 changed files with 400 additions and 42 deletions

View File

@@ -558,30 +558,32 @@ class DumperBase():
return 0, size
return size, limit
def vectorDataHelper(self, addr):
def vectorDataHelper(self, vector_data_ptr):
# vector_data_ptr is what is e.g. stored in a QVector's d_ptr.
if self.qtVersion() >= 0x050000:
if self.ptrSize() == 4:
(ref, size, alloc, offset) = self.split('IIIp', addr)
(ref, size, alloc, offset) = self.split('IIIp', vector_data_ptr)
else:
(ref, size, alloc, pad, offset) = self.split('IIIIp', addr)
(ref, size, alloc, pad, offset) = self.split('IIIIp', vector_data_ptr)
alloc = alloc & 0x7ffffff
data = addr + offset
data = vector_data_ptr + offset
else:
(ref, alloc, size) = self.split('III', addr)
data = addr + 16
(ref, alloc, size) = self.split('III', vector_data_ptr)
data = vector_data_ptr + 16
self.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
return data, size, alloc
def byteArrayDataHelper(self, addr):
def byteArrayDataHelper(self, bytearray_data_ptr):
# bytearray_data_ptr is what is e.g. stored in a QByteArray's d_ptr.
if self.qtVersion() >= 0x050000:
# QTypedArray:
# - QtPrivate::RefCount ref
# - int size
# - uint alloc : 31, capacityReserved : 1
# - qptrdiff offset
(ref, size, alloc, offset) = self.split('IIpp', addr)
(ref, size, alloc, offset) = self.split('IIpp', bytearray_data_ptr)
alloc = alloc & 0x7ffffff
data = addr + offset
data = bytearray_data_ptr + offset
if self.ptrSize() == 4:
data = data & 0xffffffff
else:
@@ -593,19 +595,19 @@ class DumperBase():
# - [padding]
# - char *data;
if self.ptrSize() == 4:
(ref, alloc, size, data) = self.split('IIIp', addr)
(ref, alloc, size, data) = self.split('IIIp', bytearray_data_ptr)
else:
(ref, alloc, size, pad, data) = self.split('IIIIp', addr)
(ref, alloc, size, pad, data) = self.split('IIIIp', bytearray_data_ptr)
else:
# Data:
# - QShared count;
# - QChar *unicode
# - char *ascii
# - uint len: 30
(dummy, dummy, dummy, size) = self.split('IIIp', addr)
size = self.extractInt(addr + 3 * self.ptrSize()) & 0x3ffffff
(dummy, dummy, dummy, size) = self.split('IIIp', bytearray_data_ptr)
size = self.extractInt(bytearray_data_ptr + 3 * self.ptrSize()) & 0x3ffffff
alloc = size # pretend.
data = self.extractPointer(addr + self.ptrSize())
data = self.extractPointer(bytearray_data_ptr + self.ptrSize())
return data, size, alloc
# addr is the begin of a QByteArrayData structure
@@ -3844,6 +3846,17 @@ class DumperBase():
return val
raise RuntimeError('EXPECTING ADDRESS OR BYTES, GOT %s' % type(datish))
def createProxyValue(self, proxy_data, type_name):
tdata = self.TypeData(self)
tdata.name = type_name
tdata.typeId = type_name
tdata.code = TypeCode.Struct
self.registerType(type_name, tdata)
val = self.Value(self)
val.type = self.Type(self, type_name)
val.ldata = proxy_data
return val
def createContainerItem(self, data, innerTypish, container):
innerType = self.createType(innerTypish)
name = self.qtNamespace() + '%s<%s>' % (container, innerType.name)

View File

@@ -24,9 +24,10 @@
############################################################################
import platform
import struct
import re
from dumper import Children, SubItem, UnnamedSubItem, toInteger
from utils import DisplayFormat
from dumper import Children, SubItem, UnnamedSubItem, toInteger, DumperBase
from utils import DisplayFormat, TypeCode
def qdump__QAtomicInt(d, value):
@@ -2969,6 +2970,12 @@ def qdumpHelper_QJsonObject(d, data, obj):
def qdump__QJsonValue(d, value):
(data, dd, t) = value.split('QpI')
if d.qtVersion() >= 0x050f00:
value = d.createProxyValue((data, dd, t, False), 'QCborValue_proxy')
d.putItem(value)
return
if t == 0:
d.putType('QJsonValue (Null)')
d.putValue('Null')
@@ -3005,10 +3012,20 @@ def qdump__QJsonValue(d, value):
def qdump__QJsonArray(d, value):
if d.qtVersion() >= 0x050f00:
_, container_ptr = value.split('pp')
qdumpHelper_QCbor_array(d, container_ptr, False)
return
qdumpHelper_QJsonArray(d, value['d'].pointer(), value['a'].pointer())
def qdump__QJsonObject(d, value):
if d.qtVersion() >= 0x050f00:
_, container_ptr = value.split('pp')
qdumpHelper_QCbor_map(d, container_ptr, False)
return
qdumpHelper_QJsonObject(d, value['d'].pointer(), value['o'].pointer())
@@ -3077,3 +3094,187 @@ def qdump__qfloat16(d, value):
d.putValue(res)
d.putNumChild(1)
d.putPlainChildren(value)
def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes):
# d.split('i@{QByteArray::size_type}pp', container_ptr) doesn't work with CDB, so be explicit:
offset = 2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8
data_d_ptr, elements_d_ptr = d.split('pp', container_ptr + offset)
elements_data_ptr, elements_size, _ = d.vectorDataHelper(elements_d_ptr)
element_at_n_addr = elements_data_ptr + element_index * 16 # sizeof(QtCbor::Element) == 15
element_value, _, element_flags = d.split('qII', element_at_n_addr)
enc = 'latin1' if is_bytes or (element_flags & 8) else 'utf16'
bytedata, _, _ = d.byteArrayDataHelper(data_d_ptr)
bytedata += element_value
if d.qtVersion() >= 0x060000:
bytedata_len = d.extractInt64(bytedata)
bytedata_data = bytedata + 8
else:
bytedata_len = d.extractInt(bytedata)
bytedata_data = bytedata + 4 # sizeof(QtCbor::ByteData) header part
elided, shown = d.computeLimit(bytedata_len, d.displayStringLimit)
res = d.readMemory(bytedata_data, shown)
d.putValue(res, enc, elided=elided)
def qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, idx, bytedata, is_cbor):
element_at_n_addr = elements_data_ptr + idx * 16 # sizeof(QtCbor::Element) == 15
element_value, element_type, element_flags = d.split('qII', element_at_n_addr)
element_container, _, _ = d.split('pII', element_at_n_addr)
if element_flags & 1: # QtCbor::Element::IsContainer
return d.createProxyValue((-1, element_container, element_type, is_cbor), 'QCborValue_proxy')
if element_flags & 2: # QtCbor::Element::HasByteData
return d.createProxyValue((idx, container_ptr, element_type, is_cbor), 'QCborValue_proxy')
return d.createProxyValue((element_value, 0, element_type, is_cbor), 'QCborValue_proxy')
def qdumpHelper_QCbor_array(d, container_ptr, is_cbor):
if not container_ptr:
d.putItemCount(0)
return
# d.split('i@{QByteArray::size_type}pp', container_ptr) doesn't work with CDB, so be explicit:
offset = 2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8
data_d_ptr, elements_d_ptr = d.split('pp', container_ptr + offset)
elements_data_ptr, elements_size, _ = d.vectorDataHelper(elements_d_ptr)
d.putItemCount(elements_size)
if d.isExpanded():
bytedata, _, _ = d.byteArrayDataHelper(data_d_ptr)
with Children(d, maxNumChild=1000):
for i in range(elements_size):
d.putSubItem(i, qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, i, bytedata, is_cbor))
def qdump__QCborArray(d, value):
container_ptr = value.extractPointer()
qdumpHelper_QCbor_array(d, container_ptr, True)
def qdumpHelper_QCbor_map(d, container_ptr, is_cbor):
if not container_ptr:
d.putItemCount(0)
return
# d.split('i@{QByteArray::size_type}pp', container_ptr) doesn't work with CDB, so be explicit:
offset = 2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8
data_d_ptr, elements_d_ptr = d.split('pp', container_ptr + offset)
elements_data_ptr, elements_size, _ = d.vectorDataHelper(elements_d_ptr)
elements_size = int(elements_size / 2)
d.putItemCount(elements_size)
if d.isExpanded():
bytedata, _, _ = d.byteArrayDataHelper(data_d_ptr)
with Children(d, maxNumChild=1000):
for i in range(elements_size):
key = qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, 2 * i, bytedata, is_cbor)
val = qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, 2 * i + 1, bytedata, is_cbor)
d.putPairItem(i, (key, val), 'key', 'value')
def qdump__QCborMap(d, value):
container_ptr = value.extractPointer()
qdumpHelper_QCbor_map(d, container_ptr, True)
def qdump__QCborValue(d, value):
item_data, container_ptr, item_type = value.split('qpi')
d.putItem(d.createProxyValue((item_data, container_ptr, item_type, True), 'QCborValue_proxy'))
def qdump__QCborValue_proxy(d, value):
item_data, container_ptr, item_type, is_cbor = value.data()
def typename(key, is_cbor):
if is_cbor:
return {
'invalid' : 'QCborValue (Invalid)',
'int' : 'QCborValue (Integer)',
'false' : 'QCborValue (False)',
'true' : 'QCborValue (True)',
'null' : 'QCborValue (Null)',
'undefined' : 'QCborValue (Undefined)',
'double' : 'QCborValue (Double)',
'bytes' : 'QCborValue (ByteArray)',
'string' : 'QCborValue (String)',
'map' : 'QCborValue (Map)',
'array' : 'QCborValue (Array)'
}.get(key, 'QCborValue (Unknown)')
else:
return {
'invalid' : 'QJsonValue (Invalid)',
'int' : 'QJsonValue (Number)',
'false' : 'QJsonValue (Bool)',
'true' : 'QJsonValue (Bool)',
'null' : 'QJsonValue (Null)',
'undefined' : 'QJsonValue (Undefined)',
'double' : 'QJsonValue (Number)',
'bytes' : 'QJsonValue (ByteArray)',
'string' : 'QJsonValue (String)',
'map' : 'QJsonValue (Object)',
'array' : 'QJsonValue (Array)'
}.get(key, 'QJsonValue (Unknown)')
if item_type == 0xffffffffffffffff:
d.putType(typename('invalid', is_cbor))
d.putValue('Invalid')
elif item_type == 0x00:
d.putType(typename('int', is_cbor))
d.putValue(item_data)
elif item_type == 0x100 + 20:
d.putType(typename('false', is_cbor))
d.putValue('False')
elif item_type == 0x100 + 21:
d.putType(typename('true', is_cbor))
d.putValue('True')
elif item_type == 0x100 + 22:
d.putType(typename('null', is_cbor))
d.putValue('Null')
elif item_type == 0x100 + 23:
d.putType(typename('undefined', is_cbor))
d.putValue('Undefined')
elif item_type == 0x202:
val = struct.unpack('d', struct.pack('q', item_data))
d.putType(typename('double', is_cbor))
d.putValue('%f' % val)
elif item_type == 0x40:
d.putType(typename('bytes', is_cbor))
qdumpHelper_QCbor_string(d, container_ptr, item_data, True)
elif item_type == 0x60:
d.putType(typename('string', is_cbor))
qdumpHelper_QCbor_string(d, container_ptr, item_data, False)
elif item_type == 0x80:
d.putType(typename('array', is_cbor))
qdumpHelper_QCbor_array(d, container_ptr, is_cbor)
elif item_type == 0xa0:
d.putType(typename('map', is_cbor))
qdumpHelper_QCbor_map(d, container_ptr, is_cbor)
elif item_type == 0x10000:
d.putType('QCborValue (DateTime)')
d.putValue('DateTime')
elif item_type == 0x10020:
d.putType('QCborValue (Url)')
d.putValue('Url')
elif item_type == 0x10023:
d.putType('QCborValue (RegularExpression)')
d.putValue('RegularExpression')
elif item_type == 0x10025:
d.putType('QCborValue (Uuid)')
d.putValue('Uuid')
else:
d.putType('QCborValue (Unknown)')
d.putValue(item_data)

View File

@@ -7175,6 +7175,127 @@ void tst_Dumpers::dumper_data()
+ Check("p", "<5 items>", "@QGraphicsPolygonItem");
QTest::newRow("QCbor")
<< Data("#include <QString>\n"
"#if QT_VERSION >= 0x050c00\n"
"#include <QCborArray>\n"
"#include <QCborMap>\n"
"#include <QCborValue>\n"
"#include <QVariantMap>\n"
"#endif\n",
"#if QT_VERSION >= 0x050c00\n"
"QCborMap ob0;\n"
"QCborMap ob = QCborMap::fromVariantMap({\n"
" {\"a\", 1},\n"
" {\"bb\", 2},\n"
" {\"ccc\", \"hallo\"},\n"
" {\"s\", \"ssss\"}\n"
"});\n"
"ob.insert(QLatin1String(\"d\"), QCborMap::fromVariantMap({{\"ddd\", 1234}}));\n"
"\n"
"QCborValue a0;\n"
"QCborValue a1(1);\n"
"QCborValue a2(\"asd\");\n"
"QCborValue a3(QString::fromUtf8(\"cöder\"));\n"
"QCborValue a4(1.4);\n"
"QCborValue a5(true);\n"
"QCborValue a6(QByteArray(\"cder\"));\n"
"\n"
"QCborArray aa;\n"
"QCborArray a;\n"
"a.append(a1);\n"
"a.append(a2);\n"
"a.append(a3);\n"
"a.append(a4);\n"
"a.append(a5);\n"
"a.append(a0);\n"
"a.append(ob);\n"
"\n"
"QCborArray b;\n"
"b.append(QCborValue(1));\n"
"b.append(a);\n"
"b.append(QCborValue(2));\n"
"\n"
"QCborArray c;\n"
"for (unsigned int i = 0; i < 32; ++i) {\n"
" c.append(QCborValue(qint64(1u << i) - 1));\n"
" c.append(QCborValue(qint64(1u << i)));\n"
" c.append(QCborValue(qint64(1u << i) + 1));\n"
"}\n"
"for (unsigned int i = 0; i < 32; ++i) {\n"
" c.append(QCborValue(-qint64(1u << i) + 1));\n"
" c.append(QCborValue(-qint64(1u << i)));\n"
" c.append(QCborValue(-qint64(1u << i) - 1));\n"
"}"
"unused(&b, &a, &aa);\n"
"#endif\n",
"")
+ Cxx11Profile()
+ CoreProfile()
+ QtVersion(0x50f00)
+ MsvcVersion(1900)
+ Check("a0", "Undefined", "QCborValue (Undefined)")
+ Check("a1", "1", "QCborValue (Integer)")
+ Check("a2", "\"asd\"", "QCborValue (String)")
+ Check("a3", "\"cöder\"", "QCborValue (String)")
+ Check("a4", "1.400000", "QCborValue (Double)")
+ Check("a5", "True", "QCborValue (True)")
+ Check("a6", "\"cder\"", "QCborValue (ByteArray)")
+ Check("aa", "<0 items>", "@QCborArray")
+ Check("a", "<7 items>", "@QCborArray")
+ Check("a.0", "[0]", "1", "QCborValue (Integer)")
+ Check("a.1", "[1]", "\"asd\"", "QCborValue (String)")
+ Check("a.2", "[2]", "\"cöder\"", "QCborValue (String)")
+ Check("a.3", "[3]", "1.400000", "QCborValue (Double)")
+ Check("a.4", "[4]", "True", "QCborValue (True)")
+ Check("a.5", "[5]", "Undefined", "QCborValue (Undefined)")
+ Check("a.6", "[6]", "<5 items>", "QCborValue (Map)")
+ Check("a.6.0", "[0] \"a\"", "1", "")
+ Check("a.6.1", "[1] \"bb\"", "2", "")
+ Check("a.6.2", "[2] \"ccc\"", "\"hallo\"", "")
+ Check("a.6.3", "[3] \"s\"", "\"ssss\"", "")
+ Check("a.6.4", "[4] \"d\"", "<1 items>", "")
+ Check("b", "b", "<3 items>" , "@QCborArray")
+ Check("b.0", "[0]", "1", "QCborValue (Integer)")
+ Check("b.1", "[1]", "<7 items>", "QCborValue (Array)")
+ Check("b.1.0", "[0]", "1", "QCborValue (Integer)")
+ Check("b.1.1", "[1]", "\"asd\"", "QCborValue (String)")
+ Check("b.1.2", "[2]", "\"cöder\"", "QCborValue (String)")
+ Check("b.1.3", "[3]", "1.400000", "QCborValue (Double)")
+ Check("b.1.4", "[4]", "True", "QCborValue (True)")
+ Check("b.1.5", "[5]", "Undefined", "QCborValue (Undefined)")
+ Check("b.1.6", "[6]", "<5 items>", "QCborValue (Map)")
+ Check("b.2", "[2]", "2", "QCborValue (Integer)")
+ Check("c", "c", "<192 items>", "@QCborArray")
+ Check("c.0", "[0]", "0", "QCborValue (Integer)")
+ Check("c.1", "[1]", "1", "QCborValue (Integer)")
+ Check("c.78", "[78]", "67108863", "QCborValue (Integer)")
+ Check("c.79", "[79]", "67108864", "QCborValue (Integer)")
+ Check("c.94", "[94]", "2147483648", "QCborValue (Integer)")
+ Check("c.95", "[95]", "2147483649", "QCborValue (Integer)")
+ Check("c.96", "[96]", "0", "QCborValue (Integer)")
+ Check("c.97", "[97]", "-1", "QCborValue (Integer)")
+ Check("c.174", "[174]", "-67108863", "QCborValue (Integer)")
+ Check("c.175", "[175]", "-67108864", "QCborValue (Integer)")
+ Check("ob0", "ob0", "<0 items>", "@QCborMap")
+ Check("ob", "ob", "<5 items>", "@QCborMap")
+ Check("ob.0", "[0] \"a\"", "1", "")
+ Check("ob.0.key", "key", "\"a\"", "QCborValue (String)")
+ Check("ob.0.value", "value", "1", "QCborValue (Integer)")
+ Check("ob.1", "[1] \"bb\"", "2", "")
+ Check("ob.2", "[2] \"ccc\"", "\"hallo\"", "")
+ Check("ob.3", "[3] \"s\"", "\"ssss\"", "")
+ Check("ob.4", "[4] \"d\"", "<1 items>", "")
;
const QtVersion jsonv1{0, 0x50e00};
const QtVersion jsonv2{0x50e00};
QTest::newRow("QJson")
<< Data("#include <QString>\n"
"#if QT_VERSION >= 0x050000\n"
@@ -7185,6 +7306,7 @@ void tst_Dumpers::dumper_data()
"#endif\n",
"#if QT_VERSION >= 0x050000\n"
"QJsonObject ob0;\n"
"QJsonObject ob = QJsonObject::fromVariantMap({\n"
" {\"a\", 1},\n"
" {\"bb\", 2},\n"
@@ -7193,6 +7315,7 @@ void tst_Dumpers::dumper_data()
"});\n"
"ob.insert(QLatin1String(\"d\"), QJsonObject::fromVariantMap({{\"ddd\", 1234}}));\n"
"\n"
"QJsonArray aa;\n"
"QJsonArray a;\n"
"a.append(QJsonValue(1));\n"
"a.append(QJsonValue(\"asd\"));\n"
@@ -7217,7 +7340,7 @@ void tst_Dumpers::dumper_data()
" c.append(QJsonValue(-qint64(1u << i)));\n"
" c.append(QJsonValue(-qint64(1u << i) - 1));\n"
"}"
"unused(&ob,&b,&a);\n"
"unused(&ob, &b, &a, &aa);\n"
"#endif\n",
"")
@@ -7227,45 +7350,66 @@ void tst_Dumpers::dumper_data()
+ QtVersion(0x50000)
+ MsvcVersion(1900)
+ Check("aa", "<0 items>", "@QJsonArray")
+ Check("a", "<6 items>", "@QJsonArray")
+ Check("a.0", "[0]", "1", "QJsonValue (Number)")
+ Check("a.1", "[1]", "\"asd\"", "QJsonValue (String)")
+ Check("a.2", "[2]", "\"cdfer\"", "QJsonValue (String)")
+ Check("a.3", "[3]", "1.4", "QJsonValue (Number)")
+ Check("a.4", "[4]", "true", "QJsonValue (Bool)")
+ Check("a.3", "[3]", "1.4", "QJsonValue (Number)") % jsonv1
+ Check("a.3", "[3]", "1.400000", "QJsonValue (Number)") % jsonv2
+ Check("a.4", "[4]", "true", "QJsonValue (Bool)") % jsonv1
+ Check("a.4", "[4]", "True", "QJsonValue (Bool)") % jsonv2
+ Check("a.5", "[5]", "<5 items>", "QJsonValue (Object)")
+ Check("a.5.0", "\"a\"", "1", "QJsonValue (Number)")
+ Check("a.5.1", "\"bb\"", "2", "QJsonValue (Number)")
+ Check("a.5.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)")
+ Check("a.5.3", "\"d\"", "<1 items>", "QJsonValue (Object)")
+ Check("a.5.4", "\"s\"", "\"ssss\"", "QJsonValue (String)")
+ Check("a.5.0", "\"a\"", "1", "QJsonValue (Number)") % jsonv1
+ Check("a.5.0", "[0] \"a\"", "1", "" ) % jsonv2
+ Check("a.5.1", "\"bb\"", "2", "QJsonValue (Number)") % jsonv1
+ Check("a.5.1", "[1] \"bb\"", "2", "" ) % jsonv2
+ Check("a.5.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)") % jsonv1
+ Check("a.5.2", "[2] \"ccc\"","\"hallo\"", "" ) % jsonv2
+ Check("a.5.3", "\"d\"", "<1 items>", "QJsonValue (Object)") % jsonv1
+ Check("a.5.3", "[3] \"d\"", "<1 items>", "" ) % jsonv2
+ Check("a.5.4", "\"s\"", "\"ssss\"", "QJsonValue (String)") % jsonv1
+ Check("a.5.4", "[4] \"s\"", "\"ssss\"", "" ) % jsonv2
+ Check("b", "b", "<3 items>" , "@QJsonArray")
+ Check("b.0", "[0]", "1", "QJsonValue (Number)")
+ Check("b.1", "[1]", "<6 items>", "QJsonValue (Array)")
+ Check("b.1.0", "[0]", "1", "QJsonValue (Number)")
+ Check("b.1.1", "[1]", "\"asd\"", "QJsonValue (String)")
+ Check("b.1.2", "[2]", "\"cdfer\"", "QJsonValue (String)")
+ Check("b.1.3", "[3]", "1.4", "QJsonValue (Number)")
+ Check("b.1.4", "[4]", "true", "QJsonValue (Bool)")
+ Check("b.1.5", "[5]", "<5 items>", "QJsonValue (Object)")
+ Check("b.2", "[2]", "2", "QJsonValue (Number)")
+ Check("b.1.0", "[0]", "1", "QJsonValue (Number)") % jsonv2
+ Check("b.1.1", "[1]", "\"asd\"", "QJsonValue (String)") % jsonv2
+ Check("b.1.2", "[2]", "\"cdfer\"", "QJsonValue (String)") % jsonv2
+ Check("b.1.3", "[3]", "1.4", "QJsonValue (Number)") % jsonv1
+ Check("b.1.3", "[3]", "1.400000", "QJsonValue (Number)") % jsonv2
+ Check("b.1.4", "[4]", "true", "QJsonValue (Bool)") % jsonv1
+ Check("b.1.5", "[5]", "<5 items>", "QJsonValue (Object)") % jsonv2
+ Check("b.2", "[2]", "2", "QJsonValue (Number)") % jsonv2
+ Check("c", "c", "<192 items>", "@QJsonArray")
+ Check("c.0", "[0]", "0.0", "QJsonValue (Number)")
+ Check("c.0", "[0]", "0.0", "QJsonValue (Number)") % jsonv1
+ Check("c.0", "[0]", "0", "QJsonValue (Number)") % jsonv2
+ Check("c.1", "[1]", "1", "QJsonValue (Number)")
+ Check("c.78", "[78]", "67108863", "QJsonValue (Number)")
+ Check("c.79", "[79]", "67108864.0", "QJsonValue (Number)")
+ Check("c.94", "[94]", "2147483648.0", "QJsonValue (Number)")
+ Check("c.95", "[95]", "2147483649.0", "QJsonValue (Number)")
+ Check("c.96", "[96]", "0.0", "QJsonValue (Number)")
+ Check("c.79", "[79]", "67108864.0", "QJsonValue (Number)") % jsonv1
+ Check("c.79", "[79]", "67108864", " QJsonValue (Number)") % jsonv2
+ Check("c.94", "[94]", "2147483648.0", "QJsonValue (Number)") % jsonv1
+ Check("c.94", "[94]", "2147483648", "QJsonValue (Number)") % jsonv2
+ Check("c.95", "[95]", "2147483649.0", "QJsonValue (Number)") % jsonv1
+ Check("c.95", "[95]", "2147483649", "QJsonValue (Number)") % jsonv2
+ Check("c.96", "[96]", "0.0", "QJsonValue (Number)") % jsonv1
+ Check("c.96", "[96]", "0", "QJsonValue (Number)") % jsonv2
+ Check("c.97", "[97]", "-1", "QJsonValue (Number)")
+ Check("c.174", "[174]", "-67108863", "QJsonValue (Number)")
+ Check("c.175", "[175]", "-67108864.0", "QJsonValue (Number)")
+ Check("c.175", "[175]", "-67108864.0", "QJsonValue (Number)") % jsonv1
+ Check("c.175", "[175]", "-67108864", "QJsonValue (Number)") % jsonv2
+ Check("ob0", "ob0", "<0 items>", "@QJsonObject")
+ Check("ob", "ob", "<5 items>", "@QJsonObject")
+ Check("ob.0", "\"a\"", "1", "QJsonValue (Number)")
+ Check("ob.1", "\"bb\"", "2", "QJsonValue (Number)")
+ Check("ob.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)")
+ Check("ob.3", "\"d\"", "<1 items>", "QJsonValue (Object)")
+ Check("ob.4", "\"s\"", "\"ssss\"", "QJsonValue (String)");
+ Check("ob.0", "\"a\"", "1", "QJsonValue (Number)") % jsonv1
+ Check("ob.0", "[0] \"a\"", "1", "" ) % jsonv2
+ Check("ob.1", "\"bb\"", "2", "QJsonValue (Number)") % jsonv1
+ Check("ob.1", "[1] \"bb\"", "2", "" ) % jsonv2
+ Check("ob.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)") % jsonv1
+ Check("ob.2", "[2] \"ccc\"", "\"hallo\"", "" ) % jsonv2
+ Check("ob.3", "\"d\"", "<1 items>", "QJsonValue (Object)") % jsonv1
+ Check("ob.3", "[3] \"d\"", "<1 items>", "" ) % jsonv2
+ Check("ob.4", "\"s\"", "\"ssss\"", "QJsonValue (String)") % jsonv1
+ Check("ob.4", "[4] \"s\"", "\"ssss\"", "" ) % jsonv2;
QTest::newRow("Q&qstring_literal_temp,V4")