Commit 90cb6e83 authored by EXT Arnaud Clère's avatar EXT Arnaud Clère

Added auto closing of unused QSeq/QRec

Fixed illegal QSeq<T_>() calls (outside QVal)
parent 39a55e64
......@@ -249,11 +249,10 @@ public:
/**/ QSequence sequence(quint32* s=nullptr) { return QCur(this).value().sequence(s); }
template<typename T> QCur bind ( T&& t) { return QCur(this).value().bind(std::forward<T>(t)); }
protected:
bool trySequence(quint32* =nullptr) { if (current().isArray ()) { steps.push(Step()); return true; } handleError(qBindExpectedSequence); return false; }
bool tryRecord (quint32* =nullptr) { if (current().isMap ()) { steps.push(Step()); return true; } handleError(qBindExpectedRecord ); return false; }
bool tryAny ( ) { if (current().isUndefined()) { return true; } handleError(qBindUnexpectedValue ); return false; }
bool tryNull ( ) { if (current().isNull ()) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryBind ( QUtf8Data& u) { QString s; if (tryBind(s) ) { u = s .toUtf8 (); return true; } return false; }
bool trySequence(quint32* =nullptr) { if (current().isArray ()) { steps.push(Step()); return true; } handleError(qBindExpectedSequence); return false; }
bool tryRecord (quint32* =nullptr) { if (current().isMap ()) { steps.push(Step()); return true; } handleError(qBindExpectedRecord ); return false; }
bool tryNull ( ) { if (current().isNull ()) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryBind ( QUtf8Data& u) { QString s; if (tryBind(s) ) { u = s .toUtf8 (); return true; } return false; }
bool tryBind ( QString& v) { if (current().isString ()) { v = current().toString (); return true; } handleError(qBindExpectedText ); return false; }
bool tryBind ( bool& v) { if (current().isBool ()) { v = current().toBool (); return true; } handleError(qBindExpectedBoolean ); return false; }
bool tryBind ( qint64& t) { if (current().isInteger ()) { t = current().toInteger (); return true; } handleError(qBindExpectedInteger ); return false; }
......@@ -265,10 +264,11 @@ protected:
bool tryItem(QIdentifierLiteral u) { steps.last().key=u; return !(steps.last().item = current(1).toMap().value(steps.last().key.latin1())).isUndefined(); }
bool tryItem(QIdentifier& k) { steps.last().key=k; return !(steps.last().item = current(1).toMap().value(steps.last().key.latin1())).isUndefined(); }
bool tryItem( ) { steps.last().idx++; return !(steps.last().item = current(1).toArray(). at(steps.last().idx )).isUndefined(); }
bool tryOut ( ) { steps.pop() ; return true; }
bool isValid() const noexcept { return cbor; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
bool tryOut ( ) { steps.pop() ; return true; }
bool tryAny() { return true; }
bool isValid() const noexcept { return cbor; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
private:
const QCborValue& current(int outer=0) const { Q_ASSERT(0<=outer); return steps.size()-outer <= 0 ? *cbor : steps[steps.size()-outer-1].item; }
......@@ -414,13 +414,11 @@ protected:
return false;
}
return true; }
bool tryOut ( ) { if (caching) { bool out = caching->tryOut(); if (out) { --cacheLevel; cacheOut(); } return out; }
levels.pop();
while (hasNext()) {
tryAny();
}
return leaveContainer(); }
bool tryOut ( ) { if (caching) { bool out = caching->tryOut(); if (out) { --cacheLevel; cacheOut(); } return out; }
levels.pop();
while (hasNext()) { tryAny(); }
return leaveContainer(); }
bool isValid() const noexcept { return const_cast<QCborReader*>(this)->lastError()==QCborError::NoError; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString("at index:%1 ").arg(currentOffset()).append(context)) : false; }
private:
......@@ -473,21 +471,20 @@ struct QTransmogrifier<QCborValue> {
if (j.isInteger ()) return v.bind(j.toInteger ());
if (j.isDouble ()) return v.bind(j.toDouble ());
if (j.isString ()) return v.bind(j.toString ());
if (j.isByteArray()) return v.bind(j.toByteArray());
if (j.isNull ()) return v.null();
if (j.isUndefined() || j.isInvalid() || v->handleError(qBindUnexpectedValue)) return v.any();
return QCur();
}
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
if (j.isByteArray()) return v.bind(j.toByteArray());
if (j.isNull ()) return v.null();
return (j.isUndefined() || v->handleError(qBindUnexpectedValue)) ? v.any() : QValueEnd();
}
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
}
static QValueEnd zap(QValue&& v, QCborValue& j) {
if (v->mode()==Write) {
return zap(std::move(v),std::move(j));
}
else if (v->mode()==Read) {
QCur r;
auto suspended = v->setErrorHandler();
QCborArray a; if ((r = v.bind(a))) { j = a ; v->setErrorHandler(suspended); return r; }
}
else if (v->mode()==Read) {
QValueEnd r;
auto suspended = v->setErrorHandler();
QCborArray a; if ((r = v.bind(a))) { j = a ; v->setErrorHandler(suspended); return r; }
QCborMap o; if ((r = v.bind(o))) { j = o ; v->setErrorHandler(suspended); return r; }
QString t; if ((r = v.bind(t))) { j = QCborValue( t ); v->setErrorHandler(suspended); return r; }
bool b; if ((r = v.bind(b))) { j = QCborValue( b ); v->setErrorHandler(suspended); return r; }
......@@ -496,11 +493,11 @@ struct QTransmogrifier<QCborValue> {
j = QCborValue(double(u)); v->setErrorHandler(suspended); return r; }
double d; if ((r = v.bind(d))) { j = QCborValue( d ); v->setErrorHandler(suspended); return r; }
QByteArray y; if ((r = v.bind(y))) { j = QCborValue( y ); v->setErrorHandler(suspended); return r; }
/**/ if ((r = v.null( ))) { j = QCborValue( nullptr ); v->setErrorHandler(suspended); return r; }
v->setErrorHandler(suspended);
if ((r = v.any()) || v->handleError(qBindUnexpectedValue)) { j = QCborValue(); }
return r;
}
/**/ if ((r = v.null( ))) { j = QCborValue( nullptr ); v->setErrorHandler(suspended); return r; }
v->setErrorHandler(suspended);
if ((r = v.any())) { j = QCborValue(); }
return r;
}
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
}
};
......
......@@ -70,7 +70,6 @@ protected:
friend class QCur;
bool trySequence(quint32* s=nullptr) { if (s) *io << *s; return true; }
bool tryRecord (quint32* s=nullptr) { if (s) *io << *s; return true; }
bool tryAny ( ) { return handleError(qBindUnexpectedValue); }
bool tryNull ( ) { *io << nullptr; return true; }
bool tryBind ( QUtf8DataView u) { QByteArray ba = QByteArray::fromRawData(u.data(), u.size()+int(sizeof('\0'))); return static_cast<QAbstractValue*>(this)->tryBind(ba); }
......
......@@ -121,7 +121,6 @@ public:
protected:
bool trySequence(quint32* =nullptr) { if (current().isArray ()) { steps.push(Step()); return true; } handleError(qBindExpectedSequence); return false; }
bool tryRecord (quint32* =nullptr) { if (current().isObject()) { steps.push(Step()); return true; } handleError(qBindExpectedRecord ); return false; }
bool tryAny ( ) { if (current().isUndefined()) { return true; } handleError(qBindUnexpectedValue ); return false; }
bool tryNull ( ) { if (current().isNull() ) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryBind ( QUtf8Data& u) { QString s; if (tryBind(s) ) { u = s .toUtf8 (); return true; } return false; }
bool tryBind ( QString& v) { if (current().isString()) { v = current().toString(); return true; } handleError(qBindExpectedText ); return false; }
......@@ -136,6 +135,7 @@ protected:
bool tryItem( ) { steps.last().idx++; return !(steps.last().item = current(1).toArray (). at(steps.last().idx )).isUndefined(); }
bool tryOut ( ) { steps.removeLast(); return true; }
bool tryAny() { return true; }
bool isValid() const noexcept { return true; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
private:
......@@ -166,7 +166,7 @@ protected:
bool trySequence(quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step{"","]"}); return putChar('['); }
bool tryRecord (quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step{"","}"}); return putChar('{'); }
bool tryAny ( ) { return handleError(qBindUnexpectedValue) && write("undefined"); }
bool tryAny ( ) { return write("undefined"); } // TODO || (isStrictJson && handleError(qBindUnexpectedValue) && write("null");
bool tryNull ( ) { return write("null"); }
bool tryBind ( QUtf8DataView u) { return putString(u.data(), u.size()); }
// JSON literals
......
......@@ -52,7 +52,7 @@ class QSettingsWriter : public QAbstractValueWriter
{
Q_DISABLE_COPY(QSettingsWriter)
public:
QSettingsWriter(QSettings* s) : settings(s) { Q_ASSERT(s); levels.push(Level(qBindExpectedItem)); }
QSettingsWriter(QSettings* s) : settings(s) { Q_ASSERT(s); settings->beginGroup("test"); } // FIXME remove extra beginGroup
// Shortcuts
/**/ QValue value ( ) { return QCur(this).value(); }
......@@ -69,16 +69,19 @@ protected:
bool tryAny () { settings->setValue(key(), QVariant() ); return true; }
bool tryNull() { settings->setValue(key(), QVariant::fromValue(nullptr)); return true; }
bool trySequence(quint32* =nullptr) { settings->beginGroup(key()); levels.push(Level( )); return true; }
bool tryRecord (quint32* =nullptr) { settings->beginGroup(key()); levels.push(Level(qBindExpectedItem)); return true; }
bool trySequence(quint32* =nullptr) { levels.push(Level( )); settings->beginGroup(key()); return true; } // TODO use beginWriteArray
bool tryRecord (quint32* =nullptr) { levels.push(Level(qBindExpectedItem)); settings->beginGroup(key()); return true; }
bool tryItem(QIdentifier& n) { levels.last().key=n; return true; }
bool tryItem( ) { levels.last().idx++; return true; }
bool tryOut ( ) { levels.pop(); settings->endGroup(); return true; }
bool tryOut ( ) {
levels.pop();
settings->endGroup();
return true;
}
private:
QString key() {
Q_ASSERT(!levels.isEmpty());
return levels.size()==1 ? QString("") :
return levels.size()==0 ? QString("") :
!levels.last().key.isNull()
? QString (levels.last().key.latin1())
: QString::number(levels.last().idx );
......@@ -132,13 +135,13 @@ protected:
bool trySequence(quint32* =nullptr) { if (levels.last().isGroup) { levels.push(Level( )); return true; } handleError(qBindExpectedSequence); return false; }
bool tryRecord (quint32* =nullptr) { if (levels.last().isGroup) { levels.push(Level(qBindExpectedItem)); return true; } handleError(qBindExpectedRecord ); return false; }
bool tryAny () { if (!settings->value(key()).isValid()) { return true; } handleError(qBindUnexpectedValue); return false; }
bool tryNull() { if ( settings->value(key()).isNull ()) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryNull() { if ( settings->value(key()).isNull ()) { return true; } handleError(qBindExpectedNull); return false; }
bool tryItem(QIdentifier& k) { levels.last().key=k ; return true; }
bool tryItem( ) { levels.last().idx++ ; return true; }
bool tryOut ( ) { levels.pop(); settings->endGroup(); return true; }
bool tryAny() { return true; }
bool isValid() const noexcept { return settings; }
bool handleError(QIdentifierLiteral error, QString context = QString()) { return errorHandler ? errorHandler(error, QString(currentPath().latin1()).append(context)) : false; }
private:
......
......@@ -52,7 +52,7 @@
// //////////////////////////////////////////////////////////////////////////
// Standard error names
extern QIdentifierLiteral qBindUnexpectedValue;
extern QIdentifierLiteral qBindUnexpectedValue; //!< Values that cannot be bound (invalid or not supported by the bound data type or our data model)
extern QIdentifierLiteral qBindExpectedItem;
extern QIdentifierLiteral qBindExpectedNull;
extern QIdentifierLiteral qBindExpectedSequence;
......@@ -278,7 +278,11 @@ public:
explicit operator bool() const noexcept { return impl && impl->isValid(); } //!< Drives QTransmogrifier<T>::bind() traversal
QCur* operator ->() noexcept { return this; }
QVal<QCur> value() noexcept ;
operator QValueEnd() { return QValueEnd{impl!=nullptr}; }
operator QValueEnd() {
bool isValid = impl && impl->isValid();
impl=nullptr;
return QValueEnd{isValid};
}
QValueErrorHandler setErrorHandler(QValueErrorHandler newHandler = nullptr) { return Q_LIKELY(impl) ? impl->setErrorHandler(newHandler) : nullptr; }
bool handleError(QIdentifierLiteral name, QString context = QString()) { return Q_LIKELY(impl) ? impl->handleError(name, context) : false; }
......@@ -396,7 +400,7 @@ template<class T_> class QSeq
Q_DISABLE_COPY(QSeq)
public:
Q_ENABLE_MOVE_DEFAULT(QSeq)
explicit QSeq(T_&& out) noexcept { std::swap(outer, out); }
~QSeq() { Q_UNUSED(QValueEnd(*this)) }
explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal
QCur* operator->() noexcept { return outer.operator ->(); }
......@@ -429,6 +433,9 @@ public:
// Shortcut
template<typename T> QSeq<T_> operator<<(T&& t) { return item().bind(std::forward<T>(t)); } // stream compatible
private:
template<class T_> friend class QVal;
explicit QSeq(T_&& out) noexcept { std::swap(outer, out); }
template<typename T, typename TEnabledIf> friend struct QTransmogrifier;
QValue unsafeItem() noexcept { return outer->tryItem() ? QValue(outer->_unsafeCopy()) : QValue(); }
QSequence unsafeThis() noexcept { return QSequence(outer->_unsafeCopy()) ; }
......@@ -441,13 +448,13 @@ template<class T_> class QRec
Q_DISABLE_COPY(QRec)
public:
Q_ENABLE_MOVE_DEFAULT(QRec)
explicit QRec(T_&& out) noexcept { std::swap(outer, out); }
~QRec() { Q_UNUSED(QValueEnd(*this)) }
explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal
QCur* operator->() noexcept { return outer.operator ->(); }
operator QValueEnd() { return out(); /* calls T_::operator QValueEnd() if T_ != QValueEnd */ }
/**/ T_ out ( ) { return outer->tryOut ( ) ? std::move(outer) : T_ (); }
/**/ T_ out ( ) { return outer->tryOut ( ) ? std::move(outer) : T_ (); }
QVal<QRec<T_>> item(QIdentifier& n) { return outer->tryItem( n ) ? QVal<QRec<T_>>(std::move(*this)) : QVal<QRec<T_>>(); }
QVal<QRec<T_>> item(const char* n) { return outer->tryItem(QIdentifierLiteral(n)) ? QVal<QRec<T_>>(std::move(*this)) : QVal<QRec<T_>>(); }
......@@ -469,6 +476,9 @@ public:
/**/ QRec<T_> with (const char* n, QValLambda customBind) { return item(n).with( customBind); }
template<typename T> QRec<T_> with (const char* n, T& t, QValFunction<T> customBind) { return item(n).bind(t, customBind); }
private:
template<class T_> friend class QVal;
explicit QRec(T_&& out) noexcept { std::swap(outer, out); }
template<typename T, typename TEnabledIf> friend struct QTransmogrifier;
QValue unsafeItem(QIdentifier& n) noexcept { return outer->tryItem(n) ? QValue(outer._unsafeCopy()) : QValue(); }
......@@ -693,7 +703,6 @@ struct QAbstractValueReader : public QAbstractValue
virtual bool tryBind( QByteArray& b) { QUtf8Data s; if (!tryBind(s)) return false; return toByteArray(b, s); }
virtual bool tryBind( QVariant& dst) {
auto suspended = setErrorHandler();
quint32 size=0; QIdentifier key; QVariant item;
if (trySequence(&size)) { QVariantList l; while (tryItem( )) { l.append( tryBind(item) ? item : QVariant()); } dst = l; return tryOut(); }
if (tryRecord (&size)) { QVariantMap l; while (tryItem(key)) { l.insert(key.latin1(), tryBind(item) ? item : QVariant()); } dst = l; return tryOut(); }
......@@ -706,7 +715,7 @@ struct QAbstractValueReader : public QAbstractValue
QString t; if (tryBind( t)) { dst = QVariant(t); return true; }
/**/ if (tryNull( )) { dst = QVariant::fromValue(nullptr); return true; }
setErrorHandler(suspended);
if (tryAny() || handleError(qBindUnexpectedValue)) { dst = QVariant(); return true; }
if (tryAny()) { dst = QVariant(); return true; }
return false;
}
......@@ -1161,7 +1170,7 @@ struct QTransmogrifier<QValue> {
QValue srcVal; QValue dstVal;
while((srcVal = srcSeq.unsafeItem())) { // using item()'s QVal<QSequence would cause an infinite compiler loop to generate corresponding QTransmogrifier<QVal<QSeq<QSeq<...>>,_> functions
dstVal = dstSeq.unsafeItem();
srcSeq = QSequence(srcVal.bind(std::move(dstVal)));
srcVal.bind(std::move(dstVal));
}
/**/ dstSeq.out();
......@@ -1174,7 +1183,7 @@ struct QTransmogrifier<QValue> {
QIdentifier srcKey; QValue srcVal; QValue dstVal;
while((srcVal = srcRec.unsafeItem(srcKey))) {
dstVal = dstRec.unsafeItem(srcKey);
srcRec = QRecord(srcVal.bind(std::move(dstVal)));
srcVal.bind(std::move(dstVal));
}
/**/ dstRec.out();
......@@ -1201,7 +1210,7 @@ struct QTransmogrifier<QValue> {
// TODO Other BindNative types we do not want to treat as text: QDateTime, QUuid
/**/ if ((srcEnd = src.null( ))) { dst.null( ); src->setErrorHandler(suspended); return srcEnd; }
src->setErrorHandler(suspended);
if ((srcEnd = src.any()) || src->handleError(qBindUnexpectedValue)) { dst.any(); }
if ((srcEnd = src.any())) { dst.any(); return srcEnd; }
return QValueEnd();
}
else if (src->mode()==Write && dst->mode()==Read) { return zap(std::move(dst),std::move(src)); } // To return reader's QCur instead of writer's QCur since it should contain more information (mismatches, etc.)
......
......@@ -170,13 +170,13 @@ protected:
bool trySequence(quint32* =nullptr) { if (current()->type()==QVariant::List ) { levels.push(Level()); return true; } handleError(qBindExpectedSequence); return false; }
bool tryRecord (quint32* =nullptr) { if (current()->type()==QVariant::Map ) { levels.push(Level()); return true; } handleError(qBindExpectedRecord ); return false; }
bool tryAny () { if (!current()->isValid()) { return true; } handleError(qBindUnexpectedValue); return false; }
bool tryNull() { if ( current()->isNull ()) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryItem(QIdentifier& k) { levels.last().key=k; return (levels.last().item = current(1)->toMap ().value(QString(levels.last().key.latin1()), QVariant())).isValid(); }
bool tryItem( ) { levels.last().idx++; return (levels.last().item = current(1)->toList().value( levels.last().idx , QVariant())).isValid(); }
bool tryOut ( ) { levels.pop() ; return true; }
bool tryAny () { return true; }
bool isValid() const noexcept { return value; }
bool handleError(QIdentifierLiteral error, QString context = QString()) { return errorHandler ? errorHandler(error, QString(currentPath().latin1()).append(context)) : false; }
private:
......
......@@ -658,7 +658,6 @@ int main(int argc, char *argv[])
QXmlStreamWriter w(&ba);
QXmlWriter d(&w);
d.bind(person);
w.writeEndDocument(); // FIXME It should not be necessary
}
STOP("Xml",ba)
START {
......
......@@ -2,7 +2,7 @@ builtin> |=================================================================
QDebug |1.33333 3.14159 ascii characters are common in QDebug false QColor(ARGB 1, 0.176471, 0, 0.729412)
Text | 1.33333 3.14159 ascii characters are common in QDebug false [ RGB:[ 45 0 186] base:255]
Json |[1.33333337,3.1415926535897931,"ascii characters are common in QDebug",false,{"RGB":[45,0,186],"base":255}]
Xml |<sequence><decimal>1.33333337</decimal><decimal>3.1415926535897931</decimal><string>ascii characters are common in QDebug</string><boolean>false</boolean><record><RGB><integer>45</integer><integer>0</integer><integer>186</integer></RGB><base>255</base></record>
Xml |<sequence><decimal>1.33333337</decimal><decimal>3.1415926535897931</decimal><string>ascii characters are common in QDebug</string><boolean>false</boolean><record><RGB><integer>45</integer><integer>0</integer><integer>186</integer></RGB><base>255</base></record></sequence>
Variant | 1.33333 3.14159 ascii characters are common in QDebug false [ RGB:[ 45 0 186] base:255]
Cbor |85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff
QCborStream |85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff
......@@ -31,7 +31,6 @@ QDebug |Person("John", "Doe", 1.75, 18, QVector(), "unicode is likely U+0
Text |(Person) names:[ John Doe] height:1.75 age:18 phones:[] comments:unicode is likely U+01  + U+1F  + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ children:[]
Json |{"names":["John","Doe"],"height":1.75,"age":18,"phones":[],"comments":"unicode is likely U+01 \u0001 + U+1F \u001F + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ","children":[]}
Xml |<Person><names><string>John</string><string>Doe</string></names><height>1.75</height><age>18</age><phones/><comments>unicode is likely U+01 + U+1F + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ</comments><children/></Person>
Variant | age:18 children:[] comments:unicode is likely U+01  + U+1F  + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ height:1.75 names:[ John Doe] phones:[]
Cbor |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765126670686f6e65738068636f6d6d656e74737843756e69636f6465206973206c696b656c7920552b30312001202b20552b3146201f202b20552b413420c2a420552b423020c2b020552b443820c39820552b464620c3bf686368696c6472656e80ff
QCborStream |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765126670686f6e65738068636f6d6d656e74737843756e69636f6465206973206c696b656c7920552b30312001202b20552b3146201f202b20552b413420c2a420552b423020c2b020552b443820c39820552b464620c3bf686368696c6472656e80ff
......@@ -57,7 +56,7 @@ Bindable |
Bindable>Cbor |bf647479706502666e756d6265726b2b34342031323334353637ff
Bindable>Json |{"type":2,"number":"+44 1234567"}
Person<>Json |================================================================================
Json>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | (0:1)IgnoredCharacter, (0:15)IgnoredCharacter, (0:23)IgnoredCharacter, (0:40)IgnoredCharacter, (0:58)IgnoredCharacter, (0:102)IgnoredCharacter
Json>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | (0:1)IgnoredCharacter, (0:15)IgnoredCharacter, (0:23)IgnoredCharacter, (0:40)IgnoredCharacter
P>Json |{"names":["John","Doe"],"height":1.7500000000000002,"age":-1,"phones":[],"comments":"","children":[]}
Json>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] |
P>JsonValue |{"age":-1,"children":[],"comments":"","height":1.7500000000000004,"names":["John","Doe"],"phones":[]}
......@@ -73,7 +72,7 @@ P>CborValue |a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000
CborValue>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] |
Cbor>CborValue|{"names": ["John", "Doe"], "height": 1.75, "age": -1, "phones": [], "comments": "", "children": []} |
CborValue>Cbor|a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000063616765206670686f6e65738068636f6d6d656e747360686368696c6472656e80
Cbor>Json |{"names":["John","Doe"],"height":1.75,"age":} |
Cbor>Json |{"names":["John","Doe"],"height":1.75,"age":undefined} |
Person<>Settings|================================================================================
P>Settings |(Person) names:[ John Doe] height:1.75 age:18 phones:[] comments:unicode is likely U+01  + U+1F  + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ children:[]
Settings>P |(Person) names:[ John Doe] height:1.75 age:18 phones:[] comments:unicode is likely U+01  + U+1F  + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ children:[] |
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment