Work on QTime, QDate, QDateTime, QSize, QPoint, QRect

unpack_upto_<integer> added for user packer / unpacker functions
This commit is contained in:
Roman
2015-04-22 23:47:31 +03:00
parent 6d04bc66c6
commit 3b0d6e3c31
12 changed files with 674 additions and 183 deletions

View File

@ -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_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_export.h) set(qmsgpack_headers msgpack.h msgpack_common.h msgpack_ext.h msgpack_export.h)
add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers}) add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers})

View File

@ -27,7 +27,8 @@ SOURCES += msgpack.cpp \
msgpack_common.cpp \ msgpack_common.cpp \
private/pack_p.cpp \ private/pack_p.cpp \
private/unpack_p.cpp \ private/unpack_p.cpp \
private/qt_types_p.cpp private/qt_types_p.cpp \
msgpack_ext.cpp
HEADERS += \ HEADERS += \
msgpack.h \ msgpack.h \
@ -36,4 +37,5 @@ HEADERS += \
private/sysdep.h \ private/sysdep.h \
msgpack_common.h \ msgpack_common.h \
msgpack_export.h \ msgpack_export.h \
private/qt_types_p.h private/qt_types_p.h \
msgpack_ext.h

View File

@ -46,140 +46,3 @@ void MsgPack::setCompatibilityModeEnabled(bool enabled)
{ {
MsgPackPrivate::compatibilityMode = 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;
}
}
}

146
src/msgpack_ext.cpp Normal file
View File

@ -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;
}
}
}

20
src/msgpack_ext.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef MSGPACK_EXT_H
#define MSGPACK_EXT_H
#include <QtGlobal>
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

View File

