Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

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

Added auto closing of unused QSeq/QRec

Fixed illegal QSeq<T_>() calls (outside QVal)
parent 39a55e64
...@@ -249,11 +249,10 @@ public: ...@@ -249,11 +249,10 @@ public:
/**/ QSequence sequence(quint32* s=nullptr) { return QCur(this).value().sequence(s); } /**/ 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)); } template<typename T> QCur bind ( T&& t) { return QCur(this).value().bind(std::forward<T>(t)); }
protected: protected:
bool trySequence(quint32* =nullptr) { if (current().isArray ()) { steps.push(Step()); return true; } handleError(qBindExpectedSequence); 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 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 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 ( 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 ( 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 ( 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; } bool tryBind ( qint64& t) { if (current().isInteger ()) { t = current().toInteger (); return true; } handleError(qBindExpectedInteger ); return false; }
...@@ -265,10 +264,11 @@ protected: ...@@ -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(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(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 tryItem( ) { steps.last().idx++; return !(steps.last().item = current(1).toArray(). at(steps.last().idx )).isUndefined(); }
bool tryOut ( ) { steps.pop() ; return true; } bool tryOut ( ) { steps.pop() ; return true; }
bool isValid() const noexcept { return cbor; } bool tryAny() { return true; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; } bool isValid() const noexcept { return cbor; }
bool handleError(QIdentifierLiteral e, QString context = QString()) { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
private: private:
const QCborValue& current(int outer=0) const { Q_ASSERT(0<=outer); return steps.size()-outer <= 0 ? *cbor : steps[steps.size()-outer-1].item; } 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: ...@@ -414,13 +414,11 @@ protected:
return false; return false;
} }
return true; } return true; }
bool tryOut ( ) { if (caching) { bool out = caching->tryOut(); if (out) { --cacheLevel; cacheOut(); } return out; } bool tryOut ( ) { if (caching) { bool out = caching->tryOut(); if (out) { --cacheLevel; cacheOut(); } return out; }
levels.pop(); levels.pop();
while (hasNext()) { while (hasNext()) { tryAny(); }
tryAny(); return leaveContainer(); }
}
return leaveContainer(); }
bool isValid() const noexcept { return const_cast<QCborReader*>(this)->lastError()==QCborError::NoError; } 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()) { return errorHandler ? errorHandler(e, QString("at index:%1 ").arg(currentOffset()).append(context)) : false; }
private: private:
...@@ -473,21 +471,20 @@ struct QTransmogrifier<QCborValue> { ...@@ -473,21 +471,20 @@ struct QTransmogrifier<QCborValue> {
if (j.isInteger ()) return v.bind(j.toInteger ()); if (j.isInteger ()) return v.bind(j.toInteger ());
if (j.isDouble ()) return v.bind(j.toDouble ()); if (j.isDouble ()) return v.bind(j.toDouble ());
if (j.isString ()) return v.bind(j.toString ()); if (j.isString ()) return v.bind(j.toString ());
if (j.isByteArray()) return v.bind(j.toByteArray()); if (j.isByteArray()) return v.bind(j.toByteArray());
if (j.isNull ()) return v.null(); if (j.isNull ()) return v.null();
if (j.isUndefined() || j.isInvalid() || v->handleError(qBindUnexpectedValue)) return v.any(); return (j.isUndefined() || v->handleError(qBindUnexpectedValue)) ? v.any() : QValueEnd();
return QCur(); }
} else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueEnd zap(QValue&& v, QCborValue& j) { static QValueEnd zap(QValue&& v, QCborValue& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
else if (v->mode()==Read) { else if (v->mode()==Read) {
QCur r; QValueEnd r;
auto suspended = v->setErrorHandler(); auto suspended = v->setErrorHandler();
QCborArray a; if ((r = v.bind(a))) { j = a ; v->setErrorHandler(suspended); return r; } 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; } 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; } 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; } bool b; if ((r = v.bind(b))) { j = QCborValue( b ); v->setErrorHandler(suspended); return r; }
...@@ -496,11 +493,11 @@ struct QTransmogrifier<QCborValue> { ...@@ -496,11 +493,11 @@ struct QTransmogrifier<QCborValue> {
j = QCborValue(double(u)); v->setErrorHandler(suspended); return r; } j = QCborValue(double(u)); v->setErrorHandler(suspended); return r; }
double d; if ((r = v.bind(d))) { j = QCborValue( d ); 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; } 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; } /**/ if ((r = v.null( ))) { j = QCborValue( nullptr ); v->setErrorHandler(suspended); return r; }
v->setErrorHandler(suspended); v->setErrorHandler(suspended);
if ((r = v.any()) || v->handleError(qBindUnexpectedValue)) { j = QCborValue(); } if ((r = v.any())) { j = QCborValue(); }
return r; return r;
} }
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
}; };
......
...@@ -70,7 +70,6 @@ protected: ...@@ -70,7 +70,6 @@ protected:
friend class QCur; friend class QCur;
bool trySequence(quint32* s=nullptr) { if (s) *io << *s; return true; } bool trySequence(quint32* s=nullptr) { if (s) *io << *s; return true; }
bool tryRecord (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 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); } 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: ...@@ -121,7 +121,6 @@ public:
protected: protected:
bool trySequence(quint32* =nullptr) { if (current().isArray ()) { steps.push(Step()); return true; } handleError(qBindExpectedSequence); return false; } 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 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 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 ( 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 ( QString& v) { if (current().isString()) { v = current().toString(); return true; } handleError(qBindExpectedText ); return false; }
...@@ -136,6 +135,7 @@ protected: ...@@ -136,6 +135,7 @@ protected:
bool tryItem( ) { steps.last().idx++; return !(steps.last().item = current(1).toArray (). at(steps.last().idx )).isUndefined(); } bool tryItem( ) { steps.last().idx++; return !(steps.last().item = current(1).toArray (). at(steps.last().idx )).isUndefined(); }
bool tryOut ( ) { steps.removeLast(); return true; } bool tryOut ( ) { steps.removeLast(); return true; }
bool tryAny() { return true; }
bool isValid() const noexcept { 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()) { return errorHandler ? errorHandler(e, QString(currentPath().latin1()).append(context)) : false; }
private: private:
...@@ -166,7 +166,7 @@ protected: ...@@ -166,7 +166,7 @@ protected:
bool trySequence(quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step{"","]"}); return putChar('['); } 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 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 tryNull ( ) { return write("null"); }
bool tryBind ( QUtf8DataView u) { return putString(u.data(), u.size()); } bool tryBind ( QUtf8DataView u) { return putString(u.data(), u.size()); }
// JSON literals // JSON literals
......
...@@ -52,7 +52,7 @@ class QSettingsWriter : public QAbstractValueWriter ...@@ -52,7 +52,7 @@ class QSettingsWriter : public QAbstractValueWriter
{ {
Q_DISABLE_COPY(QSettingsWriter) Q_DISABLE_COPY(QSettingsWriter)
public: 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 // Shortcuts
/**/ QValue value ( ) { return QCur(this).value(); } /**/ QValue value ( ) { return QCur(this).value(); }
...@@ -69,16 +69,19 @@ protected: ...@@ -69,16 +69,19 @@ protected:
bool tryAny () { settings->setValue(key(), QVariant() ); return true; } bool tryAny () { settings->setValue(key(), QVariant() ); return true; }
bool tryNull() { settings->setValue(key(), QVariant::fromValue(nullptr)); 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 trySequence(quint32* =nullptr) { levels.push(Level( )); settings->beginGroup(key()); return true; } // TODO use beginWriteArray
bool tryRecord (quint32* =nullptr) { settings->beginGroup(key()); levels.push(Level(qBindExpectedItem)); return true; } 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(QIdentifier& n) { levels.last().key=n; return true; }
bool tryItem( ) { levels.last().idx++; 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: private:
QString key() { QString key() {
Q_ASSERT(!levels.isEmpty()); return levels.size()==0 ? QString("") :
return levels.size()==1 ? QString("") :
!levels.last().key.isNull() !levels.last().key.isNull()
? QString (levels.last().key.latin1()) ? QString (levels.last().key.latin1())
: QString::number(levels.last().idx ); : QString::number(levels.last().idx );
...@@ -132,13 +135,13 @@ protected: ...@@ -132,13 +135,13 @@ protected:
bool trySequence(quint32* =nullptr) { if (levels.last().isGroup) { levels.push(Level( )); return true; } handleError(qBindExpectedSequence); return false; } 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 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(QIdentifier& k) { levels.last().key=k ; return true; }
bool tryItem( ) { levels.last().idx++ ; 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; }
bool tryAny() { return true; }
bool isValid() const noexcept { return settings; } 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 error, QString context = QString()) { return errorHandler ? errorHandler(error, QString(currentPath().latin1()).append(context)) : false; }
private: private:
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
// ////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////
// Standard error names // 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 qBindExpectedItem;
extern QIdentifierLiteral qBindExpectedNull; extern QIdentifierLiteral qBindExpectedNull;
extern QIdentifierLiteral qBindExpectedSequence; extern QIdentifierLiteral qBindExpectedSequence;
...@@ -278,7 +278,11 @@ public: ...@@ -278,7 +278,11 @@ public:
explicit operator bool() const noexcept { return impl && impl->isValid(); } //!< Drives QTransmogrifier<T>::bind() traversal explicit operator bool() const noexcept { return impl && impl->isValid(); } //!< Drives QTransmogrifier<T>::bind() traversal
QCur* operator ->() noexcept { return this; } QCur* operator ->() noexcept { return this; }
QVal<QCur> value() noexcept ; 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; } 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; } 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 ...@@ -396,7 +400,7 @@ template<class T_> class QSeq
Q_DISABLE_COPY(QSeq) Q_DISABLE_COPY(QSeq)
public: public:
Q_ENABLE_MOVE_DEFAULT(QSeq) 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 explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal
QCur* operator->() noexcept { return outer.operator ->(); } QCur* operator->() noexcept { return outer.operator ->(); }
...@@ -429,6 +433,9 @@ public: ...@@ -429,6 +433,9 @@ public:
// Shortcut // Shortcut
template<typename T> QSeq<T_> operator<<(T&& t) { return item().bind(std::forward<T>(t)); } // stream compatible template<typename T> QSeq<T_> operator<<(T&& t) { return item().bind(std::forward<T>(t)); } // stream compatible
private: private:
template<class T_> friend class QVal;
explicit QSeq(T_&& out) noexcept { std::swap(outer, out); }
template<typename T, typename TEnabledIf> friend struct QTransmogrifier; template<typename T, typename TEnabledIf> friend struct QTransmogrifier;
QValue unsafeItem() noexcept { return outer->tryItem() ? QValue(outer->_unsafeCopy()) : QValue(); } QValue unsafeItem() noexcept { return outer->tryItem() ? QValue(outer->_unsafeCopy()) : QValue(); }
QSequence unsafeThis() noexcept { return QSequence(outer->_unsafeCopy()) ; } QSequence unsafeThis() noexcept { return QSequence(outer->_unsafeCopy()) ; }
...@@ -441,13 +448,13 @@ template<class T_> class QRec ...@@ -441,13 +448,13 @@ template<class T_> class QRec
Q_DISABLE_COPY(QRec) Q_DISABLE_COPY(QRec)
public: public:
Q_ENABLE_MOVE_DEFAULT(QRec) 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 explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal
QCur* operator->() noexcept { return outer.operator ->(); } QCur* operator->() noexcept { return outer.operator ->(); }
operator QValueEnd() { return out(); /* calls T_::operator QValueEnd() if T_ != QValueEnd */ } 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(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_>>(); } 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: ...@@ -469,6 +476,9 @@ public:
/**/ QRec<T_> with (const char* n, QValLambda customBind) { return item(n).with( customBind); } /**/ 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); } template<typename T> QRec<T_> with (const char* n, T& t, QValFunction<T> customBind) { return item(n).bind(t, customBind); }
private: private:
template<class T_> friend class QVal;
explicit QRec(T_&& out) noexcept { std::swap(outer, out); }
template<typename T, typename TEnabledIf> friend struct QTransmogrifier; template<typename T, typename TEnabledIf> friend struct QTransmogrifier;
QValue unsafeItem(QIdentifier& n) noexcept { return outer->tryItem(n) ? QValue(outer._unsafeCopy()) : QValue(); } QValue unsafeItem(QIdentifier& n) noexcept { return outer->tryItem(n) ? QValue(outer._unsafeCopy()) : QValue(); }
...@@ -693,7 +703,6 @@ struct QAbstractValueReader : public QAbstractValue ...@@ -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( QByteArray& b) { QUtf8Data s; if (!tryBind(s)) return false; return toByteArray(b, s); }
virtual bool tryBind( QVariant& dst) { virtual bool tryBind( QVariant& dst) {
auto suspended = setErrorHandler(); auto suspended = setErrorHandler();
quint32 size=0; QIdentifier key; QVariant item; 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 (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 (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 ...@@ -706,7 +715,7 @@ struct QAbstractValueReader : public QAbstractValue
QString t; if (tryBind( t)) { dst = QVariant(t); return true; } QString t; if (tryBind( t)) { dst = QVariant(t); return true; }
/**/ if (tryNull( )) { dst = QVariant::fromValue(nullptr); return true; } /**/ if (tryNull( )) { dst = QVariant::fromValue(nullptr); return true; }
setErrorHandler(suspended); setErrorHandler(suspended);
if (tryAny() || handleError(qBindUnexpectedValue)) { dst = QVariant(); return true; } if (tryAny()) { dst = QVariant(); return true; }
return false; return false;
} }
...@@ -1161,7 +1170,7 @@ struct QTransmogrifier<QValue> { ...@@ -1161,7 +1170,7 @@ struct QTransmogrifier<QValue> {
QValue srcVal; QValue dstVal; 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 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(); dstVal = dstSeq.unsafeItem();
srcSeq = QSequence(srcVal.bind(std::move(dstVal))); srcVal.bind(std::move(dstVal));
} }
/**/ dstSeq.out(); /**/ dstSeq.out();
...@@ -1174,7 +1183,7 @@ struct QTransmogrifier<QValue> { ...@@ -1174,7 +1183,7 @@ struct QTransmogrifier<QValue> {
QIdentifier srcKey; QValue srcVal; QValue dstVal; QIdentifier srcKey; QValue srcVal; QValue dstVal;
while((srcVal = srcRec.unsafeItem(srcKey))) { while((srcVal = srcRec.unsafeItem(srcKey))) {
dstVal = dstRec.unsafeItem(srcKey); dstVal = dstRec.unsafeItem(srcKey);
srcRec = QRecord(srcVal.bind(std::move(dstVal))); srcVal.bind(std::move(dstVal));
} }
/**/ dstRec.out(); /**/ dstRec.out();
...@@ -1201,7 +1210,7 @@ struct QTransmogrifier<QValue> { ...@@ -1201,7 +1210,7 @@ struct QTransmogrifier<QValue> {
// TODO Other BindNative types we do not want to treat as text: QDateTime, QUuid // 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; } /**/ if ((srcEnd = src.null( ))) { dst.null( ); src->setErrorHandler(suspended); return srcEnd; }
src->setErrorHandler(suspended); src->setErrorHandler(suspended);
if ((srcEnd = src.any()) || src->handleError(qBindUnexpectedValue)) { dst.any(); } if ((srcEnd = src.any())) { dst.any(); return srcEnd; }
return QValueEnd(); 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.) 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: ...@@ -170,13 +170,13 @@ protected:
bool trySequence(quint32* =nullptr) { if (current()->type()==QVariant::List ) { levels.push(Level()); return true; } handleError(qBindExpectedSequence); return false; } 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 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 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(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 tryItem( ) { levels.last().idx++; return (levels.last().item = current(1)->toList().value( levels.last().idx , QVariant())).isValid(); }
bool tryOut ( ) { levels.pop() ; return true; } bool tryOut ( ) { levels.pop() ; return true; }
bool tryAny () { return true; }
bool isValid() const noexcept { return value; } 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 error, QString context = QString()) { return errorHandler ? errorHandler(error, QString(currentPath().latin1()).append(context)) : false; }
private: private:
......
...@@ -658,7 +658,6 @@ int main(int argc, char *argv[]) ...@@ -658,7 +658,6 @@ int main(int argc, char *argv[])
QXmlStreamWriter w(&ba); QXmlStreamWriter w(&ba);
QXmlWriter d(&w); QXmlWriter d(&w);
d.bind(person); d.bind(person);
w.writeEndDocument(); // FIXME It should not be necessary
} }
STOP("Xml",ba) STOP("Xml",ba)
START { START {
......
...@@ -2,7 +2,7 @@ builtin> |================================================================= ...@@ -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) 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] 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}] 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] Variant | 1.33333 3.14159 ascii characters are common in QDebug false [ RGB:[ 45 0 186] base:255]
Cbor |85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff Cbor |85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff
QCborStream |85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff QCborStream |85fa3faaaaabfb400921fb54442d187825617363696920636861726163746572732061726520636f6d6d6f6e20696e20514465627567f4bf635247429f182d0018baff646261736518ffff
...@@ -31,7 +31,6 @@ QDebug |Person("John", "Doe", 1.75, 18, QVector(), "unicode is likely U+0 ...@@ -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:[] 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":[]} 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> 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:[] 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 Cbor |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765126670686f6e65738068636f6d6d656e74737843756e69636f6465206973206c696b656c7920552b30312001202b20552b3146201f202b20552b413420c2a420552b423020c2b020552b443820c39820552b464620c3bf686368696c6472656e80ff
QCborStream |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765126670686f6e65738068636f6d6d656e74737843756e69636f6465206973206c696b656c7920552b30312001202b20552b3146201f202b20552b413420c2a420552b423020c2b020552b443820c39820552b464620c3bf686368696c6472656e80ff QCborStream |bf656e616d65739f644a6f686e63446f65ff66686569676874fb3ffc00000000000063616765126670686f6e65738068636f6d6d656e74737843756e69636f6465206973206c696b656c7920552b30312001202b20552b3146201f202b20552b413420c2a420552b423020c2b020552b443820c39820552b464620c3bf686368696c6472656e80ff
...@@ -57,7 +56,7 @@ Bindable | ...@@ -57,7 +56,7 @@ Bindable |
Bindable>Cbor |bf647479706502666e756d6265726b2b34342031323334353637ff Bindable>Cbor |bf647479706502666e756d6265726b2b34342031323334353637ff
Bindable>Json |{"type":2,"number":"+44 1234567"} Bindable>Json |{"type":2,"number":"+44 1234567"}
Person<>Json |================================================================================ 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":[]} 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:[] | 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":[]} P>JsonValue |{"age":-1,"children":[],"comments":"","height":1.7500000000000004,"names":["John","Doe"],"phones":[]}
...@@ -73,7 +72,7 @@ P>CborValue |a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000 ...@@ -73,7 +72,7 @@ P>CborValue |a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000
CborValue>P |(Person) names:[ John Doe] height:1.75 age:-1 phones:[] comments: children:[] | 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": []} | Cbor>CborValue|{"names": ["John", "Doe"], "height": 1.75, "age": -1, "phones": [], "comments": "", "children": []} |
CborValue>Cbor|a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000063616765206670686f6e65738068636f6d6d656e747360686368696c6472656e80 CborValue>Cbor|a6656e616d657382644a6f686e63446f6566686569676874fb3ffc00000000000063616765206670686f6e65738068636f6d6d656e747360686368696c6472656e80
Cbor>Json |{"names":["John","Doe"],"height":1.75,"age":} | 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:[] 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:[] | 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