Some bugs fixed

float support added
float, double, QByteArray, QList<T> to MsgPackStream added
float, double, QByteArrat tests for MsgPackStream added
This commit is contained in:
Roman
2015-05-24 22:31:35 +03:00
parent 1277a0c204
commit 7d5d72e814
8 changed files with 272 additions and 39 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ build
lib lib
Makefile Makefile
*.autosave *.autosave
bin/

View File

@ -216,7 +216,7 @@ quint8 *MsgPackPrivate::pack_float(float f, quint8 *p, bool wr)
if (wr) *p = 0xca; if (wr) *p = 0xca;
p++; p++;
if (wr) { if (wr) {
quint8 *d = (quint8 *)&i; quint8 *d = (quint8 *)&f;
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
*(p + 3 - i) = *(d + i); *(p + 3 - i) = *(d + i);
@ -225,10 +225,9 @@ quint8 *MsgPackPrivate::pack_float(float f, quint8 *p, bool wr)
*(p + i) = *(d + i); *(p + i) = *(d + i);
#endif #endif
} }
return p + 8; return p + 4;
} }
quint8 *MsgPackPrivate::pack_double(double i, quint8 *p, bool wr) quint8 *MsgPackPrivate::pack_double(double i, quint8 *p, bool wr)
{ {
if (wr) *p = 0xcb; if (wr) *p = 0xcb;
@ -246,9 +245,8 @@ quint8 *MsgPackPrivate::pack_double(double i, quint8 *p, bool wr)
return p + 8; return p + 8;
} }
quint8 *MsgPackPrivate::pack_bin(const QByteArray &arr, quint8 *p, bool wr) quint8 *MsgPackPrivate::pack_bin_header(quint32 len, quint8 *p, bool wr)
{ {
int len = arr.length();
if (len <= std::numeric_limits<quint8>::max()) { if (len <= std::numeric_limits<quint8>::max()) {
if (wr) *p = compatibilityMode ? 0xd9 : 0xc4; if (wr) *p = compatibilityMode ? 0xd9 : 0xc4;
p++; p++;
@ -265,9 +263,15 @@ quint8 *MsgPackPrivate::pack_bin(const QByteArray &arr, quint8 *p, bool wr)
if (wr) _msgpack_store32(p, len); if (wr) _msgpack_store32(p, len);
p += 4; p += 4;
} }
return p;
}
quint8 *MsgPackPrivate::pack_bin(const QByteArray &arr, quint8 *p, bool wr)
{
quint32 len = arr.length();
p = pack_bin_header(len, p, wr);
if (wr) memcpy(p, arr.data(), len); if (wr) memcpy(p, arr.data(), len);
p += len; p += len;
return p; return p;
} }

View File

@ -40,6 +40,7 @@ quint8 * pack_string_raw(const char *str, quint32 len, quint8 *p, bool wr);
quint8 * pack_string(const QString &str, quint8 *p, bool wr); quint8 * pack_string(const QString &str, quint8 *p, bool wr);
quint8 * pack_float(float f, quint8 *p, bool wr); quint8 * pack_float(float f, quint8 *p, bool wr);
quint8 * pack_double(double i, quint8 *p, bool wr); quint8 * pack_double(double i, quint8 *p, bool wr);
quint8 * pack_bin_header(quint32 len, quint8 *p, bool wr);
quint8 * pack_bin(const QByteArray &arr, quint8 *p, bool wr); quint8 * pack_bin(const QByteArray &arr, quint8 *p, bool wr);
quint8 * pack_map(const QVariantMap &map, quint8 *p, bool wr, QVector<QByteArray> &user_data); quint8 * pack_map(const QVariantMap &map, quint8 *p, bool wr, QVector<QByteArray> &user_data);
quint8 * pack_user(const QVariant &v, quint8 *p, bool wr, QVector<QByteArray> &user_data); quint8 * pack_user(const QVariant &v, quint8 *p, bool wr, QVector<QByteArray> &user_data);

View File