@ -2,6 +2,7 @@
#include "pack_p.h" #include "pack_p.h"
#include "unpack_p.h" #include "unpack_p.h"
#include "sysdep.h" #include "sysdep.h"
#include "../msgpack_ext.h"
#include <QDebug> #include <QDebug>
@ -11,7 +12,7 @@
#define NO_QTGUI_WARNING "Library built without QtGui, hence some types are not available" #define NO_QTGUI_WARNING "Library built without QtGui, hence some types are not available"
#include <QTime> #include <QTime>
#include <QPoint> #include <QRect>
bool MsgPackPrivate::register_qtype(QMetaType::Type q_type, quint8 msgpack_type) 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_packer(q_type, msgpack_type, pack_qcolor);
MsgPackPrivate::register_unpacker(msgpack_type, unpack_qcolor); MsgPackPrivate::register_unpacker(msgpack_type, unpack_qcolor);
#else #else
qWarning() << NO_QTGUI_WARNING; qWarning() << NO_QTGUI_WARNING;
return false; return false;
#endif //QT_GUI_LIB #endif //QT_GUI_LIB
} else if (q_type == QMetaType::QTime) { } 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) { } else if (q_type == QMetaType::QDateTime) {
MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qdatetime); MsgPackPrivate::register_packer(q_type, msgpack_type, pack_qdatetime);
MsgPackPrivate::register_unpacker(msgpack_type, unpack_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; return true;
} }
@ -42,44 +52,65 @@ quint32 MsgPackPrivate::pack_qcolor(const QVariant &variant, QByteArray &data, b
if (write) { if (write) {
QColor color = variant.value<QColor>(); QColor color = variant.value<QColor>();
data.resize(4); data.resize(4);
data[0] = color.red(); quint8 *p = (quint8 *)data.data();
data[1] = color.green(); p[0] = color.red();
data[2] = color.blue(); p[1] = color.green();
data[3] = color.alpha(); p[2] = color.blue();
p[3] = color.alpha();
} }
return 4; // 4 bytes: r,g,b,a return 4; // 4 bytes: r,g,b,a
} }
QVariant MsgPackPrivate::unpack_qcolor(const QByteArray &data) QVariant MsgPackPrivate::unpack_qcolor(const QByteArray &data)
{ {
return QColor((quint8)data[0], (quint8)data[1], quint8 *p = (quint8 *)data.data();
(quint8)data[2], (quint8)data[3]); return QColor(p[0], p[1], p[2], p[3]);
} }
#endif //MsgPackPrivate #endif // QT_GUI_LIB
// Date and Time // Date and Time
void MsgPackPrivate::pack_qtime_raw(const QTime &time, quint8 *p) void MsgPackPrivate::pack_qtime_raw(const QTime &time, quint8 *p)
{ {
quint32 t = time.msecsSinceStartOfDay(); quint8 hm, ms;
_msgpack_store32(p, t); 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); quint8 h, m, s;
return QTime::fromMSecsSinceStartOfDay(t); 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) quint32 MsgPackPrivate::pack_qtime(const QVariant &variant, QByteArray &data, bool write)
{ {
if (write) QTime time = variant.toTime();
pack_qtime_raw(variant.toTime(), (quint8 *)data.data()); quint8 size = time.msec() == 0 ? 2 : 4;
return 4; // 24h*60m*60s*1000ms = max 27 bits if (write) {
data.resize(size);
pack_qtime_raw(time, (quint8 *)data.data());
}
return size;
} }
QVariant MsgPackPrivate::unpack_qtime(const QByteArray &data) 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) 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(); quint16 year = date.year();
quint8 month = date.month(); quint8 month = date.month();
quint8 day = date.day(); quint8 day = date.day();
quint16 dy = year | (day & 0x80); if (day > 15)
year |= 0x8000;
quint8 md = (month << 4) | (day & 0xf); quint8 md = (month << 4) | (day & 0xf);
_msgpack_store16(p, dy); _msgpack_store16(p, year);
p[2] = md; 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) 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()); pack_qdate_raw(variant.toDate(), (quint8 *)data.data());
return 3; // d(5th bit)xyyyyyyyyyyyyyy, mmmmdddd }
return 3;
} }
QVariant MsgPackPrivate::unpack_qdate(const QByteArray &data) 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) 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) { if (write) {
data.resize(3 + time_size);
quint8 *p = (quint8 *)data.data(); quint8 *p = (quint8 *)data.data();
QDateTime dt = variant.toDateTime();
pack_qdate_raw(dt.date(), p); 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) QVariant MsgPackPrivate::unpack_qdatetime(const QByteArray &data)
{ {
quint8 *p = (quint8 *)data.data(); quint8 *p = (quint8 *)data.data();
QDate d = unpack_qdate_raw(p); 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); return QDateTime(d, t);
} }
// Points and Vectors // 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) quint32 MsgPackPrivate::pack_qpoint(const QVariant &variant, QByteArray &data, bool write)
{ {
QPoint pt = variant.toPoint(); QPoint pt = variant.toPoint();
quint8 *p = 0; quint8 size = pack_two_integers(pt.x(), pt.y(), 0, false);
if (write) { if (write) {
p = (quint8 *)data.data(); data.resize(size);
p = MsgPackPrivate::pack_int(pt.x(), p, false); pack_two_integers(pt.x(), pt.y(), (quint8 *)data.data(), true);
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;
} }
return size;
} }
QVariant MsgPackPrivate::unpack_qpoint(const QByteArray &data) QVariant MsgPackPrivate::unpack_qpoint(const QByteArray &data)
{ {
quint8 *p = (quint8 *)data.data(); quint8 *p = (quint8 *)data.data();
QVariant v; qint32 x;
p = (MsgPackPrivate::unpackers[*p - 0xc0])(v, p); 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;
}

View File

@ -14,12 +14,31 @@ QVariant unpack_qcolor(const QByteArray &data);
#endif //QT_GUI_LIB #endif //QT_GUI_LIB
// Date and Time // 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); quint32 pack_qtime(const QVariant &variant, QByteArray &data, bool write);
QVariant unpack_qtime(const QByteArray &data); 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); void pack_qdate_raw(const QDate &date, quint8 *p);
/// @brief internal: unpack bytes to QDate
QDate unpack_qdate_raw(quint8 *p); QDate unpack_qdate_raw(quint8 *p);
quint32 pack_qdate(const QVariant &variant, QByteArray &data, bool write); quint32 pack_qdate(const QVariant &variant, QByteArray &data, bool write);
QVariant unpack_qdate(const QByteArray &data); 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); QVariant unpack_qdatetime(const QByteArray &data);
// Points and Vectors // 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); quint32 pack_qpoint(const QVariant &variant, QByteArray &data, bool write);
QVariant unpack_qpoint(const QByteArray &data); 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 } // MsgPackPrivate

