Commit 2e29e5e7 authored by EXT Arnaud Clère's avatar EXT Arnaud Clère

Factored some error reporting

Added generic bypass of unexpected items
Fixed QSettingsReader sequence/record
Moved stop to QAbstractValue (maybe not such a good idea as it is mostly
used to ensure well-formedness that is the responsibility of the fluent
interface)
parent 28efdf9b
......@@ -137,14 +137,16 @@ protected:
bool tryBind( float& t) { return set(t); }
bool tryBind( double& t) { return set(t); }
bool trySequence(quint32* =nullptr) { if (levels.last().isGroup) { levels.push(Level( )); return true; } return false; }
bool tryRecord (quint32* =nullptr) { if (levels.last().isGroup) { levels.push(Level(qBindExpectedItem)); return true; } return false; }
bool trySequence(quint32* =nullptr) { if (settings->allKeys().contains(key()+"/size")) { levels.push(Level( )); return true; } return false; }
bool tryRecord (quint32* =nullptr) { if (settings->allKeys().contains(key()+"/" )) { levels.push(Level(qBindExpectedItem)); return true; } return false; }
bool tryNull() { return settings->value(key()).isNull(); }
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 tryItem(QIdentifier& k) { levels.last().key=k; return true; }
bool tryItem(QIdentifierLiteral n) { levels.last().key=n; return true; }
bool tryItem( ) { levels.last().idx++; return true; }
bool tryOut () { if (levels.size()<=1) return false; levels.pop(); settings->endGroup(); return true; }
bool tryAny() { return true; }
bool isValid() const noexcept { return settings; }
......
......@@ -198,6 +198,8 @@ struct QAbstractValue {
//! \warning meta() is ignored by default and subject to various interpretation, so users should define or adopt existing meta data standards like XSD for sake of interoperability
virtual void _meta(QIdentifierLiteral&, QAsciiData&) {}
virtual void stop() { Q_VERIFY(isErrorFiltered(qBindStopped)) }
virtual QValueErrorFilter setErrorFilter(QValueErrorFilter newFilter) {
auto previousHandler = errorFilter;
errorFilter = newFilter;
......@@ -264,8 +266,6 @@ protected:
bool tryBind( QUtf8Data& t) { return Q_LIKELY(impl) && (impl->tryBind(t) || (impl->isErrorFiltered(qBindExpectedText ) && impl->tryAny())); }
bool tryBind( QString& t) { return Q_LIKELY(impl) && (impl->tryBind(t) || (impl->isErrorFiltered(qBindExpectedText ) && impl->tryAny())); }
// TODO qBindExpectedConstant after successful tryBind without attempting (but testing several constants requires memoizing the bound value anyway...)
bool tryBind(const QUtf8Data& t) { return Q_LIKELY(impl) && (impl->tryBind(t) || (impl->isErrorFiltered(qBindExpectedText ) && impl->tryAny())); }
bool tryBind(const QString& t) { return Q_LIKELY(impl) && (impl->tryBind(t) || (impl->isErrorFiltered(qBindExpectedText ) && impl->tryAny())); }
bool tryBind( QUtf8Data&& t) { return Q_LIKELY(impl) && (impl->tryBind(t) || (impl->isErrorFiltered(qBindExpectedText ) && impl->tryAny())); }
......@@ -332,7 +332,7 @@ private:
template<class T> friend class QVal;
template<class T> friend class QSeq;
template<class T> friend class QRec;
void stop() noexcept { Q_VERIFY(isErrorFiltered(qBindStopped)); impl = nullptr; }
void stop() { if (Q_LIKELY(impl)) { impl->stop(); impl = nullptr; } }
QCur _unsafeCopy() noexcept { return impl ? QCur(impl) : QCur(); } // FIXME replace with std::move(outer) to avoid resuming read/write when QCur was actually stopped!
......@@ -414,7 +414,7 @@ public:
void setIsVariant() { suspendErrorHandler(); }
/**/ T_ unexpected() { return outer->isErrorFiltered(qBindUnexpectedValue) ? any() : T_(); }
/**/ T_ unexpected() { return resumeErrorHandler() && outer->isErrorFiltered(qBindUnexpectedValue) ? any() : T_(); }
/**/ T_ any() { return outer->tryAny() && resumeErrorHandler() ? std::move(outer) : T_(); }
QVal<T_> meta (QIdentifierLiteral& n, QAsciiData& m) { outer->_meta(n,m); return std::move(*this); }
......@@ -503,7 +503,6 @@ public:
QRec<QSeq<T_>> record (quint32* s=nullptr) { return item().record (s) ; }
/**/ QSeq<T_> null ( ) { return item().null ( ) ; }
/**/ QSeq<T_> any ( ) { return item().any ( ) ; }
/**/ QSeq<T_> bind ( const char* u) { return item().bind(QUtf8DataView(u)); }
/**/ QSeq<T_> bind ( QUtf8DataView u) { return item().bind (u) ; }
/**/ QSeq<T_> bind ( QAsciiDataView a) { return item().bind (a) ; }
......@@ -726,7 +725,7 @@ struct QAbstractValueWriter : public QAbstractValue
}
if (src.isNull()) return tryNull();
return isErrorFiltered(qBindUnexpectedValue) && tryAny();
return false;
}
virtual bool tryBind( QUtf8Data& r) { QUtf8Data copy(r); return tryBind(std::move(copy)); }
......@@ -773,17 +772,18 @@ struct QAbstractValueReader : public QAbstractValue
virtual bool tryItem( ) = 0;
virtual bool tryItem(QIdentifier& n) = 0;
virtual bool tryItem(QIdentifierLiteral n) { QIdentifier id; return tryItem(id) && id.utf8()==n.utf8(); }
// TODO
// QIdentifier id;
// for (;;) {
// if (!tryItem(id))
// return false;
// if (id.utf8()==n.utf8())
// return true;
// Q_VERIFY(isErrorFiltered(qBindUnexpectedItem) && tryAny())
// }
// }
virtual bool tryItem(QIdentifierLiteral n) {
QIdentifier id;
for(;;) {
if (!tryItem(id))
return false;
if (id.utf8()==n.utf8())
return true;
Q_VERIFY(isErrorFiltered(qBindUnexpectedItem, n.latin1()))
if (!tryAny())
return false;
}
}
virtual bool tryBind( const char* u) { return tryBind(QUtf8DataView(u)); }
virtual bool tryBind( QUtf8DataView u) { QUtf8Data r; if (!tryBind(r)) return false; Q_VERIFY(r.utf8()==u.data() || isErrorFiltered(qBindExpectedConstant)) return true; }
......@@ -818,8 +818,8 @@ struct QAbstractValueReader : public QAbstractValue
{
QSuspendedValueErrorHandler(this);
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(); }
if (trySequence(&size)) { QVariantList l; while (tryItem( )) { if (!tryBind(item)) { item = QVariant(); if (!(isErrorFiltered(qBindUnexpectedValue) && tryAny())) { stop(); return true; } } l.append( item); } dst = l; return tryOut(); }
if (tryRecord (&size)) { QVariantMap l; while (tryItem(key)) { if (!tryBind(item)) { item = QVariant(); if (!(isErrorFiltered(qBindUnexpectedValue) && tryAny())) { stop(); return true; } } l.insert(key.latin1(), item); } dst = l; return tryOut(); }
bool b; if (tryBind( b)) { dst = QVariant(b); return true; }
quint64 u; if (tryBind( u)) { dst = QVariant(u); return true; }
qint64 l; if (tryBind( l)) { dst = QVariant(l); return true; }
......@@ -829,7 +829,7 @@ struct QAbstractValueReader : public QAbstractValue
QString t; if (tryBind( t)) { dst = QVariant(t); return true; }
/**/ if (tryNull( )) { dst = QVariant::fromValue(nullptr); return true; }
}
return isErrorFiltered(qBindUnexpectedValue) && tryAny();
return false;
}
virtual bool tryBind(const QUtf8Data& k) { QUtf8Data r; if (!tryBind(r)) return false; Q_VERIFY(k==r || isErrorFiltered(qBindExpectedConstant)); return true; }
......
......@@ -76,5 +76,5 @@ CborValue>Cbor|a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000
Cbor>Json |{"names":["John","Doe"],"height":1.75,"age":-1,"phones":[],"comments":"","children":[]} |
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:[] | names /ExpectedItem/-1:UnexpectedItem, /ExpectedItem/-1:UnexpectedEnd, /ExpectedItem:UnexpectedValue
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:[] | /ExpectedItem:ExpectedRecord, /names:ExpectedSequence, /names:ExpectedText, /names:ExpectedText, /names:UnexpectedEnd, /names:Stopped, /names:UnexpectedValue
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