@ -209,7 +209,7 @@ MsgPackStream &MsgPackStream::operator>>(float &f)
CHECK_STREAM_PRECOND(*this); CHECK_STREAM_PRECOND(*this);
quint8 *fp = (quint8 *)&f; quint8 *fp = (quint8 *)&f;
quint8 p[5]; quint8 p[5];
if (dev->read((char *)&p, 1) != 1) { if (dev->read((char *)p, 1) != 1) {
setStatus(ReadPastEnd); setStatus(ReadPastEnd);
return *this; return *this;
} }
@ -217,6 +217,10 @@ MsgPackStream &MsgPackStream::operator>>(float &f)
setStatus(ReadCorruptData); setStatus(ReadCorruptData);
return *this; return *this;
} }
if (dev->read((char *)p + 1, 4) != 4) {
setStatus(ReadPastEnd);
return *this;
}
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
*(fp + 3 - i) = *(p + i + 1); *(fp + 3 - i) = *(p + i + 1);
@ -230,9 +234,9 @@ MsgPackStream &MsgPackStream::operator>>(float &f)
MsgPackStream &MsgPackStream::operator>>(double &d) MsgPackStream &MsgPackStream::operator>>(double &d)
{ {
CHECK_STREAM_PRECOND(*this); CHECK_STREAM_PRECOND(*this);
quint8 *fp = (quint8 *)&f; quint8 *fp = (quint8 *)&d;
quint8 p[9]; quint8 p[9];
if (dev->read((char *)&p, 1) != 1) { if (dev->read((char *)p, 1) != 1) {
setStatus(ReadPastEnd); setStatus(ReadPastEnd);
return *this; return *this;
} }
@ -240,6 +244,10 @@ MsgPackStream &MsgPackStream::operator>>(double &d)
setStatus(ReadCorruptData); setStatus(ReadCorruptData);
return *this; return *this;
} }
if (dev->read((char *)p + 1, 8) != 8) {
setStatus(ReadPastEnd);
return *this;
}
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
*(fp + 7 - i) = *(p + i + 1); *(fp + 7 - i) = *(p + i + 1);
@ -287,17 +295,39 @@ MsgPackStream &MsgPackStream::operator>>(QString &str)
MsgPackStream &MsgPackStream::operator>>(QByteArray &array) MsgPackStream &MsgPackStream::operator>>(QByteArray &array)
{ {
CHECK_STREAM_PRECOND(*this);
} quint8 p[5];
if (dev->read((char *)p, 1) != 1) {
MsgPackStream &MsgPackStream::operator>>(QVariantList &list) setStatus(ReadPastEnd);
{ return *this;
}
} quint32 len;
if (p[0] == MsgPack::FirstByte::BIN8) {
MsgPackStream &MsgPackStream::operator>>(QVariantMap &map) if (dev->read((char *)p + 1, 1) != 1) {
{ setStatus(ReadPastEnd);
return *this;
}
len = p[1];
} else if (p[0] == MsgPack::FirstByte::BIN16) {
if (dev->read((char *)p + 1, 2) != 2) {
setStatus(ReadPastEnd);
return *this;
}
len = _msgpack_load16(quint16, &p[1]);
} else if (p[0] == MsgPack::FirstByte::BIN32) {
if (dev->read((char *)p + 1, 4) != 4) {
setStatus(ReadPastEnd);
return *this;
}
len = _msgpack_load32(quint32, &p[1]);
} else {
setStatus(ReadCorruptData);
return *this;
}
array.resize(len);
if (dev->read(array.data(), len) != len)
setStatus(ReadPastEnd);
return *this;
} }
MsgPackStream &MsgPackStream::operator<<(bool b) MsgPackStream &MsgPackStream::operator<<(bool b)
@ -364,7 +394,7 @@ MsgPackStream &MsgPackStream::operator<<(double d)
{ {
CHECK_STREAM_WRITE_PRECOND(*this); CHECK_STREAM_WRITE_PRECOND(*this);
quint8 p[9]; quint8 p[9];
quint8 sz = MsgPackPrivate::pack_float(d, p, true) - p; quint8 sz = MsgPackPrivate::pack_double(d, p, true) - p;
if (dev->write((char *)p, sz) != sz) if (dev->write((char *)p, sz) != sz)
setStatus(WriteFailed); setStatus(WriteFailed);
return *this; return *this;
@ -399,17 +429,17 @@ MsgPackStream &MsgPackStream::operator<<(const char *str)
MsgPackStream &MsgPackStream::operator<<(QByteArray array) MsgPackStream &MsgPackStream::operator<<(QByteArray array)
{ {
CHECK_STREAM_WRITE_PRECOND(*this);
} quint8 p[5];
quint32 len = array.length();
MsgPackStream &MsgPackStream::operator<<(QVariantList list) quint8 header_len = MsgPackPrivate::pack_bin_header(len, p, true) - p;
{ if (dev->write((char *)p, header_len) != header_len) {
setStatus(WriteFailed);
} return *this;
}
MsgPackStream &MsgPackStream::operator<<(QVariantMap map) if (dev->write(array.data(), len) != len)
{ setStatus(WriteFailed);
return *this;
} }
bool MsgPackStream::unpack_upto_quint8(quint8 &u8, quint8 *p) bool MsgPackStream::unpack_upto_quint8(quint8 &u8, quint8 *p)

View File

@ -33,8 +33,6 @@ public:
MsgPackStream &operator>>(double &d); MsgPackStream &operator>>(double &d);
MsgPackStream &operator>>(QString &str); MsgPackStream &operator>>(QString &str);
MsgPackStream &operator>>(QByteArray &array); MsgPackStream &operator>>(QByteArray &array);
MsgPackStream &operator>>(QVariantList &list);
MsgPackStream &operator>>(QVariantMap &map);
MsgPackStream &operator<<(bool b); MsgPackStream &operator<<(bool b);
MsgPackStream &operator<<(quint32 u32); MsgPackStream &operator<<(quint32 u32);
@ -46,8 +44,6 @@ public:
MsgPackStream &operator<<(QString str); MsgPackStream &operator<<(QString str);
MsgPackStream &operator<<(const char *str); MsgPackStream &operator<<(const char *str);
MsgPackStream &operator<<(QByteArray array); MsgPackStream &operator<<(QByteArray array);
MsgPackStream &operator<<(QVariantList list);
MsgPackStream &operator<<(QVariantMap map);
private: private:
QIODevice *dev; QIODevice *dev;
@ -64,4 +60,29 @@ private:
bool unpack_upto_qint64(qint64 &i64, quint8 *p); bool unpack_upto_qint64(qint64 &i64, quint8 *p);
}; };
template <typename T>
MsgPackStream& operator<<(MsgPackStream& s, const QList<T> &list)
{
s << (quint32)list.size();
for (int i = 0; i < list.size(); ++i)
s << list[i];
return s;
}
template <typename T>
MsgPackStream& operator>>(MsgPackStream& s, QList<T> &list)
{
list.clear();
quint32 size;
s >> size;
for (quint32 i = 0; i < size; ++i) {
T t;
s >> t;
list.append(t);
if (s.atEnd())
break;
}
return s;
}
#endif // STREAM_H #endif // STREAM_H

