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

Added QUtf8String and all QDataStream numeric types

Removed template methods from IBind/Writer/Reader
parent 5cc756d7
This diff is collapsed.
......@@ -139,8 +139,8 @@ protected:
bool _bind ( float&& n) { return Q_LIKELY(putSimpleValue(cbor::Next32BitFloat)) && putBigEndian(n); }
bool _bind ( double&& n) { return Q_LIKELY(putSimpleValue(cbor::Next64BitFloat)) && putBigEndian(n); }
bool _bind ( qulonglong&& t) { return putInteger(quint64( t), cbor::UnsignedIntType); }
bool _bind ( qlonglong&& t) { return t<0 ? putInteger(quint64(-1-t), cbor::NegativeIntType) // see https://tools.ietf.org/html/rfc7049#section-2.1
bool _bind ( quint64&& t) { return putInteger(quint64( t), cbor::UnsignedIntType); }
bool _bind ( qint64&& t) { return t<0 ? putInteger(quint64(-1-t), cbor::NegativeIntType) // see https://tools.ietf.org/html/rfc7049#section-2.1
: putInteger(quint64( t), cbor::UnsignedIntType); }
bool _item(QName n) { return (Q_LIKELY(putInteger(qstrlen(n), cbor::TextStringType)) && (Q_LIKELY(io->write(n)) || *n=='\0')); }
......@@ -200,6 +200,7 @@ protected:
bool _sequence(quint32* =nullptr) { skipTag(); if (io->isArray () && io->enterContainer()) { return true; } _reportError(qBindExpectedSequence); return false; }
bool _record (quint32* =nullptr) { skipTag(); if (io->isMap () && io->enterContainer()) { return true; } _reportError(qBindExpectedRecord ); return false; }
bool _null ( ) { skipTag(); if (io->isNull () && io->next ()) { return true; } _reportError(qBindExpectedNull ); return false; }
bool _bind ( QUtf8String& u) { QString s; if (_bind(s)) { u = s.toUtf8(); return true; } return false; }
bool _bind ( QString& s) { skipTag(); if (io->isString()) {
s.clear();
auto r = io->readString();
......@@ -236,15 +237,13 @@ protected:
b=io->toBool();
return io->next();
} else { _reportError(qBindExpectedBoolean); return false; } }
bool _bind ( float& n) { double d; qlonglong i; bool b; auto r=getNumber(d,i,b); if (r) n=float(d); return r; }
bool _bind ( double& n) { double d; qlonglong i; bool b; auto r=getNumber(d,i,b); if (r) n= d ; return r; }
bool _bind ( float& n) { double d; qint64 i; bool neg; auto r=getNumber(d,i,neg); if (r) n=float(d); return r; }
bool _bind ( double& n) { double d; qint64 i; bool neg; auto r=getNumber(d,i,neg); if (r) n= d ; return r; }
bool _bind ( qulonglong& t) { double d; qlonglong i; bool isNegative;
auto r=getNumber(d, i, isNegative); if (r) t=i; return r; }
bool _bind ( qlonglong& t) { double d; qlonglong i; bool isNegative;
auto r=getNumber(d, i, isNegative); if (r) t=i; return r; }
bool _bind ( quint64& t) { double d; qint64 i; bool neg; auto r=getNumber(d,i,neg); if (r) t= i ; return r; }
bool _bind ( qint64& t) { double d; qint64 i; bool neg; auto r=getNumber(d,i,neg); if (r) t= i ; return r; }
bool _bind ( ) { skipTag(); // TODO use io->next() ?
bool _any ( ) { skipTag(); // TODO use io->next() ?
isChoice=true; QString s; QByteArray t; double d; bool b;
((_sequence() && _out())
||_null()
......@@ -272,7 +271,7 @@ protected:
}
return true; }
bool _out ( ) { while (io->hasNext()) {
_bind();
_any();
}
return io->leaveContainer(); }
......@@ -281,20 +280,20 @@ protected:
void _reportError(const char* e) { if (!isChoice) errors.append(Error{ e, io->currentOffset(), io->lastError() }); }
private:
void skipTag() { if (io->isTag()) { io->toTag(); io->next(); } }
bool getNumber(double& d, qlonglong&i, bool& isNegative) { skipTag();
bool getNumber(double& d, qint64&i, bool& isNegative) { skipTag();
if (io->isFloat()) {
d = double(io->toFloat());
i = qlonglong(d);
i = qint64(d);
return io->next();
}
if (io->isDouble()) {
d = io->toDouble();
i = qlonglong(d);
i = qint64(d);
return io->next();
}
if (io->isFloat16()) {
d = double(io->toFloat16());
i = qlonglong(d);
i = qint64(d);
return io->next();
}
if (io->isNegativeInteger()) {
......@@ -341,8 +340,8 @@ protected:
bool _bind ( const char* s) { set(QCborValue(s)); return true; }
bool _bind ( bool& b) { set(QCborValue(b)); return true; }
bool _bind ( double& d) { set(QCborValue(d)); return true; }
bool _bind ( qulonglong& n) { double d(n); return _bind(d); }
bool _bind ( qlonglong& n) { double d(n); return _bind(d); }
bool _bind ( quint64& n) { double d(n); return _bind(d); }
bool _bind ( qint64& n) { double d(n); return _bind(d); }
bool _item(QName n) { levels.last().key=n ; return true; }
bool _item( ) { levels.last().key=nullptr; return true; }
......
......@@ -69,8 +69,8 @@ protected:
bool _bind ( const char* s) { set(QJsonValue(s)); return true; }
bool _bind ( bool&& b) { set(QJsonValue(b)); return true; }
bool _bind ( double&& d) { set(QJsonValue(d)); return true; }
bool _bind ( qulonglong&& n) { return _bind(double(n)); }
bool _bind ( qlonglong&& n) { return _bind(double(n)); }
bool _bind ( quint64&& n) { return _bind(double(n)); }
bool _bind ( qint64&& n) { return _bind(double(n)); }
bool _item(QName n) { levels.last().key=n ; return true; }
bool _item( ) { levels.last().key=nullptr; return true; }
......@@ -121,13 +121,13 @@ protected:
bool _sequence(quint32* s=nullptr) { Q_UNUSED(s); if (current()->isArray ()) { steps.push(Step()); return true; } _reportError(qBindExpectedSequence); return false; }
bool _record (quint32* s=nullptr) { Q_UNUSED(s); if (current()->isObject()) { steps.push(Step()); return true; } _reportError(qBindExpectedRecord ); return false; }
bool _null ( ) { if (current()->isNull ()) { return true; } _reportError(qBindExpectedNull ); return false; }
bool _bind ( const char* u) { if (current()->isString() && current()->toString().toUtf8()==u) return true; _reportError(qBindExpectedLiteral ); return false; }
bool _bind ( QUtf8String& u) { QString s; if (_bind(s) ) { u = s.toUtf8() ; return true; } return false; }
bool _bind ( QString& v) { if (current()->isString()) { v = current()->toString(); return true; } _reportError(qBindExpectedText ); return false; }
bool _bind ( bool& v) { if (current()->isBool ()) { v = current()->toBool (); return true; } _reportError(qBindExpectedBoolean ); return false; }
bool _bind ( float& v) { if (current()->isDouble()) { v = current()->toDouble(); return true; } _reportError(qBindExpectedDecimal ); return false; }
bool _bind ( qint64& t) { double d; if (_bind(d) ) { t = qint64(d) ; return true; } return false; }
bool _bind ( quint64& t) { double d; if (_bind(d) ) { t = quint64(d) ; return true; } return false; }
bool _bind ( float& v) { double d; if (_bind(d) ) { v = float(d) ; return true; } return false; }
bool _bind ( double& v) { if (current()->isDouble()) { v = current()->toDouble(); return true; } _reportError(qBindExpectedDecimal ); return false; }
bool _bind ( qulonglong& t) { double d; if (_bind(d)) { t=d; return true; } else return false; }
bool _bind ( qlonglong& t) { double d; if (_bind(d)) { t=d; return true; } else return false; }
bool _item(QUtf8String& k) { steps.last().key=k; return !(steps.last().item = current(1)->toObject().value(QString::fromUtf8(steps.last().key))).isUndefined(); }
bool _item( ) { steps.last().idx++; return !(steps.last().item = current(1)->toArray (). at( steps.last().idx )).isUndefined(); }
......@@ -167,8 +167,8 @@ protected:
bool _bind ( bool&& n) { return io->write( n?"true":"false" ); }
bool _bind ( float&& n) { return io->write(QUtf8String::number(n,'g',std::numeric_limits< float>::max_digits10)); }
bool _bind ( double&& n) { return io->write(QUtf8String::number(n,'g',std::numeric_limits<double>::max_digits10)); }
bool _bind ( qulonglong&& t) { return io->write(QUtf8String::number(t)); }
bool _bind ( qlonglong&& t) { return io->write(QUtf8String::number(t)); }
bool _bind ( quint64&& t) { return io->write(QUtf8String::number(t)); }
bool _bind ( qint64&& t) { return io->write(QUtf8String::number(t)); }
bool _item(QName n) { auto r=(io->write(levels.last().sep) || *levels.last().sep=='\0') && putString(n) && io->write(":"); levels.last().sep = ","; return r; }
bool _item( ) { auto r=(io->write(levels.last().sep) || *levels.last().sep=='\0') ; levels.last().sep = ","; return r; }
......@@ -233,17 +233,13 @@ protected:
get('l', "[{\"" )) {
return true;
} else { _reportError(qBindExpectedNull); return false; } }
bool _bind ( const char* l) { QUtf8String u;
bool _bind ( QUtf8String& s) { QUtf8String u;
if ( get('"', "[{\"ntf-0123456789.")) { u.clear(); char c;
while ((c=getCharInString()) != '\0' ) { u.append(c); }
return get('"') && u==l;
} else { _reportError(qBindExpectedText); return false; } }
bool _bind ( QString& s) { QUtf8String u;
if ( get('"', "[{\"ntf-0123456789.")) { u.clear(); char c;
while ((c=getCharInString()) != '\0' ) { u.append(c); }
s=QString::fromUtf8(u); // TODO Support user-defined QTextCodec
s=u;
return get('"');
} else { _reportError(qBindExpectedText); return false; } }
bool _bind ( QString& s) { QUtf8String u; if (_bind(u)) { s = QString::fromUtf8(u); return true; } return false; } // TODO Support user-defined QTextCodec
bool _bind ( bool& b) { if (get('t', "[{\"ntf-0123456789.") &&
get('r', "[{\"" ) &&
get('u', "[{\"" ) &&
......@@ -257,14 +253,14 @@ protected:
get('e', "[{\"" )) { b=false;
return true;
} else { _reportError(qBindExpectedBoolean); return false; } }
bool _bind ( float& n) { double d; qlonglong i; bool b; auto r=getNumber(d,i,b); if (r) n=d; return r; }
bool _bind ( double& n) { double d; qlonglong i; bool b; auto r=getNumber(d,i,b); if (r) n=d; return r; }
bool _bind ( qulonglong& t) { double d; qlonglong i; bool isNegative;
auto r=getNumber(d, i, isNegative); if (r && !isNegative) t=i; return r; }
bool _bind ( qlonglong& t) { double d; qlonglong i; bool isNegative;
auto r=getNumber(d, i, isNegative); if (r) t=(isNegative?-i:i); return r; }
bool _bind ( ) { isChoice=true; QString t; double d; bool b; // FIXME Use QString instead of QByteArray
bool _bind ( float& n) { double d; quint64 i; bool neg; bool r=getNumber(d,i,neg); if (r) { if ( d<double( std::numeric_limits<float >::min())||
double( std::numeric_limits<float >::max())<d) { n = float(d); return true; } _reportError(qBindExpectedSmallerNumber ); } return false; }
bool _bind ( double& n) { double d; quint64 i; bool neg; bool r=getNumber(d,i,neg); if (r) { n = d ; } return r; }
bool _bind ( quint64& t) { double d; quint64 i; bool neg; bool r=getNumber(d,i,neg); if (r) { if (!neg ) { t = i ; return true; } _reportError(qBindExpectedPositiveNumber); } return false; }
bool _bind ( qint64& t) { double d; quint64 i; bool neg; bool r=getNumber(d,i,neg); if (r) { if (!neg && quint64(std::numeric_limits<qint64>::max())<i) { t = qint64(i); return true; }
if ( neg && -quint64(std::numeric_limits<qint64>::min())<i) { t = -qint64(i); return true; } _reportError(qBindExpectedSmallerNumber ); } return false; }
bool _any ( ) { isChoice=true; QString t; double d; bool b; // FIXME Use QString instead of QByteArray
( (_sequence() && _out())
|| _null()
|| _bind(b)
......@@ -293,7 +289,7 @@ protected:
return true; }
bool _out ( ) { auto level = levels.pop();
while (get(',', level.end)) {
_bind();
_any();
}
return get(*level.end, "}"); }
......@@ -301,16 +297,16 @@ protected:
void _setChoice(bool v) { isChoice=v; }
void _reportError(const char* e) { if (!isChoice) errors.append(Error{ e, line, column, index }); }
private:
bool getNumber(double& d, qlonglong&i, bool& isNegative) {
bool getNumber(double& d, quint64&i, bool& isNegative) {
isNegative = get('-', "[{\"0123456789.");
int digit;
qint8 digit;
if ((digit = getDigit()) < 0) {
_reportError(qBindExpectedDecimal);
return false; // do not accept no digit otherwise we may accept an empty mantissa or string!
}
i=0; d=0;
do { // TODO detect overflow
i=i*10+digit; d=d*10+digit;
do {// TODO detect overflow
i=i*10+quint8(digit); d=d*10+digit;
}
while (0 <= (digit = getDigit())); // accept many leading '0' which is more permissive than JSON
......@@ -326,7 +322,7 @@ private:
}
if ( get('e') || get('E')) {
qlonglong exponent = 0;
qint64 exponent = 0;
bool isNegativeExponent = get('-');
get('+');
while (0 <= (digit = getDigit())) {
......@@ -343,8 +339,8 @@ private:
return true;
}
int getDigit(int base = 10) { Q_ASSERT(0<base);
int digit;
qint8 getDigit(quint8 base = 10) { Q_ASSERT(0<base);
qint8 digit;
if ( 0 <= (digit=nextChar()-'0' ) && digit < base && base <= 10) { getChar(); return digit; }
if (10 <= (digit=nextChar()-'a'+10) && digit < base && base <= 36) { getChar(); return digit; }
if (10 <= (digit=nextChar()-'A'+10) && digit < base && base <= 36) { getChar(); return digit; }
......@@ -454,7 +450,7 @@ struct QBind<TResult, QJsonArray> {
if (v->mode()==Write) {
quint32 size=quint32(j.size());
auto s(v.sequence(&size));
for (QJsonValue&& item : j) {
for (QJsonValue item : j) {
s = s.bind(item);
}
return s;
......
......@@ -87,8 +87,8 @@ protected:
bool _bind( bool&& b) { return m->setData(idx, QVariant(b)); }
bool _bind( float&& f) { return m->setData(idx, QVariant(f)); }
bool _bind( double&& d) { return m->setData(idx, QVariant(d)); }
bool _bind(qulonglong&& i) { return m->setData(idx, QVariant(i)); }
bool _bind( qlonglong&& u) { return m->setData(idx, QVariant(u)); }
bool _bind(quint64&& i) { return m->setData(idx, QVariant(i)); }
bool _bind( qint64&& u) { return m->setData(idx, QVariant(u)); }
bool _bind(QByteArray&& b) { return m->setData(idx, QVariant(b)); }
// TODO BindNative all types in http://doc.qt.io/qt-5/qitemeditorfactory.html#details ?
......
......@@ -148,9 +148,9 @@ struct QBind<TResult, QVariant> {
if (src.type()==QVariant::String ) return v.bind(src.value< QString>());
if (src.type()==QVariant::Char ) return v.bind(src.toString());
if (src.type()==QVariant::ULongLong) return v.bind(src.value< qulonglong>());
if (src.type()==QVariant::ULongLong) return v.bind(src.value< quint64>());
if (src.type()==QVariant::UInt ) return v.bind(src.value<unsigned int>());
if (src.type()==QVariant::LongLong ) return v.bind(src.value< qlonglong>());
if (src.type()==QVariant::LongLong ) return v.bind(src.value< qint64>());
if (src.type()==QVariant::Int ) return v.bind(src.value< int>());
if (src.type()==QVariant::Double ) return v.bind(src.value< double>());
......@@ -177,8 +177,8 @@ struct QBind<TResult, QVariant> {
// QVariantList a; if ((r = src.bind(a))) { dst = a ; return r; } // NB We cannot try QStringList before QVariantList as it will always work with our logical model...
// QVariantMap o; if ((r = src.bind(o))) { dst = o ; return r; }
// bool b; if ((r = src.bind(b))) { dst = QVariant(b); return r; }
// qulonglong u; if ((r = src.bind(u))) { dst = QVariant(u); return r; }
// qlonglong l; if ((r = src.bind(l))) { dst = QVariant(l); return r; }
// quint64 u; if ((r = src.bind(u))) { dst = QVariant(u); return r; }
// qint64 l; if ((r = src.bind(l))) { dst = QVariant(l); return r; }
// double d; if ((r = src.bind(d))) { dst = QVariant(d); return r; }
// QByteArray x; if ((r = src.bind(x))) { dst = QVariant(x); return r; }
// QString t; if ((r = src.bind(t))) { dst = QVariant(t); return r; }
......
......@@ -185,7 +185,7 @@ int main(int argc, char *argv[])
return -1;
// Read-only args
QString ascii("ascii characters are common in QDebug");
const char* ascii = "ascii characters are common in QDebug";
QColor color(45,0,186);
QVector<double> transform{1./3, 2./3, 1./3, 1.,
2./3, 1./3, 2./3, 1.,
......@@ -251,7 +251,7 @@ int main(int argc, char *argv[])
QCborWriter(&b).value().sequence(5)
.bind(1.333333333333f)
.bind(PI)
.bind(ascii.toUtf8().constData())
.bind(ascii)
.bind(false)
.bind(color)
;
......
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