Commit c6fda812 authored by EXT Arnaud Clère's avatar EXT Arnaud Clère

WIP stricter error handling that detected invalid XML chars at slight

performance cost (getting rid of some virtual should improve this)
parent 15204fb8
......@@ -235,7 +235,7 @@ public:
QCborVisitor(QCborValue* v) : cbor(v) { Q_ASSERT(v); }
void reset(QCborValue* v) { cbor=v; Q_ASSERT(v); steps.resize(0); }
QAsciiData currentPath() {
QAsciiData currentPath() const {
QByteArray path;
Q_FOREACH(Step s, steps) {
if (!s.key.isNull()) { path.append('{').append( s.key.utf8() ); }
......@@ -249,10 +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 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; }
......@@ -264,11 +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 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; }
bool tryOut ( ) { steps.pop() ; return true; }
bool tryAny() { return true; }
bool isValid() const noexcept { return cbor; }
bool handleError(QIdentifierLiteral e, QString context = QString()) const { 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; }
......@@ -289,9 +289,9 @@ public:
QCborReader(QIODevice* io) : QCborStreamReader(io), cacheVisitor(&cachedValue) { Q_ASSERT(io); }
// Shortcuts
/**/ QValue value ( ) { return QCur(this).value(); }
/**/ 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)); }
/**/ QValue value ( ) { return QCur(this).value(); }
/**/ QSequence sequence(quint32* s=nullptr) { return QCur(this).value().sequence(s); }
template<typename T> QValueEnd bind ( T&& t) { return QCur(this).value().bind(std::forward<T>(t)); }
protected:
bool trySequence(quint32* s=nullptr) { if (caching) { cacheLevel++; return caching->trySequence(s); }
skipTag(); if (isArray () && enterContainer()) { levels.push(Level()); return true; } handleError(qBindExpectedSequence); return false; }
......@@ -414,13 +414,13 @@ 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; }
bool handleError(QIdentifierLiteral e, QString context = QString()) const { return errorHandler ? errorHandler(e, QString("at %1 ").arg(currentOffset()).append(context)) : false; }
private:
void skipTag() { if (isTag()) next(); }
bool getNumber(double& d) { skipTag();
......@@ -471,20 +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();
return (j.isUndefined() || v->handleError(qBindUnexpectedValue)) ? v.any() : QValueEnd();
}
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) {
QValueEnd 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; }
......@@ -493,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())) { 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(); }
}
};
......
......@@ -105,7 +105,7 @@ public:
QJsonVisitor(const QJsonValue* v) : json(v) { Q_ASSERT(v); }
void reset(QJsonValue* v) { json=v; Q_ASSERT(v); steps.resize(0); }
QAsciiData currentPath() {
QAsciiData currentPath() const {
QByteArray path;
Q_FOREACH(Step s, steps) {
if (!s.key.isNull()) { path.append('{').append( s.key.utf8() ); }
......@@ -137,7 +137,7 @@ protected:
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; }
bool handleError(QIdentifierLiteral e, QString context = QString()) const { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
private:
const QJsonValue& current(int outer=0) const { Q_ASSERT(0<=outer && json); return steps.size()-outer <= 0 ? *json : steps[steps.size()-outer-1].item; }
......@@ -234,7 +234,7 @@ class QJsonReader : public QAbstractValueReader
public:
QJsonReader(QIODevice* io) : io(io), cacheWriter(&cachedValue), cacheReader(&cachedValue) { Q_ASSERT(io); }
void reset(QIODevice* other) {
errors.clear(); levels.clear();
levels.clear();
line=0; column=0; index=-1;
cachedNumber = None; d=.0; i=0; neg=bool();
cacheLevel = 0; cachedValue = QJsonValue();
......@@ -246,8 +246,6 @@ public:
}
struct Step { int index; const char* end; QMap<QIdentifier,QJsonValue/*TODO QVariant for meta() support*/> cachedItems; Step(int i=-1, const char* e=nullptr) : index(i), end(e) {} };
struct Error { QIdentifierLiteral error; int line; int column; int index; QValueEnd zap(QValue&& value) { QByteArray u(error.utf8()); u.append(' ').append(QByteArray::number(line)).append(':').append(QByteArray::number(column)); return value.bind(QUtf8Data(u)); } };
QVector<Error> errors;
// Shortcuts
/**/ QValue value ( ) { return QCur(this).value(); }
......@@ -387,7 +385,7 @@ protected:
return true; }
bool isValid() const noexcept { return io; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString("(%1:%2)").arg(line).arg(column).append(context)) : false; }
bool handleError(QIdentifierLiteral e, QString context = QString()) const { return errorHandler ? errorHandler(e, QString("at %1:%2 ").arg(line).arg(column).append(context)) : false; }
private:
CachedNumber getNumber() {
if (cachedNumber!=None) return cachedNumber;
......@@ -558,7 +556,7 @@ struct QTransmogrifier<QJsonValue> {
double d; if ((r = v.bind(d))) { j = QJsonValue( d ); v->setErrorHandler(suspended); return r; }
/**/ if ((r = v.null( ))) { j = QJsonValue( ); v->setErrorHandler(suspended); return r; }
v->setErrorHandler(suspended);
if (v->handleError(qBindUnexpectedValue)) { j = QJsonValue(QJsonValue::Undefined); }
if ((r = v.any())) { j = QJsonValue(QJsonValue::Undefined); }
return r;
}
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
......
......@@ -392,8 +392,6 @@ protected:
// TODO QDate*, QTime
// TODO QPixmap if metadata suggests a QMimeData image ?
virtual bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, context) : true; }
void resetItemData() { ba.clear(); w.reset(&ba); }
QAbstractValue* itemBind() { return static_cast<QAbstractValue*>(&w); }
......@@ -619,18 +617,10 @@ protected:
QAbstractValue* itemBind() { return static_cast<QAbstractValue*>(&r); }
void setItemData(QUtf8Data u) { io.buffer() = u.utf8(); io.seek(0); r.reset(&io); }
bool handleError(QIdentifierLiteral e, QString context = QString()) {
if (errorHandler) {
QString path;
for (auto current = parent; parent.isValid(); current = current.parent()) {
path.prepend(QString('/').append(current.row()).append(',').append(current.column()));
}
return errorHandler(e, path.append(context));
}
else {
return false;
}
QString path(QModelIndex current) const {
return current.isValid() ? path(current.parent())+QString("/%1,%2").arg(current.row()).arg(current.column()) : "";
}
bool handleError(QIdentifierLiteral e, QString context = QString()) const { return errorHandler ? errorHandler(e, QString("at %1 %2").arg(path(parent)).arg(context)) : false; }
QBuffer io;
TItemReader r;
......
......@@ -101,13 +101,13 @@ public:
Q_ENABLE_MOVE_DEFAULT(QSettingsReader)
QSettingsReader(QSettings* s) : settings(s) { Q_ASSERT(s); levels.push(Level(qBindExpectedItem)); }
QAsciiData currentPath() {
QByteArray path;
Q_FOREACH(Level l, levels) {
if (l.key.isNull()) { path.append('/').append( l.key.utf8() ); }
else { path.append('/').append(QByteArray::number(l.idx )); }
QString currentPath() const {
QString path;
for (auto&& l : levels) {
if (l.key.isNull()) { path.append('/').append(l.key.latin1()); }
else { path.append('/').append(QString::number(l.idx)); }
}
return QAsciiData(path);
return path;
}
// Shortcuts
......@@ -143,7 +143,7 @@ protected:
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; }
bool handleError(QIdentifierLiteral e, QString context = QString()) const { return errorHandler ? errorHandler(e, QString("at %1 %2").arg(currentPath(), context)) : false; }
private:
template<typename T>
bool set(T& t, QIdentifierLiteral error) { QVariant v = settings->value(key()); if (v.convert(qMetaTypeId<T>())) { t = v.value<T>(); return true; } handleError(error); return false; }
......
#include "QValue.h"
QIdentifierLiteral qBindUnexpectedValue ("UnexpectedValue" );
QIdentifierLiteral qBindUnexpectedEnd ("qBindUnexpectedEnd" );
QIdentifierLiteral qBindUnexpectedEnd ("UnexpectedEnd" );
QIdentifierLiteral qBindBlocked ("Blocked" );
QIdentifierLiteral qBindExpectedItem ("ExpectedItem" );
QIdentifierLiteral qBindExpectedNull ("ExpectedNull" );
......
This diff is collapsed.
......@@ -123,7 +123,7 @@ public:
QVariantVisitor(const QVariant* v) : value(v) { Q_ASSERT(v); }
void reset(const QVariant* v) { value=v; Q_ASSERT(v); levels.resize(0); }
QAsciiData currentPath() {
QAsciiData currentPath() const {
QByteArray path;
Q_FOREACH(Level l, levels) {
if (l.key.isNull()) { path.append('{').append( l.key.utf8() ); }
......@@ -178,7 +178,7 @@ protected:
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; }
bool handleError(QIdentifierLiteral e, QString context = QString()) const { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
private:
const QVariant* current(unsigned outer=0) const { return unsigned(levels.size())-outer <= 0 ? value : &(levels[unsigned(levels.size())-outer-1].item); }
......
......@@ -86,10 +86,10 @@ protected:
bool tryBind ( double&& n) { static QString s; s.setNum( n ,'g',std::numeric_limits<double>::max_digits10); writeText("decimal" , s); return true; } // with specific precision
bool tryBind ( QByteArray&& s) { QString h; h.reserve(s.size()*2+2+1); h.append("0x").append(s.toHex().toUpper()) ; writeText("hexBinary", h); return true; }
bool isValid() const noexcept { return !io->hasError(); }
bool isValid() const noexcept { return !io->hasError() || handleError(qBindUnexpectedEnd, io->device()->errorString()); }
bool tryOut ( ) { io->writeEndElement(); return true; }
bool tryItem( ) { return true; }
bool tryOut () { io->writeEndElement(); return true; }
bool tryItem() { return true; }
bool tryItem(QIdentifier& n) { name=n; return true; }
void _meta(QIdentifierLiteral &n, QAsciiData &m);
private:
......@@ -101,7 +101,17 @@ private:
QAsciiData& operator[](QIdentifierLiteral n) { return find(n)->second; }
};
void writeText(const char* def, QString text) { io->writeStartElement(tag(def).latin1()); att(); io->writeCharacters(text); io->writeEndElement(); }
void writeText(const char* def, const QString& text) {
io->writeStartElement(tag(def).latin1());
att();
QString valid;
valid.reserve(text.size());
for (QChar c : text) {
valid.append(c<'\x20' && c!='\x9' && c!='\xA' && c!='\xD' ? '?' : c);
}
io->writeCharacters(valid);
io->writeEndElement();
}
QIdentifier tag(const char* def) { if (name.isNull()) { return QIdentifier(def); } auto n=name; name=QIdentifier(); return n; }
void att() { for (auto&& a : atts) { if (!a.second.isNull()) io->writeAttribute(a.first.latin1(), a.second.latin1()); } }
......
......@@ -401,7 +401,13 @@ int main(int argc, char *argv[])
qRegisterMetaTypeStreamOperators<QUtf8Data>();
GROUP("builtin>")//========================================================
QStringList errors;
auto handler = [&errors](QIdentifierLiteral error, QString context) {
errors.append(context.append(error.latin1()));
return true;
};
GROUP("builtin")//========================================================
{
START {
s.resize(0);
......@@ -544,7 +550,7 @@ int main(int argc, char *argv[])
STOP("Bindables>Json",ba)
}
GROUP_STOP
GROUP("doubles>")//========================================================
GROUP("doubles")//========================================================
{
START {
s.resize(0);
......@@ -636,7 +642,7 @@ int main(int argc, char *argv[])
STOP("Bindable>Json",ba)
}
GROUP_STOP
GROUP("Person>")//=========================================================
GROUP("Person")//=========================================================
{
START {
s.resize(0);
......@@ -779,7 +785,7 @@ int main(int argc, char *argv[])
STOP("Bindable>Json",ba)
}
GROUP_STOP
GROUP("Phone>")//=========================================================
GROUP("Phone")//=========================================================
{
START {
s.resize(0);
......@@ -860,12 +866,7 @@ int main(int argc, char *argv[])
}
GROUP_STOP
QStringList errors;
auto handler = [&errors](QIdentifierLiteral error, QString context) {
errors.append(context.append(error.latin1()));
return true;
};
GROUP("Person<>Json")//====================================================
GROUP("Person-Json")//====================================================
{
QBuffer json; json.open(QIODevice::ReadOnly);
json.buffer() = "_{ \"names\": [ _\"John\" _, \"Doe\"] , \"age\"_:_null, \"height\":_1.75, \"phones\": [], \"_\":\"superfluous item\" _} ";
......@@ -929,12 +930,13 @@ int main(int argc, char *argv[])
STOP("Json>Cbor",ba.toHex())
}
GROUP_STOP
GROUP("Person<>Cbor")//====================================================
GROUP("Person-Cbor")//====================================================
{
QBuffer cbor; cbor.open(QIODevice::ReadOnly);
cbor.buffer() = QByteArray::fromHex(
"A5656E616D657382644A6F686E63446F6563616765F666686569676874F93F006670686F6E65738060707375706572666C756F7573206974656D");
// { "names": [ "John", "Doe"], "age":null,"height": 1.75, "phones": [],"":"superfluous item"}
// { "names": [ "John", "Doe"], "age":null,"height": 1.75, "phones": [],"":"superfluous item" }
// 41 58
Person p;
QBuffer roundtrip; roundtrip.open(QIODevice::ReadWrite);
QCborValue cv;
......@@ -1084,7 +1086,7 @@ int main(int argc, char *argv[])
STOP("Cbor>Json",b.buffer()+" | "+errors.join(", "))
}
GROUP_STOP
GROUP("Person<>Settings")//====================================================
GROUP("Person-Settings")//====================================================
{
QFileInfo iniFile(QDir::currentPath()+"/../QBind");
QSettings::setPath(QSettings::IniFormat,QSettings::UserScope,iniFile.path());
......
builtin> |================================================================================
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}]
......@@ -12,7 +12,7 @@ QByteArray |abaaaa3f182d4454fb21094061736369692063686172616374657273206172652
Bindables |
Bindables>Cbor|85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff
Bindables>Json|[1.33333337,3.1415926535897931,"ascii characters are common in QDebug",false,{"RGB":[45,0,186],"base":255}]
doubles> |================================================================================
doubles |================================================================================
QDebug |0.333333 0.666667 0.333333 1 0.666667 0.333333 0.666667 1 0.333333 0.666667 0.333333 1 0 0 0 1
Text | 0.333333 0.666667 0.333333 1 0.666667 0.333333 0.666667 1 0.333333 0.666667 0.333333 1 0 0 0 1
Json |[0.33333333333333331,0.66666666666666663,0.33333333333333331,1,0.66666666666666663,0.33333333333333331,0.66666666666666663,1,0.33333333333333331,0.66666666666666663,0.33333333333333331,1,0,0,0,1]
......@@ -26,11 +26,11 @@ QByteArray |10000000555555555555d53f555555555555e53f555555555555d53f000000000
Bindable |
Bindable>Cbor |90fb3fd5555555555555fb3fe5555555555555fb3fd5555555555555fb3ff0000000000000fb3fe5555555555555fb3fd5555555555555fb3fe5555555555555fb3ff0000000000000fb3fd5555555555555fb3fe5555555555555fb3fd5555555555555fb3ff0000000000000fb0000000000000000fb0000000000000000fb0000000000000000fb3ff0000000000000
Bindable>Json |[0.33333333333333331,0.66666666666666663,0.33333333333333331,1,0.66666666666666663,0.33333333333333331,0.66666666666666663,1,0.33333333333333331,0.66666666666666663,0.33333333333333331,1,0,0,0,1]
Person> |================================================================================
Person |================================================================================
QDebug |Person("John", "Doe", 1.75, 18, QVector(), "unicode is likely U+01 \u0001 + U+1F \u001F + U+A4 ¤ U+B0 ° U+D8 Ø U+FF ÿ", ())
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></Person>
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
......@@ -41,7 +41,7 @@ QJsonDocument |{"age":18,"children":[],"comments":"unicode is likely U+01 \u0001
Bindable |
Bindable>Cbor |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765126670686f6e65738068636f6d6d656e74737843756e69636f6465206973206c696b656c7920552b30312001202b20552b3146201f202b20552b413420c2a420552b423020c2b020552b443820c39820552b464620c3bf686368696c6472656e80ff
Bindable>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":[]}
Phone> |================================================================================
Phone |================================================================================
QDebug |Phone(Phone::Home, "+44 1234567")
Text |(Phone) type:(Home)2 number:+44 1234567
Json |{"type":2,"number":"+44 1234567"}
......@@ -55,16 +55,16 @@ QByteArray |022b34342031323334353637
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
Person-Json |================================================================================
Json>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | at 0:1 IgnoredCharacter, at 0:15 IgnoredCharacter, at 0:23 IgnoredCharacter, at 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":[]}
JsonValue>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] |
Json>JsonValue|{"age":-1,"children":[],"comments":"","height":1.7500000000000004,"names":["John","Doe"],"phones":[]} |
Json>Cbor |bf656e616d65739f644a6f686e63446f65ff66686569676874fa3fe0000063616765206670686f6e65739fff68636f6d6d656e747360686368696c6472656e9fffff
Person<>Cbor |================================================================================
Cbor>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | at index:41 commentsIgnoredItem
Person-Cbor |================================================================================
Cbor>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | at 41 commentsIgnoredItem, at 41 UnexpectedEnd, at 58 UnexpectedEnd
P>Cbor |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765206670686f6e65738068636f6d6d656e747360686368696c6472656e80ff
Cbor>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] |
QCborStream>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | true
......@@ -73,7 +73,7 @@ CborValue>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments:
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":undefined} |
Person<>Settings|================================================================================
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:[] | /-1/namesIgnoredItem
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:[] | at /-1/ namesIgnoredItem, at /-1/ UnexpectedEnd, at /-1 UnexpectedEnd
P>Settings |QBind
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