View File

@ -8,7 +8,7 @@ if (Qt5Core_FOUND)
set(TEST_LIBRARIES ${Qt5Test_LIBRARIES}) set(TEST_LIBRARIES ${Qt5Test_LIBRARIES})
endif () endif ()
set(TEST_SUBDIRS pack unpack mixed) set(TEST_SUBDIRS pack unpack mixed qttypes ext)
foreach(subdir ${TEST_SUBDIRS}) foreach(subdir ${TEST_SUBDIRS})
add_subdirectory(${subdir}) add_subdirectory(${subdir})

24
tests/ext/CMakeLists.txt Normal file
View File

@ -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()

149
tests/ext/ext_test.cpp Normal file
View File

@ -0,0 +1,149 @@
#include <QString>
#include <QtTest>
#include <QDebug>
#include <msgpack.h>
#include <limits>
#include <msgpack_ext.h>
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<quint8>::max());
MsgPack::Ext::unpack_upto_quint8(&u8, (quint8 *)packed.data(), &success);
QVERIFY(u8 == std::numeric_limits<quint8>::max());
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<quint16>::max());
MsgPack::Ext::unpack_upto_quint16(&u16, (quint8 *)packed.data(), &success);
QVERIFY(u16 == std::numeric_limits<quint16>::max());
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<quint32>::max());
MsgPack::Ext::unpack_upto_quint32(&u32, (quint8 *)packed.data(), &success);
QVERIFY(u32 == std::numeric_limits<quint32>::max());
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<quint64>::max());
MsgPack::Ext::unpack_upto_quint64(&u64, (quint8 *)packed.data(), &success);
QVERIFY(u64 == std::numeric_limits<quint64>::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<quint8>::min() - 1);
MsgPack::Ext::unpack_upto_qint8(&i8, (quint8 *)packed.data(), &success);
QVERIFY(i8 == std::numeric_limits<quint8>::min() - 1);
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<quint16>::min() - 1);
MsgPack::Ext::unpack_upto_qint16(&i16, (quint8 *)packed.data(), &success);
QVERIFY(i16 == std::numeric_limits<quint16>::min() - 1);
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<quint32>::min() - 1);
MsgPack::Ext::unpack_upto_qint32(&i32, (quint8 *)packed.data(), &success);
QVERIFY(i32 == std::numeric_limits<quint32>::min() - 1);
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<quint64>::min() - 1);
MsgPack::Ext::unpack_upto_qint64(&i64, (quint8 *)packed.data(), &success);
QVERIFY(i64 == std::numeric_limits<quint64>::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<qint8>::max());
MsgPack::Ext::unpack_upto_qint8(&i8, (quint8 *)packed.data(), &success);
QVERIFY(i8 == std::numeric_limits<qint8>::max());
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<qint16>::max());
MsgPack::Ext::unpack_upto_qint16(&i16, (quint8 *)packed.data(), &success);
QVERIFY(i16 == std::numeric_limits<qint16>::max());
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<qint32>::max());
MsgPack::Ext::unpack_upto_qint32(&i32, (quint8 *)packed.data(), &success);
QVERIFY(i32 == std::numeric_limits<qint32>::max());
QVERIFY(success);
packed = MsgPack::pack(std::numeric_limits<qint64>::max());
MsgPack::Ext::unpack_upto_qint64(&i64, (quint8 *)packed.data(), &success);
QVERIFY(i64 == std::numeric_limits<qint64>::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"

View File

@ -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()

View File

@ -0,0 +1,124 @@
#include <QString>
#include <QtTest>
#include <QDebug>
#include <msgpack.h>
#include <limits>
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<qint32>::max(), std::numeric_limits<qint32>::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<qint32>::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"