From 3b0d6e3c3180ec24c8f01b2369ea02a0155ce1c8 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 22 Apr 2015 23:47:31 +0300 Subject: [PATCH] Work on QTime, QDate, QDateTime, QSize, QPoint, QRect unpack_upto_ added for user packer / unpacker functions --- src/CMakeLists.txt | 4 +- src/msgpack-qt.pro | 6 +- src/msgpack.cpp | 137 ----------------------- src/msgpack_ext.cpp | 146 +++++++++++++++++++++++++ src/msgpack_ext.h | 20 ++++ src/private/qt_types_p.cpp | 192 ++++++++++++++++++++++++++------- src/private/qt_types_p.h | 29 ++++- tests/CMakeLists.txt | 2 +- tests/ext/CMakeLists.txt | 24 +++++ tests/ext/ext_test.cpp | 149 +++++++++++++++++++++++++ tests/qttypes/CMakeLists.txt | 24 +++++ tests/qttypes/qttypes_test.cpp | 124 +++++++++++++++++++++ 12 files changed, 674 insertions(+), 183 deletions(-) create mode 100644 src/msgpack_ext.cpp create mode 100644 src/msgpack_ext.h create mode 100644 tests/ext/CMakeLists.txt create mode 100644 tests/ext/ext_test.cpp create mode 100644 tests/qttypes/CMakeLists.txt create mode 100644 tests/qttypes/qttypes_test.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ac4d56..59c05cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ -set(qmsgpack_srcs msgpack.cpp msgpack_common.cpp private/pack_p.cpp private/unpack_p.cpp private/qt_types_p.cpp) -set(qmsgpack_headers msgpack.h msgpack_common.h msgpack_export.h) +set(qmsgpack_srcs msgpack.cpp msgpack_common.cpp msgpack_ext.cpp private/pack_p.cpp private/unpack_p.cpp private/qt_types_p.cpp) +set(qmsgpack_headers msgpack.h msgpack_common.h msgpack_ext.h msgpack_export.h) add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers}) diff --git a/src/msgpack-qt.pro b/src/msgpack-qt.pro index 97ddb4b..544eecc 100644 --- a/src/msgpack-qt.pro +++ b/src/msgpack-qt.pro @@ -27,7 +27,8 @@ SOURCES += msgpack.cpp \ msgpack_common.cpp \ private/pack_p.cpp \ private/unpack_p.cpp \ - private/qt_types_p.cpp + private/qt_types_p.cpp \ + msgpack_ext.cpp HEADERS += \ msgpack.h \ @@ -36,4 +37,5 @@ HEADERS += \ private/sysdep.h \ msgpack_common.h \ msgpack_export.h \ - private/qt_types_p.h + private/qt_types_p.h \ + msgpack_ext.h diff --git a/src/msgpack.cpp b/src/msgpack.cpp index fed3bba..fdd413d 100644 --- a/src/msgpack.cpp +++ b/src/msgpack.cpp @@ -46,140 +46,3 @@ void MsgPack::setCompatibilityModeEnabled(bool enabled) { MsgPackPrivate::compatibilityMode = enabled; } - -quint8 * MsgPack::ExtHelpers::unpack_upto_quint8(quint8 *to, quint8 *p, bool *success) -{ - if (*p <= MsgPack::FirstByte::POSITIVE_FIXINT) { - *to = *(p++); - } else if (*p == MsgPack::FirstByte::UINT8) { - *to = *(++p); - } else { - *success = false; - return p; - } - *success = true; - return p; -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_quint16(quint16 *to, quint8 *p, bool *success) -{ - if (*p == MsgPack::FirstByte::UINT16) { - *to = _msgpack_load16(quint16, p); - *success = true; - return p + 2; - } else { - quint8 u8; - p = unpack_upto_quint8(&u8, p, success); - *to = u8; - return p; - } -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_quint32(quint32 *to, quint8 *p, bool *success) -{ - if (*p == MsgPack::FirstByte::UINT32) { - *to = _msgpack_load32(quint32, p); - *success = true; - return p + 4; - } else { - quint16 u16; - p = unpack_upto_quint16(&u16, p, success); - *to = u16; - return p; - } -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_quint64(quint64 *to, quint8 *p, bool *success) -{ - if (*p == MsgPack::FirstByte::UINT64) { - *to = _msgpack_load64(quint64, p); - *success = true; - return p + 8; - } else { - quint32 u32; - p = unpack_upto_quint32(&u32, p, success); - *to = u32; - return p; - } -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_qint8(qint8 *to, quint8 *p, bool *success) -{ - if (*p >= MsgPack::FirstByte::NEGATIVE_FIXINT) { - *to = *p; - *success = true; - return p + 1; - } else if (*p == MsgPack::FirstByte::INT8) { - *to = (qint8) *(++p); - *success = true; - return p + 1; - } else { - quint8 u8; - p = unpack_upto_quint8(&u8, p, success); - *to = u8; - return p; - } -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_qint16(qint16 *to, quint8 *p, bool *success) -{ - if (*p == MsgPack::FirstByte::INT16) { - *to = _msgpack_load16(qint16, p); - *success = true; - return p + 2; - } else { - qint8 i8; - p = unpack_upto_qint8(&i8, p, success); - *to = i8; - if (*success) { - return p; - } else { - quint16 u16; - p = unpack_upto_quint16(&u16, p, success); - *to = u16; - return p; - } - } -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_qint32(qint32 *to, quint8 *p, bool *success) -{ - if(*p == MsgPack::FirstByte::INT32) { - *to = _msgpack_load32(qint32, p); - *success = true; - return p + 4; - } else { - qint16 i16; - p = unpack_upto_qint16(&i16, p, success); - *to = i16; - if (*success) { - return p; - } else { - quint32 u32; - p = unpack_upto_quint32(&u32, p, success); - *to = u32; - return p; - } - } -} - -quint8 *MsgPack::ExtHelpers::unpack_upto_qint64(qint64 *to, quint8 *p, bool *success) -{ - if(*p == MsgPack::FirstByte::INT64) { - *to = _msgpack_load64(qint64, p); - *success = true; - return p + 8; - } else { - qint32 i32; - p = unpack_upto_qint32(&i32, p, success); - *to = i32; - if (*success) { - return p; - } else { - quint64 u64; - p = unpack_upto_quint64(&u64, p, success); - *to = u64; - return p; - } - } -} diff --git a/src/msgpack_ext.cpp b/src/msgpack_ext.cpp new file mode 100644 index 0000000..5a4f094 --- /dev/null +++ b/src/msgpack_ext.cpp @@ -0,0 +1,146 @@ +#include "msgpack_ext.h" +#include "msgpack_common.h" +#include "private/sysdep.h" + +quint8 * MsgPack::Ext::unpack_upto_quint8(quint8 *to, quint8 *p, bool *success) +{ + if (*p <= MsgPack::FirstByte::POSITIVE_FIXINT) { + *to = *(p++); + } else if (*p == MsgPack::FirstByte::UINT8) { + *to = *(++p); + } else { + *success = false; + return p; + } + *success = true; + return p; +} + +quint8 *MsgPack::Ext::unpack_upto_quint16(quint16 *to, quint8 *p, bool *success) +{ + if (*p == MsgPack::FirstByte::UINT16) { + p++; + *to = _msgpack_load16(quint16, p); + *success = true; + return p + 2; + } else { + quint8 u8; + p = unpack_upto_quint8(&u8, p, success); + *to = u8; + return p; + } +} + +quint8 *MsgPack::Ext::unpack_upto_quint32(quint32 *to, quint8 *p, bool *success) +{ + if (*p == MsgPack::FirstByte::UINT32) { + p++; + *to = _msgpack_load32(quint32, p); + *success = true; + return p + 4; + } else { + quint16 u16; + p = unpack_upto_quint16(&u16, p, success); + *to = u16; + return p; + } +} + +quint8 *MsgPack::Ext::unpack_upto_quint64(quint64 *to, quint8 *p, bool *success) +{ + if (*p == MsgPack::FirstByte::UINT64) { + p++; + *to = _msgpack_load64(quint64, p); + *success = true; + return p + 8; + } else { + quint32 u32; + p = unpack_upto_quint32(&u32, p, success); + *to = u32; + return p; + } +} + +quint8 *MsgPack::Ext::unpack_upto_qint8(qint8 *to, quint8 *p, bool *success) +{ + if (*p >= MsgPack::FirstByte::NEGATIVE_FIXINT) { + *to = *p; + *success = true; + return p + 1; + } else if (*p == MsgPack::FirstByte::INT8) { + *to = (qint8) *(++p); + *success = true; + return p + 1; + } else { + quint8 u8; + p = unpack_upto_quint8(&u8, p, success); + *to = u8; + return p; + } +} + +quint8 *MsgPack::Ext::unpack_upto_qint16(qint16 *to, quint8 *p, bool *success) +{ + if (*p == MsgPack::FirstByte::INT16) { + p++; + *to = _msgpack_load16(qint16, p); + *success = true; + return p + 2; + } else { + qint8 i8; + p = unpack_upto_qint8(&i8, p, success); + *to = i8; + if (*success) { + return p; + } else { + quint16 u16; + p = unpack_upto_quint16(&u16, p, success); + *to = u16; + return p; + } + } +} + +quint8 *MsgPack::Ext::unpack_upto_qint32(qint32 *to, quint8 *p, bool *success) +{ + if(*p == MsgPack::FirstByte::INT32) { + p++; + *to = _msgpack_load32(qint32, p); + *success = true; + return p + 4; + } else { + qint16 i16; + p = unpack_upto_qint16(&i16, p, success); + *to = i16; + if (*success) { + return p; + } else { + quint32 u32; + p = unpack_upto_quint32(&u32, p, success); + *to = u32; + return p; + } + } +} + +quint8 *MsgPack::Ext::unpack_upto_qint64(qint64 *to, quint8 *p, bool *success) +{ + if(*p == MsgPack::FirstByte::INT64) { + p++; + *to = _msgpack_load64(qint64, p); + *success = true; + return p + 8; + } else { + qint32 i32; + p = unpack_upto_qint32(&i32, p, success); + *to = i32; + if (*success) { + return p; + } else { + quint64 u64; + p = unpack_upto_quint64(&u64, p, success); + *to = u64; + return p; + } + } +} diff --git a/src/msgpack_ext.h b/src/msgpack_ext.h new file mode 100644 index 0000000..c36c789 --- /dev/null +++ b/src/msgpack_ext.h @@ -0,0 +1,20 @@ +#ifndef MSGPACK_EXT_H +#define MSGPACK_EXT_H +#include + +namespace MsgPack +{ + namespace Ext { + quint8 * unpack_upto_quint8(quint8 *to, quint8 *from, bool *success); + quint8 * unpack_upto_quint16(quint16 *to, quint8 *from, bool *success); + quint8 * unpack_upto_quint32(quint32 *to, quint8 *from, bool *success); + quint8 * unpack_upto_quint64(quint64 *to, quint8 *from, bool *success); + quint8 * unpack_upto_qint8(qint8 *to, quint8 *from, bool *success); + quint8 * unpack_upto_qint16(qint16 *to, quint8 *from, bool *success); + quint8 * unpack_upto_qint32(qint32 *to, quint8 *from, bool *success); + quint8 * unpack_upto_qint64(qint64 *to, quint8 *from, bool *success); + quint8 * unpack_float(float *to, quint8 *from, bool *success); + quint8 * unpack_double(double *to, quint8 *from, bool *success); + } // ExtHelpers +} // MsgPack +#endif // MSGPACK_EXT_H diff --git a/src/private/qt_types_p.cpp b/src/private/qt_types_p.cpp index 6c550b4..8491ab1 100644 --- a/src/private/qt_types_p.cpp +++ b/src/private/qt_types_p.cpp @@ -2,6 +2,7 @@ #include "pack_p.h" #include "unpack_p.h" #include "sysdep.h" +#include "../msgpack_ext.h" #include @@ -11,7 +12,7 @@ #define NO_QTGUI_WARNING "Library built without QtGui, hence some types are not available" #include -#include +#include bool MsgPackPrivate::register_qtype(QMetaType::Type q_type, quint8 msgpack_type) { @@ -20,7 +21,7 @@ bool MsgPackPrivate::register_qtype(QMetaType::Type q_type, quint8 msgpack_type) MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qcolor); MsgPackPrivate::register_unpacker(msgpack_type, unpack_qcolor); #else - qWarning() << NO_QTGUI_WARNING; + qWarning() << NO_QTGUI_WARNING; return false; #endif //QT_GUI_LIB } else if (q_type == QMetaType::QTime) { @@ -32,6 +33,15 @@ bool MsgPackPrivate::register_qtype(QMetaType::Type q_type, quint8 msgpack_type) } else if (q_type == QMetaType::QDateTime) { MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qdatetime); MsgPackPrivate::register_unpacker(msgpack_type, unpack_qdatetime); + } else if (q_type == QMetaType::QPoint) { + MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qpoint); + MsgPackPrivate::register_unpacker(msgpack_type, unpack_qpoint); + } else if (q_type == QMetaType::QSize) { + MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qsize); + MsgPackPrivate::register_unpacker(msgpack_type, unpack_qsize); + } else if (q_type == QMetaType::QRect) { + MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qrect); + MsgPackPrivate::register_unpacker(msgpack_type, unpack_qrect); } return true; } @@ -42,44 +52,65 @@ quint32 MsgPackPrivate::pack_qcolor(const QVariant &variant, QByteArray &data, b if (write) { QColor color = variant.value(); data.resize(4); - data[0] = color.red(); - data[1] = color.green(); - data[2] = color.blue(); - data[3] = color.alpha(); + quint8 *p = (quint8 *)data.data(); + p[0] = color.red(); + p[1] = color.green(); + p[2] = color.blue(); + p[3] = color.alpha(); } return 4; // 4 bytes: r,g,b,a } QVariant MsgPackPrivate::unpack_qcolor(const QByteArray &data) { - return QColor((quint8)data[0], (quint8)data[1], - (quint8)data[2], (quint8)data[3]); + quint8 *p = (quint8 *)data.data(); + return QColor(p[0], p[1], p[2], p[3]); } -#endif //MsgPackPrivate +#endif // QT_GUI_LIB // Date and Time void MsgPackPrivate::pack_qtime_raw(const QTime &time, quint8 *p) { - quint32 t = time.msecsSinceStartOfDay(); - _msgpack_store32(p, t); + quint8 hm, ms; + hm = (quint8)time.hour() << 4; + hm |= (quint8)time.minute() >> 2; + ms = ((quint8)time.minute() << 6) & 0xc0; // 11000000 + ms |= (quint8)time.second(); + p[0] = hm; p[1] = ms; + + if (time.msec() != 0) { + p[2] = (quint8)( (quint16)time.msec() >> 8 ); + p[3] = (quint8)time.msec(); + } } -QTime MsgPackPrivate::unpack_qtime_raw(quint8 *p) +QTime MsgPackPrivate::unpack_qtime_raw(quint8 *p, bool with_ms) { - quint32 t = _msgpack_load32(quint32, p); - return QTime::fromMSecsSinceStartOfDay(t); + quint8 h, m, s; + quint16 ms = 0; + h = p[0] >> 4; + m = (p[0] << 2) | (p[1] >> 6); + m &= 0x3f; // 00111111 + s = p[1] & 0x3f; + if (with_ms) + ms = (p[2] << 8) | p[3]; + return QTime(h, m, s, ms); } quint32 MsgPackPrivate::pack_qtime(const QVariant &variant, QByteArray &data, bool write) { - if (write) - pack_qtime_raw(variant.toTime(), (quint8 *)data.data()); - return 4; // 24h*60m*60s*1000ms = max 27 bits + QTime time = variant.toTime(); + quint8 size = time.msec() == 0 ? 2 : 4; + if (write) { + data.resize(size); + pack_qtime_raw(time, (quint8 *)data.data()); + } + return size; } QVariant MsgPackPrivate::unpack_qtime(const QByteArray &data) { - return unpack_qtime_raw((quint8 *)data.data()); + return unpack_qtime_raw((quint8 *)data.data(), data.size() == 4); } void MsgPackPrivate::pack_qdate_raw(const QDate &date, quint8 *p) @@ -87,9 +118,10 @@ void MsgPackPrivate::pack_qdate_raw(const QDate &date, quint8 *p) quint16 year = date.year(); quint8 month = date.month(); quint8 day = date.day(); - quint16 dy = year | (day & 0x80); + if (day > 15) + year |= 0x8000; quint8 md = (month << 4) | (day & 0xf); - _msgpack_store16(p, dy); + _msgpack_store16(p, year); p[2] = md; } @@ -105,9 +137,11 @@ QDate MsgPackPrivate::unpack_qdate_raw(quint8 *p) quint32 MsgPackPrivate::pack_qdate(const QVariant &variant, QByteArray &data, bool write) { - if (write) + if (write) { + data.resize(3); pack_qdate_raw(variant.toDate(), (quint8 *)data.data()); - return 3; // d(5th bit)xyyyyyyyyyyyyyy, mmmmdddd + } + return 3; } QVariant MsgPackPrivate::unpack_qdate(const QByteArray &data) @@ -117,44 +151,126 @@ QVariant MsgPackPrivate::unpack_qdate(const QByteArray &data) quint32 MsgPackPrivate::pack_qdatetime(const QVariant &variant, QByteArray &data, bool write) { + QDateTime dt = variant.toDateTime(); + quint8 time_size = dt.time().msec() == 0 ? 2 : 4; if (write) { + data.resize(3 + time_size); quint8 *p = (quint8 *)data.data(); - QDateTime dt = variant.toDateTime(); pack_qdate_raw(dt.date(), p); - pack_qtime_raw(dt.time(), p + 3); + p += 3; + pack_qtime_raw(dt.time(), p); } - return 7; // 3 for date, 4 for time + return 3 + time_size; // 3 for date, 4 for time } QVariant MsgPackPrivate::unpack_qdatetime(const QByteArray &data) { quint8 *p = (quint8 *)data.data(); QDate d = unpack_qdate_raw(p); - QTime t = unpack_qtime_raw(p + 3); + QTime t = unpack_qtime_raw(p + 3, data.size() == 7); return QDateTime(d, t); } // Points and Vectors +quint8 MsgPackPrivate::pack_two_integers(qint32 a, qint32 b, quint8 *to, bool write) +{ + quint8 *p = 0; + p = MsgPackPrivate::pack_int(a, p, false); + p = MsgPackPrivate::pack_int(b, p, false); + quint8 size = p - (quint8 *)0; + if (write) { + to = MsgPackPrivate::pack_int(a, to, true); + MsgPackPrivate::pack_int(b, to, true); + } + return size; +} + quint32 MsgPackPrivate::pack_qpoint(const QVariant &variant, QByteArray &data, bool write) { QPoint pt = variant.toPoint(); - quint8 *p = 0; + quint8 size = pack_two_integers(pt.x(), pt.y(), 0, false); if (write) { - p = (quint8 *)data.data(); - p = MsgPackPrivate::pack_int(pt.x(), p, false); - p = MsgPackPrivate::pack_int(pt.y(), p, false); - return data.size(); // ok since it already resized - } else { - p = MsgPackPrivate::pack_int(pt.x(), p, false); - p = MsgPackPrivate::pack_int(pt.y(), p, false); - return p - (quint8 *)0; + data.resize(size); + pack_two_integers(pt.x(), pt.y(), (quint8 *)data.data(), true); } + return size; } QVariant MsgPackPrivate::unpack_qpoint(const QByteArray &data) { quint8 *p = (quint8 *)data.data(); - QVariant v; - p = (MsgPackPrivate::unpackers[*p - 0xc0])(v, p); - + qint32 x; + bool ok; + p = MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + QPoint pt; + pt.setX(x); + MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + pt.setY(x); + return pt; } + +quint32 MsgPackPrivate::pack_qsize(const QVariant &variant, QByteArray &data, bool write) +{ + QSize sz = variant.toSize(); + quint8 size = pack_two_integers(sz.width(), sz.height(), 0, false); + if (write) { + data.resize(size); + pack_two_integers(sz.width(), sz.height(), (quint8 *)data.data(), true); + } + return size; +} + +QVariant MsgPackPrivate::unpack_qsize(const QByteArray &data) +{ + quint8 *p = (quint8 *)data.data(); + qint32 x; + bool ok; + p = MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + QSize sz; + sz.setWidth(x); + MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + sz.setHeight(x); + return sz; +} + +quint32 MsgPackPrivate::pack_qrect(const QVariant &variant, QByteArray &data, bool write) +{ + QRect rect = variant.toRect(); + QPoint pt1 = rect.topLeft(); + QPoint pt2 = rect.bottomRight(); + quint8 size = pack_two_integers(pt1.x(), pt1.y(), 0, false); + size += pack_two_integers(pt2.x(), pt2.y(), 0, false); + if (write) { + data.resize(size); + quint8 *p = (quint8 *)data.data(); + p += pack_two_integers(pt1.x(), pt1.y(), p, true); + pack_two_integers(pt2.x(), pt2.y(), p, true); + } + return size; +} + +QVariant MsgPackPrivate::unpack_qrect(const QByteArray &data) +{ + quint8 *p = (quint8 *)data.data(); + qint32 x; + bool ok; + + p = MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + QPoint pt; + pt.setX(x); + p = MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + pt.setY(x); + + QRect rect; + rect.setTopLeft(pt); + + p = MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + pt.setX(x); + p = MsgPack::Ext::unpack_upto_qint32(&x, p, &ok); + pt.setY(x); + + rect.setBottomRight(pt); + + return rect; +} + diff --git a/src/private/qt_types_p.h b/src/private/qt_types_p.h index 725a3b6..9c90c3e 100644 --- a/src/private/qt_types_p.h +++ b/src/private/qt_types_p.h @@ -14,12 +14,31 @@ QVariant unpack_qcolor(const QByteArray &data); #endif //QT_GUI_LIB // Date and Time -void pack_qtime_raw(const QTime &time, quint8 *p); -QTime unpack_qtime_raw(quint8 *p); +/** + * @brief pack_qtime_raw internal: packs QTime to 4 or 2 bytes (with or without ms) + * @param time QTime to pack + * @param p pointer to preallocated array + * format: (bits) hhhhmmmm mmssssss [------ms msmsmsms] + */ +void pack_qtime_raw(const QTime &time, quint8 *p); // return 2 - without ms, 4 with ms +/** + * @brief unpack_qtime_raw internal: unpack 2 or 4 bytes to QTime + * @param p data to unpack + * @param with_ms true if array is 4 bytes (i.e. unpack with ms) + * @return QTime + */ +QTime unpack_qtime_raw(quint8 *p, bool with_ms); quint32 pack_qtime(const QVariant &variant, QByteArray &data, bool write); QVariant unpack_qtime(const QByteArray &data); +/** + * @brief pack_qdate_raw internal: pack QDate to 3 bytes + * @param date QDate to pack + * @param p pointer to preallocated array + * format: (bits) d(5th bit)xyyyyyyyyyyyyyy, mmmmdddd + */ void pack_qdate_raw(const QDate &date, quint8 *p); +/// @brief internal: unpack bytes to QDate QDate unpack_qdate_raw(quint8 *p); quint32 pack_qdate(const QVariant &variant, QByteArray &data, bool write); QVariant unpack_qdate(const QByteArray &data); @@ -28,9 +47,13 @@ quint32 pack_qdatetime(const QVariant &variant, QByteArray &data, bool write); QVariant unpack_qdatetime(const QByteArray &data); // Points and Vectors +quint8 pack_two_integers(qint32 a, qint32 b, quint8 *to, bool write); quint32 pack_qpoint(const QVariant &variant, QByteArray &data, bool write); QVariant unpack_qpoint(const QByteArray &data); - +quint32 pack_qsize(const QVariant &variant, QByteArray &data, bool write); +QVariant unpack_qsize(const QByteArray &data); +quint32 pack_qrect(const QVariant &variant, QByteArray &data, bool write); +QVariant unpack_qrect(const QByteArray &data); } // MsgPackPrivate diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 18f82e5..856446b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,7 +8,7 @@ if (Qt5Core_FOUND) set(TEST_LIBRARIES ${Qt5Test_LIBRARIES}) endif () -set(TEST_SUBDIRS pack unpack mixed) +set(TEST_SUBDIRS pack unpack mixed qttypes ext) foreach(subdir ${TEST_SUBDIRS}) add_subdirectory(${subdir}) diff --git a/tests/ext/CMakeLists.txt b/tests/ext/CMakeLists.txt new file mode 100644 index 0000000..e5ca9c1 --- /dev/null +++ b/tests/ext/CMakeLists.txt @@ -0,0 +1,24 @@ +set(QT_USE_QTTEST TRUE) + +if (NOT Qt5Core_FOUND) + include( ${QT_USE_FILE} ) +endif() + +include(AddFileDependencies) + +include_directories(../../src ${CMAKE_CURRENT_BINARY_DIR}) + +set(UNIT_TESTS ext_test) + +foreach(test ${UNIT_TESTS}) + message(status "Building ${test}") + add_executable(${test} ${test}.cpp) + + target_link_libraries(${test} + ${QT_LIBRARIES} + ${TEST_LIBRARIES} + qmsgpack + ) + + add_test(${test} ${test}) +endforeach() \ No newline at end of file diff --git a/tests/ext/ext_test.cpp b/tests/ext/ext_test.cpp new file mode 100644 index 0000000..6455f49 --- /dev/null +++ b/tests/ext/ext_test.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include + +class ExtText : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void test_upto_quint(); + void test_upto_qint(); + void test_upto_qint_to_quint(); + void test_fail(); +}; + +void ExtText::test_upto_quint() +{ + QByteArray packed; + bool success; + quint8 u8; + quint16 u16; + quint32 u32; + quint64 u64; + + packed = MsgPack::pack(0); + MsgPack::Ext::unpack_upto_quint8(&u8, (quint8 *)packed.data(), &success); + QVERIFY(u8 == 0); + QVERIFY(success); + MsgPack::Ext::unpack_upto_quint16(&u16, (quint8 *)packed.data(), &success); + QVERIFY(u16 == 0); + QVERIFY(success); + MsgPack::Ext::unpack_upto_quint32(&u32, (quint8 *)packed.data(), &success); + QVERIFY(u32 == 0); + QVERIFY(success); + MsgPack::Ext::unpack_upto_quint64(&u64, (quint8 *)packed.data(), &success); + QVERIFY(u64 == 0); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_quint8(&u8, (quint8 *)packed.data(), &success); + QVERIFY(u8 == std::numeric_limits::max()); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_quint16(&u16, (quint8 *)packed.data(), &success); + QVERIFY(u16 == std::numeric_limits::max()); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_quint32(&u32, (quint8 *)packed.data(), &success); + QVERIFY(u32 == std::numeric_limits::max()); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_quint64(&u64, (quint8 *)packed.data(), &success); + QVERIFY(u64 == std::numeric_limits::max()); + QVERIFY(success); +} + +void ExtText::test_upto_qint() +{ + QByteArray packed; + bool success; + qint8 i8; + qint16 i16; + qint32 i32; + qint64 i64; + + packed = MsgPack::pack(-32); + MsgPack::Ext::unpack_upto_qint8(&i8, (quint8 *)packed.data(), &success); + QVERIFY(i8 == -32); + QVERIFY(success); + MsgPack::Ext::unpack_upto_qint16(&i16, (quint8 *)packed.data(), &success); + QVERIFY(i16 == -32); + QVERIFY(success); + MsgPack::Ext::unpack_upto_qint32(&i32, (quint8 *)packed.data(), &success); + QVERIFY(i32 == -32); + QVERIFY(success); + MsgPack::Ext::unpack_upto_qint64(&i64, (quint8 *)packed.data(), &success); + QVERIFY(i64 == -32); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::min() - 1); + MsgPack::Ext::unpack_upto_qint8(&i8, (quint8 *)packed.data(), &success); + QVERIFY(i8 == std::numeric_limits::min() - 1); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::min() - 1); + MsgPack::Ext::unpack_upto_qint16(&i16, (quint8 *)packed.data(), &success); + QVERIFY(i16 == std::numeric_limits::min() - 1); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::min() - 1); + MsgPack::Ext::unpack_upto_qint32(&i32, (quint8 *)packed.data(), &success); + QVERIFY(i32 == std::numeric_limits::min() - 1); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::min() - 1); + MsgPack::Ext::unpack_upto_qint64(&i64, (quint8 *)packed.data(), &success); + QVERIFY(i64 == std::numeric_limits::min() - 1); + QVERIFY(success); +} + +void ExtText::test_upto_qint_to_quint() +{ + QByteArray packed; + bool success; + qint8 i8; + qint16 i16; + qint32 i32; + qint64 i64; + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_qint8(&i8, (quint8 *)packed.data(), &success); + QVERIFY(i8 == std::numeric_limits::max()); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_qint16(&i16, (quint8 *)packed.data(), &success); + QVERIFY(i16 == std::numeric_limits::max()); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_qint32(&i32, (quint8 *)packed.data(), &success); + QVERIFY(i32 == std::numeric_limits::max()); + QVERIFY(success); + + packed = MsgPack::pack(std::numeric_limits::max()); + MsgPack::Ext::unpack_upto_qint64(&i64, (quint8 *)packed.data(), &success); + QVERIFY(i64 == std::numeric_limits::max()); + QVERIFY(success); +} + +void ExtText::test_fail() +{ + quint8 p[] = {0xd9}; + quint8 u8; + bool ok; + quint8 *p2 = MsgPack::Ext::unpack_upto_quint8(&u8, p, &ok); + QVERIFY(!ok); + QVERIFY(p2 - p == 0); +} + +QTEST_APPLESS_MAIN(ExtText) + +#include "ext_test.moc" diff --git a/tests/qttypes/CMakeLists.txt b/tests/qttypes/CMakeLists.txt new file mode 100644 index 0000000..9f37e5b --- /dev/null +++ b/tests/qttypes/CMakeLists.txt @@ -0,0 +1,24 @@ +set(QT_USE_QTTEST TRUE) + +if (NOT Qt5Core_FOUND) + include( ${QT_USE_FILE} ) +endif() + +include(AddFileDependencies) + +include_directories(../../src ${CMAKE_CURRENT_BINARY_DIR}) + +set(UNIT_TESTS qttypes_test) + +foreach(test ${UNIT_TESTS}) + message(status "Building ${test}") + add_executable(${test} ${test}.cpp) + + target_link_libraries(${test} + ${QT_LIBRARIES} + ${TEST_LIBRARIES} + qmsgpack + ) + + add_test(${test} ${test}) +endforeach() \ No newline at end of file diff --git a/tests/qttypes/qttypes_test.cpp b/tests/qttypes/qttypes_test.cpp new file mode 100644 index 0000000..ebcaa28 --- /dev/null +++ b/tests/qttypes/qttypes_test.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include + +class QtTypesTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void test_qtime(); + void test_qdate(); + void test_qpoint(); + void test_qsize(); + void test_qrect(); +}; + +void QtTypesTest::test_qtime() +{ + MsgPack::registerType(QMetaType::QTime, 0x77); + QTime t(0, 0, 0, 0); + QByteArray packed = MsgPack::pack(t); + QTime t2 = MsgPack::unpack(packed).toTime(); + QVERIFY(t == t2); + QVERIFY(packed.size() == 4); + + t = QTime(12, 01, 01, 0); + packed = MsgPack::pack(t); + t2 = MsgPack::unpack(packed).toTime(); + QVERIFY(t == t2); + QVERIFY(packed.size() == 4); + + t = QTime(12, 59, 59, 0); + packed = MsgPack::pack(t); + t2 = MsgPack::unpack(packed).toTime(); + QVERIFY(t == t2); + QVERIFY(packed.size() == 4); + + t = QTime(12, 34, 56, 999); + packed = MsgPack::pack(t); + t2 = MsgPack::unpack(packed).toTime(); + QVERIFY(t == t2); + QVERIFY(packed.size() == 6); +} + +void QtTypesTest::test_qdate() +{ + MsgPack::registerType(QMetaType::QDate, 0x78); + QDate d; + QByteArray packed = MsgPack::pack(d); + QDate d2 = MsgPack::unpack(packed).toDate(); + QVERIFY(d == d2); + QVERIFY(packed.size() == 6); + + d = QDate(1234, 12, 1); + packed = MsgPack::pack(d); + d2 = MsgPack::unpack(packed).toDate(); + QVERIFY(d == d2); + + d = QDate(9999, 1, 31); + packed = MsgPack::pack(d); + d2 = MsgPack::unpack(packed).toDate(); + QVERIFY(d == d2); +} + +void QtTypesTest::test_qpoint() +{ + MsgPack::registerType(QMetaType::QPoint, 0x79); + QPoint pt(1, 2); + QByteArray packed = MsgPack::pack(pt); + QVERIFY(packed.size() == 4); + QPoint pt2 = MsgPack::unpack(packed).toPoint(); + QVERIFY(pt == pt2); + + pt = QPoint(1234, 5678); + packed = MsgPack::pack(pt); + QVERIFY(packed.size() == 9); + pt2 = MsgPack::unpack(packed).toPoint(); + QVERIFY(pt == pt2); + + pt = QPoint(std::numeric_limits::max(), std::numeric_limits::max()); + packed = MsgPack::pack(pt); + QVERIFY(packed.size() == 13); + pt2 = MsgPack::unpack(packed).toPoint(); + QVERIFY(pt == pt2); +} + +void QtTypesTest::test_qsize() +{ + MsgPack::registerType(QMetaType::QSize, 80); + QSize sz(1, 2); + QByteArray packed = MsgPack::pack(sz); + QVERIFY(packed.size() == 4); + QSize sz2 = MsgPack::unpack(packed).toSize(); + QVERIFY(sz == sz2); + + sz = QSize(1234, 5678); + packed = MsgPack::pack(sz); + QVERIFY(packed.size() == 9); + sz2 = MsgPack::unpack(packed).toSize(); + QVERIFY(sz == sz2); +} + +void QtTypesTest::test_qrect() +{ + MsgPack::registerType(QMetaType::QRect, 81); + QRect r(1, 2, 3, 4); + QByteArray packed = MsgPack::pack(r); + QVERIFY(packed.size() == 6); + QRect r2 = MsgPack::unpack(packed).toRect(); + QVERIFY(r == r2); + + qint32 max = std::numeric_limits::max(); + r = QRect(0, 0, max, max); + packed = MsgPack::pack(r); + QVERIFY(packed.size() == 15); + r2 = MsgPack::unpack(packed).toRect(); + QVERIFY(r == r2); +} + +QTEST_APPLESS_MAIN(QtTypesTest) + +#include "qttypes_test.moc"