View File

@ -8,11 +8,85 @@ class MixedTest : public QObject
Q_OBJECT Q_OBJECT
private Q_SLOTS: private Q_SLOTS:
void test_float();
void test_double();
void test_map(); void test_map();
void test_ext(); void test_ext();
void test_mixed(); void test_mixed();
}; };
void MixedTest::test_float()
{
float f;
QByteArray packed;
packed = MsgPack::pack(0.0f);
f = MsgPack::unpack(packed).toFloat();
QVERIFY(f == 0.0f);
QVERIFY(packed.size() == 5);
packed = MsgPack::pack(-0.0f);
f = MsgPack::unpack(packed).toFloat();
QVERIFY(f == -0.0f);
QVERIFY(packed.size() == 5);
packed = MsgPack::pack(1.0f);
f = MsgPack::unpack(packed).toFloat();
QVERIFY(f == 1.0f);
QVERIFY(packed.size() == 5);
packed = MsgPack::pack(-1.0f);
f = MsgPack::unpack(packed).toFloat();
QVERIFY(f == -1.0f);
QVERIFY(packed.size() == 5);
packed = MsgPack::pack(32767.0f);
f = MsgPack::unpack(packed).toFloat();
QVERIFY(f == 32767.0f);
QVERIFY(packed.size() == 5);
packed = MsgPack::pack(-32767.0f);
f = MsgPack::unpack(packed).toFloat();
QVERIFY(f == -32767.0f);
QVERIFY(packed.size() == 5);
}
void MixedTest::test_double()
{
double d;
QByteArray packed;
packed = MsgPack::pack(0.0);
d = MsgPack::unpack(packed).toDouble();
QVERIFY(d == 0.0);
QVERIFY(packed.size() == 9);
packed = MsgPack::pack(-0.0);
d = MsgPack::unpack(packed).toDouble();
QVERIFY(d == -0.0);
QVERIFY(packed.size() == 9);
packed = MsgPack::pack(1.0);
d = MsgPack::unpack(packed).toDouble();
QVERIFY(d == 1.0);
QVERIFY(packed.size() == 9);
packed = MsgPack::pack(-1.0);
d = MsgPack::unpack(packed).toDouble();
QVERIFY(d == -1.0);
QVERIFY(packed.size() == 9);
packed = MsgPack::pack(32767.0);
d = MsgPack::unpack(packed).toDouble();
QVERIFY(d == 32767.0);
QVERIFY(packed.size() == 9);
packed = MsgPack::pack(-32767.0);
d = MsgPack::unpack(packed).toDouble();
QVERIFY(d == -32767.0);
QVERIFY(packed.size() == 9);
}
void MixedTest::test_map() void MixedTest::test_map()
{ {
QVariantMap map; QVariantMap map;

View File

@ -271,7 +271,7 @@ void PackTest::test_bin()
QVERIFY(p[2] == 0x00); QVERIFY(p[2] == 0x00);
QVERIFY(memcmp(p + 3, ba.data(), ba.size()) == 0); QVERIFY(memcmp(p + 3, ba.data(), ba.size()) == 0);
ba = QByteArray(65536, 'r'); ba = QByteArray(65536, 'x');
arr = MsgPack::pack(ba); arr = MsgPack::pack(ba);
QVERIFY(arr.size() == ba.size() + 5); QVERIFY(arr.size() == ba.size() + 5);
p = (quint8 *)arr.data(); p = (quint8 *)arr.data();

View File

@ -14,7 +14,9 @@ private Q_SLOTS:
void test_pack_integers(); void test_pack_integers();
void test_unpack_string(); void test_unpack_string();
void test_pack_string(); void test_pack_string();
void test_float();
void test_double();
void test_bin();
}; };
void StreamTest::test_unpack_integers() void StreamTest::test_unpack_integers()
@ -203,7 +205,107 @@ void StreamTest::test_pack_string()
QVERIFY(l[4].isEmpty()); QVERIFY(l[4].isEmpty());
} }
void StreamTest::test_float()
{
QByteArray packed;
{
MsgPackStream stream(&packed, QIODevice::WriteOnly);
stream << -0.0f << 0.0f << -1.0f << 1.0f << -32767.0f << 32767.0f;
QVERIFY(packed.size() == 6 * 5);
QVERIFY(stream.status() == MsgPackStream::Ok);
}
MsgPackStream stream(packed);
float f;
stream >> f;
QVERIFY(f == -0.0f);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> f;
QVERIFY(f == 0.0f);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> f;
QVERIFY(f == -1.0f);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> f;
QVERIFY(f == 1.0f);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> f;
QVERIFY(f == -32767.0f);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> f;
QVERIFY(f == 32767.0f);
QVERIFY(stream.status() == MsgPackStream::Ok);
}
void StreamTest::test_double()
{
QByteArray packed;
{
MsgPackStream stream(&packed, QIODevice::WriteOnly);
stream << -0.0 << 0.0 << -1.0 << 1.0 << -32767.0 << 32767.0;
QVERIFY(packed.size() == 6 * 9);
QVERIFY(stream.status() == MsgPackStream::Ok);
}
MsgPackStream stream(packed);
double d;
stream >> d;
QVERIFY(d == -0.0);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> d;
QVERIFY(d == 0.0);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> d;
QVERIFY(d == -1.0);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> d;
QVERIFY(d == 1.0);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> d;
QVERIFY(d == -32767.0);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> d;
QVERIFY(d == 32767.0);
QVERIFY(stream.status() == MsgPackStream::Ok);
}
void StreamTest::test_bin()
{
QByteArray ba1("msgpack"), ba2(256, 'r'), ba3(65536, 'x');
QByteArray packed;
{
MsgPackStream stream(&packed, QIODevice::WriteOnly);
stream << ba1 << ba2 << ba3;
}
QVERIFY(packed.size() == 7+2 + 256+3 + 65536+5);
MsgPackStream stream(packed);
QByteArray ba;
stream >> ba;
QVERIFY(ba == ba1);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> ba;
QVERIFY(ba == ba2);
QVERIFY(stream.status() == MsgPackStream::Ok);
stream >> ba;
QVERIFY(ba == ba3);
QVERIFY(stream.status() == MsgPackStream::Ok);
}
QTEST_APPLESS_MAIN(StreamTest) QTEST_APPLESS_MAIN(StreamTest)
#include "stream_test.moc" #include "stream_test.moc"