Commit 79abcda4 authored by EXT Arnaud Clère's avatar EXT Arnaud Clère

Fixed QJsonReader cachelevel

More precise null handling including qBindExpectedValue for values that
are not null and not among the expecte values (say a QVariant other than
list/map and basic types...)
parent 51dab6dc
......@@ -294,10 +294,10 @@ protected:
skipTag(); if (isArray () && enterContainer()) { levels.push(Level()); return true; } handleError(qBindExpectedSequence); return false; }
bool tryRecord (quint32* s=nullptr) { if (caching) { cacheLevel++; return caching->tryRecord(s); }
skipTag(); if (isMap () && enterContainer()) { levels.push(Level()); return true; } handleError(qBindExpectedRecord ); return false; }
bool tryNull ( ) { if (caching) { cacheLevel++; return caching->tryNull() && cacheOut(); }
skipTag(); if (isNull () && next ()) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryNull ( ) { if (caching) { return caching->tryNull() && cacheOut(); }
skipTag(); if ((isNull() || isUndefined()) && next()) { 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& s) { if (caching) { cacheLevel++; return caching->tryBind(s) && cacheOut(); }
bool tryBind ( QString& s) { if (caching) { return caching->tryBind(s) && cacheOut(); }
skipTag(); if (isString()) {
s.resize(0);
auto r = readString();
......@@ -313,7 +313,7 @@ protected:
}
return true;
} else { handleError(qBindExpectedText); return false; } }
bool tryBind ( QByteArray& s) { if (caching) { cacheLevel++; return caching->tryBind(s) && cacheOut(); }
bool tryBind ( QByteArray& s) { if (caching) { return caching->tryBind(s) && cacheOut(); }
skipTag(); if (isByteArray()) {
s.resize(0);
auto r = readByteArray();
......@@ -329,12 +329,12 @@ protected:
}
return true;
} else { handleError(qBindExpectedBytes); return false; } }
bool tryBind ( bool& b) { if (caching) { cacheLevel++; return caching->tryBind(b) && cacheOut(); }
bool tryBind ( bool& b) { if (caching) { return caching->tryBind(b) && cacheOut(); }
skipTag(); if (isBool()) {
b=toBool();
return next();
} else { handleError(qBindExpectedBoolean); return false; } }
bool tryBind ( double& n) { if (caching) { cacheLevel++; return caching->tryBind(n) && cacheOut(); }
bool tryBind ( double& n) { if (caching) { return caching->tryBind(n) && cacheOut(); }
return getNumber(n); }
bool tryBind ( float& n) { double d;
if (!tryBind(d)) { return false; }
......@@ -342,12 +342,12 @@ protected:
double(std::numeric_limits<float>::max()) <d) { handleError(qBindExpectedSmallerNumber); return false; }
n=float(d); return true; }
bool tryBind ( quint64& t) { if (caching) { cacheLevel++; return caching->tryBind(t) && cacheOut(); }
bool tryBind ( quint64& t) { if (caching) { return caching->tryBind(t) && cacheOut(); }
quint64 i; bool neg;
if (!getInteger(i,neg)) { handleError(qBindExpectedInteger ); return false; }
if ( neg ) { handleError(qBindExpectedPositiveInteger); return false; }
t=i; return true; }
bool tryBind ( qint64& t) { if (caching) { cacheLevel++; return caching->tryBind(t) && cacheOut(); }
bool tryBind ( qint64& t) { if (caching) { return caching->tryBind(t) && cacheOut(); }
quint64 i; bool neg;
if (!getInteger(i,neg)) { handleError(qBindExpectedInteger ); return false; }
if ( neg ) { if (quint64(-std::numeric_limits<qint64>::min())<i) { handleError(qBindExpectedSmallerNumber); return false; } t=-qint64(i); return true; }
......@@ -409,7 +409,7 @@ protected:
return false;
}
return true; }
bool tryOut ( ) { if (caching) { return caching->tryOut() && cacheOut(); }
bool tryOut ( ) { if (caching) { bool out = caching->tryOut(); if (out) { --cacheLevel; cacheOut(); } return out; }
levels.pop();
while (hasNext()) {
tryAny();
......@@ -433,9 +433,8 @@ private:
handleError(qBindExpectedInteger); return false;
}
bool cacheOut() { Q_ASSERT(cacheLevel);
if (!--cacheLevel) {
caching=nullptr;
bool cacheOut() { if (!cacheLevel) {
caching = nullptr;
if (!device()->isSequential()) {
device()->seek(cachingAfter);
}
......@@ -471,7 +470,8 @@ struct QTransmogrifier<QCborValue> {
if (j.isDouble ()) return v.bind(j.toDouble ());
if (j.isString ()) return v.bind(j.toString ());
if (j.isByteArray()) return v.bind(j.toByteArray());
return v.null();
if (j.isNull() || j.isUndefined() || j.isInvalid() || v->handleError(qBindExpectedValue)) return v.null();
return QValueStatus();
}
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.null(); }
}
......@@ -491,9 +491,9 @@ 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( ); v->setErrorHandler(suspended); return r; }
r = v.null();
v->setErrorHandler(suspended);
v->handleError(qBindIgnoredItem);
if (r || v->handleError(qBindExpectedValue)) { j = QCborValue(); }
return r;
}
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.null(); }
......
This diff is collapsed.
......@@ -595,7 +595,7 @@ protected:
using QAbstractValue::tryBind; // full overload set so that following overloads calls work (instead of calling themselves and overflowing the call stack)
virtual bool tryNull( ) { return hidden() ? true : I<=d ? itemBind()->tryNull() : read().isNull () ; }
virtual bool tryNull( ) { return hidden() ? true : I<=d ? itemBind()->tryNull() : read().isNull () || !read().isValid(); }
virtual bool tryBind( QString&& u) { return hidden() ? true : I<=d ? itemBind()->tryBind(std::move(u)) : u==read().toString() ; }
virtual bool tryBind( bool&& b) { return hidden() ? true : I<=d ? itemBind()->tryBind(std::move(b)) : b==read().toBool () ; }
virtual bool tryBind( float&& f) { return hidden() ? true : I<=d ? itemBind()->tryBind(std::move(f)) : qFuzzyCompare(f,read().toFloat ()); }
......
This diff is collapsed.
......@@ -168,7 +168,7 @@ 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 tryNull ( ) { if (current()->isNull() ) { return true; } handleError(qBindExpectedNull ); return false; }
bool tryNull ( ) { if (current()->isNull() || !current()->isValid()) { 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(); }
......
......@@ -57,7 +57,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:[] | at (0,1) IgnoredCharacter, at (0,15) IgnoredCharacter, at (0,23) IgnoredCharacter, at (0,40) 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, (0:58)IgnoredCharacter, (0:102)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":[]}
......
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