diff --git a/CMakeLists.txt b/CMakeLists.txt index d1d7694..0ef8be1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,6 @@ if (WIN32) set(CMAKE_DEBUG_POSTFIX "d") endif (WIN32) - - option (QT4_BUILD "BUild with Qt4") if (NOT QT4_BUILD) find_package(Qt5Core QUIET) diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 32e49b2..0000000 --- a/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include -#include - -quint32 packQPoint(const QVariant &variant, QByteArray &data, bool write) -{ - if (write) { - data.resize(8); - QDataStream out(&data, QIODevice::WriteOnly); - out.setVersion(QDataStream::Qt_5_3); - out << variant.toPoint(); - } - return 8; -} - -QVariant unpackQPoint(QByteArray &data) -{ - QDataStream in(&data, QIODevice::ReadOnly); - in.setVersion(QDataStream::Qt_5_3); - QPoint p; - in >> p; - return p; -} - -int main(int argc, char *argv[]) -{ - Q_UNUSED(argc) - Q_UNUSED(argv) - //QCoreApplication a(argc, argv); - - MsgPack::registerPacker(QMetaType::QPoint, 7, packQPoint); - MsgPack::registerUnpacker(7, unpackQPoint); - - QVariantList l; - - l << QPoint(12, 13); - QByteArray arr = MsgPack::pack(l); - qDebug() << arr.toBase64(); - - qDebug() << MsgPack::unpack(arr); - - - return 0; - //return a.exec(); -} diff --git a/msgpack-qt.pro b/msgpack-qt.pro deleted file mode 100644 index c35a340..0000000 --- a/msgpack-qt.pro +++ /dev/null @@ -1,28 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2014-09-07T17:43:05 -# -#------------------------------------------------- - -QT += core - -QT -= gui - -TARGET = qmsgpack -#CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - - -SOURCES += main.cpp \ - msgpack.cpp \ - private/pack_p.cpp \ - private/unpack_p.cpp - -HEADERS += \ - msgpack.h \ - private/pack_p.h \ - private/unpack_p.h \ - private/sysdep.h \ - msgpack_common.h diff --git a/msgpack.cpp b/msgpack.cpp deleted file mode 100644 index 2c54923..0000000 --- a/msgpack.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "msgpack.h" -#include -#include "private/unpack_p.h" -#include "private/pack_p.h" -#include - -QVariant MsgPack::unpack(const QByteArray &data) -{ - quint8 *p = (quint8 *)data.data(); - quint8 *end = p + data.size() - 1; - - return MsgPackPrivate::unpack(p, end); -} - - -QByteArray MsgPack::pack(const QVariant &variant) -{ - quint8 *p = 0; - quint8 *end = MsgPackPrivate::pack(variant, p, false); - quint32 size = end - p; - qDebug() << "size probe:" << size; - - QByteArray arr; - arr.resize(size); - end = MsgPackPrivate::pack(variant, (quint8 *)arr.data(), true); - - return arr; -} - - -bool MsgPack::registerPacker(QMetaType::Type qType, qint8 msgpackType, MsgPack::pack_user_f packer) -{ - return MsgPackPrivate::register_packer(qType, msgpackType, packer); -} - - -bool MsgPack::registerUnpacker(qint8 msgpackType, MsgPack::unpack_user_f unpacker) -{ - return MsgPackPrivate::register_unpacker(msgpackType, unpacker); -} diff --git a/msgpack.h b/msgpack.h deleted file mode 100644 index 34e13dd..0000000 --- a/msgpack.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef MSGPACK_H -#define MSGPACK_H -#include -#include -#include "msgpack_common.h" - -namespace MsgPack -{ - QVariant unpack(const QByteArray &data); - bool registerUnpacker(qint8 msgpackType, unpack_user_f unpacker); - - QByteArray pack(const QVariant &variant); - bool registerPacker(QMetaType::Type qType, qint8 msgpackType, pack_user_f packer); -} - -#endif // MSGPACK_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e83feb..e82a68b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -set(qmsgpack_srcs msgpack.cpp private/pack_p.cpp private/unpack_p.cpp) +set(qmsgpack_srcs msgpack.cpp msgpack_common.cpp private/pack_p.cpp private/unpack_p.cpp) set(qmsgpack_headers msgpack.h msgpack_common.h msgpack_export.h) add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers}) @@ -9,6 +9,11 @@ else () target_link_libraries(qmsgpack ${QT_LIBRARIES}) endif () +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/msgpack_common.h.in" + "${CMAKE_CURRENT_SOURCE_DIR}/msgpack_common.h" + IMMEDIATE @ONLY) + if (NOT android) set_target_properties(qmsgpack PROPERTIES VERSION ${QMSGPACK_MAJOR}.${QMSGPACK_MINOR}.${QMSGPACK_VERSION} diff --git a/src/main.cpp b/src/main.cpp index 32e49b2..f18a437 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,18 +30,28 @@ int main(int argc, char *argv[]) Q_UNUSED(argv) //QCoreApplication a(argc, argv); - MsgPack::registerPacker(QMetaType::QPoint, 7, packQPoint); - MsgPack::registerUnpacker(7, unpackQPoint); + qDebug() << "msgpack v" << MsgPack::version(); - QVariantList l; + QVariantMap map; + map["one"] = 1; + map["map"] = QVariantMap(); +// map["booleans"] = QVariantList() << false << true; +// map["list2"] = QVariantList() << (QVariantList() << "abc" << "def") +// << (QVariantList() << "qwe" << "rty"); + map["integers"] = QVariantList() << 0 << 127 << -31 << 128 << 777; +// map["bytearray"] = QByteArray("bytes"); + +// QVariantMap map2; +// map2["one"] = 1; +// map2["two"] = QVariantMap(); +// map["map2"] = map2; + + QByteArray arr = MsgPack::pack(map); + + QVariantMap um = MsgPack::unpack(arr).toMap(); - l << QPoint(12, 13); - QByteArray arr = MsgPack::pack(l); qDebug() << arr.toBase64(); - qDebug() << MsgPack::unpack(arr); - - return 0; //return a.exec(); } diff --git a/src/msgpack-qt.pro b/src/msgpack-qt.pro index 7774d33..cfb1e2f 100644 --- a/src/msgpack-qt.pro +++ b/src/msgpack-qt.pro @@ -11,8 +11,8 @@ QT -= gui TARGET = qmsgpack CONFIG -= app_bundle -TEMPLATE = lib -DEFINES += MSGPACK_MAKE_LIB +TEMPLATE = app +#DEFINES += MSGPACK_MAKE_LIB target.path = ../build INSTALLS += target QMAKE_CXXFLAGS += -fPIC @@ -20,6 +20,7 @@ QMAKE_CXXFLAGS += -fPIC SOURCES += main.cpp \ msgpack.cpp \ + msgpack_common.cpp \ private/pack_p.cpp \ private/unpack_p.cpp diff --git a/src/msgpack_common.cpp b/src/msgpack_common.cpp new file mode 100644 index 0000000..894435d --- /dev/null +++ b/src/msgpack_common.cpp @@ -0,0 +1,9 @@ +#include "msgpack_common.h" + +QString MsgPack::version() +{ + return QString("%1.%2.%3") + .arg(MSGPACK_MAJOR) + .arg(MSGPACK_MINOR) + .arg(MSGPACK_VERSION); +} \ No newline at end of file diff --git a/src/msgpack_common.h b/src/msgpack_common.h index 935f5ba..a765236 100644 --- a/src/msgpack_common.h +++ b/src/msgpack_common.h @@ -3,6 +3,10 @@ #include +#define MSGPACK_MAJOR 0 +#define MSGPACK_MINOR 0 +#define MSGPACK_VERSION 0 + namespace MsgPack { /** * pack some variant to byte array data @@ -12,7 +16,9 @@ namespace MsgPack { */ typedef quint32 (*pack_user_f)(const QVariant &variant, QByteArray &data, bool write); -typedef QVariant (*unpack_user_f)(QByteArray &data); +typedef QVariant (*unpack_user_f)(const QByteArray &data); + +QString version(); } #endif // COMMON_H diff --git a/msgpack_common.h b/src/msgpack_common.h.in similarity index 65% rename from msgpack_common.h rename to src/msgpack_common.h.in index 935f5ba..231c1b5 100644 --- a/msgpack_common.h +++ b/src/msgpack_common.h.in @@ -3,6 +3,10 @@ #include +#define MSGPACK_MAJOR @QMSGPACK_MAJOR@ +#define MSGPACK_MINOR @QMSGPACK_MINOR@ +#define MSGPACK_VERSION @QMSGPACK_VERSION@ + namespace MsgPack { /** * pack some variant to byte array data @@ -12,7 +16,9 @@ namespace MsgPack { */ typedef quint32 (*pack_user_f)(const QVariant &variant, QByteArray &data, bool write); -typedef QVariant (*unpack_user_f)(QByteArray &data); +typedef QVariant (*unpack_user_f)(const QByteArray &data); + +QString version(); } #endif // COMMON_H diff --git a/src/private/pack_p.cpp b/src/private/pack_p.cpp index 4287895..79f4492 100644 --- a/src/private/pack_p.cpp +++ b/src/private/pack_p.cpp @@ -18,6 +18,8 @@ quint8 *MsgPackPrivate::pack(const QVariant &v, quint8 *p, bool wr) p = pack_string(v.toString(), p, wr); else if (t == QMetaType::QVariantList) p = pack_list(v.toList(), p, wr); + else if (t == QMetaType::QStringList) + p = pack_stringlist(v.toStringList(), p, wr); else if (t == QMetaType::LongLong) p = pack_longlong(v.toLongLong(), p, wr); else if (t == QMetaType::ULongLong) @@ -120,9 +122,8 @@ quint8 *MsgPackPrivate::pack_bool(const QVariant &v, quint8 *p, bool wr) return p + 1; } -quint8 *MsgPackPrivate::pack_list(const QVariantList &list, quint8 *p, bool wr) +quint8 *MsgPackPrivate::pack_listlen(quint32 len, quint8 *p, bool wr) { - int len = list.length(); if (len <= 15) { if (wr) *p = 0x90 | len; p++; @@ -137,11 +138,27 @@ quint8 *MsgPackPrivate::pack_list(const QVariantList &list, quint8 *p, bool wr) if (wr) _msgpack_store32(p, len); p += 4; } + return p; +} + +quint8 *MsgPackPrivate::pack_list(const QVariantList &list, quint8 *p, bool wr) +{ + int len = list.length(); + p = pack_listlen(len, p, wr); foreach (QVariant item, list) p = pack(item, p, wr); return p; } +quint8 *MsgPackPrivate::pack_stringlist(const QStringList &list, quint8 *p, bool wr) +{ + int len = list.length(); + p = pack_listlen(len, p, wr); + foreach (QString item, list) + p = pack_string(item, p, wr); + return p; +} + quint8 *MsgPackPrivate::pack_string(const QString &str, quint8 *p, bool wr) { int len = str.length(); @@ -306,3 +323,4 @@ quint8 *MsgPackPrivate::pack_user(const QVariant &v, quint8 *p, bool wr) memcpy(p, data.data(), len); return p += len; } + diff --git a/src/private/pack_p.h b/src/private/pack_p.h index bac2330..5b8ceaf 100644 --- a/src/private/pack_p.h +++ b/src/private/pack_p.h @@ -22,15 +22,16 @@ quint8 * pack_longlong(qint64 i, quint8 *p, bool wr); quint8 * pack_ulonglong(quint64 i, quint8 *p, bool wr); quint8 * pack_bool(const QVariant &v, quint8 *p, bool wr); + +quint8 * pack_listlen(quint32 len, quint8 *p, bool wr); quint8 * pack_list(const QVariantList &list, quint8 *p, bool wr); +quint8 * pack_stringlist(const QStringList &list, quint8 *p, bool wr); + quint8 * pack_string(const QString &str, quint8 *p, bool wr); quint8 * pack_double(double i, quint8 *p, bool wr); quint8 * pack_array(const QByteArray &arr, quint8 *p, bool wr); quint8 * pack_map(const QVariantMap &map, quint8 *p, bool wr); quint8 * pack_user(const QVariant &v, quint8 *p, bool wr); - - - } #endif // PACK_P_H diff --git a/src/private/unpack_p.cpp b/src/private/unpack_p.cpp index aa84f2b..db868b1 100644 --- a/src/private/unpack_p.cpp +++ b/src/private/unpack_p.cpp @@ -352,24 +352,28 @@ quint8 * MsgPackPrivate::unpack_fixext16(QVariant &v, quint8 *p) quint8 * MsgPackPrivate::unpack_ext8(QVariant &v, quint8 *p) { - qint8 type = *(++p); - quint32 len = *(p++); + p++; + quint32 len = *(p); + p += 1; + qint8 type = *(p); return unpack_ext(v, p + 1, type, len); } quint8 * MsgPackPrivate::unpack_ext16(QVariant &v, quint8 *p) { - qint8 type = *(++p); + p++; quint32 len = _msgpack_load16(quint32, p); p += 2; + qint8 type = *(p); return unpack_ext(v, p + 1, type, len); } quint8 * MsgPackPrivate::unpack_ext32(QVariant &v, quint8 *p) { - qint8 type = *(++p); + p++; quint32 len = _msgpack_load32(quint32, p); p += 4; + qint8 type = *(p); return unpack_ext(v, p + 1, type, len); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 09112b4..18f82e5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,4 +8,8 @@ if (Qt5Core_FOUND) set(TEST_LIBRARIES ${Qt5Test_LIBRARIES}) endif () -add_subdirectory(pack) \ No newline at end of file +set(TEST_SUBDIRS pack unpack mixed) + +foreach(subdir ${TEST_SUBDIRS}) + add_subdirectory(${subdir}) +endforeach() \ No newline at end of file diff --git a/tests/mixed/CMakeLists.txt b/tests/mixed/CMakeLists.txt new file mode 100644 index 0000000..546649c --- /dev/null +++ b/tests/mixed/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 mixed_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/mixed/mixed.pro b/tests/mixed/mixed.pro new file mode 100644 index 0000000..ba6ee3f --- /dev/null +++ b/tests/mixed/mixed.pro @@ -0,0 +1,22 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-09-26T19:10:31 +# +#------------------------------------------------- + +QT += testlib + +QT -= gui + +TARGET = mixed_test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +INCLUDEPATH += ../../src +LIBS += -lqmsgpack + + +SOURCES += mixed_test.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/mixed/mixed_test.cpp b/tests/mixed/mixed_test.cpp new file mode 100644 index 0000000..1976483 --- /dev/null +++ b/tests/mixed/mixed_test.cpp @@ -0,0 +1,239 @@ +#include +#include +#include +#include + +class MixedTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void test_map(); + void test_ext(); + void test_mixed(); +}; + +void MixedTest::test_map() +{ + QVariantMap map; + map.insert(QString("%1").QString::arg(0, 5), "v"); + QByteArray arr = MsgPack::pack(map); + QVERIFY(arr.size() == map.size() * 8 + 1); + quint8 *p = (quint8 *)arr.data(); + QVERIFY(p[0] == (0x80 | map.size())); + QVariantMap m2 = MsgPack::unpack(arr).toMap(); + QVERIFY(m2 == map); + + for (int i = 1; i < 16; ++i) + map.insert(QString("%1").QString::arg(i, 5), "v"); + arr = MsgPack::pack(map); + QVERIFY(arr.size() == map.size() * 8 + 3); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xde); + QVERIFY(p[1] == 0x00); + QVERIFY(p[2] == 0x10); + m2 = MsgPack::unpack(arr).toMap(); + QVERIFY(m2 == map); + + for (int i = 16; i < 65536; ++i) + map.insert(QString("%1").QString::arg(i, 5), "v"); + arr = MsgPack::pack(map); + QVERIFY(arr.size() == map.size() * 8 + 5); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xdf); + QVERIFY(p[1] == 0x00); + QVERIFY(p[2] == 0x01); + QVERIFY(p[3] == 0x00); + QVERIFY(p[4] == 0x00); + m2 = MsgPack::unpack(arr).toMap(); + QVERIFY(m2 == map); +} + +class CustomType +{ +public: + CustomType() {} + CustomType(const CustomType &other) { m_size = other.m_size; } + ~CustomType() {} + + CustomType(int size) : m_size(size) {} + + int size() { return m_size; } + void setSize(int size) { m_size = size; } +private: + int m_size; +}; + +Q_DECLARE_METATYPE(CustomType) + +quint32 pack_custom_type(const QVariant &variant, QByteArray &data, bool write) +{ + CustomType ct = variant.value(); + if (write) { + data.resize(ct.size()); + quint8 *p = (quint8 *)data.data(); + for (int i = 0; i < ct.size(); ++i) + p[i] = 7; + } + + return ct.size(); +} + +QVariant unpack_custom_type(const QByteArray &data) +{ + return data; +} + +void MixedTest::test_ext() +{ + CustomType ct(1); + QVariant custom; + custom.setValue(ct); + + MsgPack::registerPacker((QMetaType::Type)qMetaTypeId(), + 3, pack_custom_type); + MsgPack::registerUnpacker(3, unpack_custom_type); + + QByteArray arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 2 + ct.size()); + quint8 *p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xd4); + QVERIFY(p[1] == 0x03); + QVERIFY(p[2] == 0x07); + QByteArray ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(2); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 2 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xd5); + QVERIFY(p[1] == 0x03); + QVERIFY(p[2] == 0x07); + QVERIFY(p[3] == 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(4); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 2 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xd6); + QVERIFY(p[1] == 0x03); + QVERIFY(p[2] == 0x07); + QVERIFY(p[3] == 0x07); + QVERIFY(p[4] == 0x07); + QVERIFY(p[5] == 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(8); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 2 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xd7); + QVERIFY(p[1] == 0x03); + for (int i = 0; i < ct.size(); ++i) + QVERIFY(p[2 + i] = 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(16); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 2 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xd8); + QVERIFY(p[1] == 0x03); + for (int i = 0; i < ct.size(); ++i) + QVERIFY(p[2 + i] = 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(3); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 3 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xc7); + QVERIFY(p[1] == 0x03); + QVERIFY(p[2] == 0x03); + for (int i = 0; i < ct.size(); ++i) + QVERIFY(p[3 + i] = 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(256); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 4 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xc8); + QVERIFY(p[1] == 0x01); + QVERIFY(p[2] == 0x00); + QVERIFY(p[3] == 0x03); + for (int i = 0; i < ct.size(); ++i) + QVERIFY(p[4 + i] = 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); + + ct.setSize(65536); + custom.setValue(ct); + arr = MsgPack::pack(custom); + QVERIFY(arr.size() == 6 + ct.size()); + p = (quint8 *)arr.data(); + QVERIFY(p[0] == 0xc9); + QVERIFY(p[1] == 0x00); + QVERIFY(p[2] == 0x01); + QVERIFY(p[3] == 0x00); + QVERIFY(p[4] == 0x00); + QVERIFY(p[5] == 0x03); + for (int i = 0; i < ct.size(); ++i) + QVERIFY(p[6 + i] = 0x07); + ub = MsgPack::unpack(arr).toByteArray(); + QVERIFY(ub.size() == ct.size()); + for (int i = 0; i < ub.size(); ++i) + QVERIFY(ub.data()[i] == 7); +} + +void MixedTest::test_mixed() +{ + QVariantMap map; + map["booleans"] = QVariantList() << false << true; + map["list2"] = QVariantList() << (QVariantList() << "abc" << "def") + << (QVariantList() << "qwe" << "rty"); + map["integers"] = QVariantList() << 0 << 127 << -31 << 128 << 777; + map["bytearray"] = QByteArray("bytes"); + + QVariantMap map2; + map2["one"] = 1; + map2["two"] = QVariantMap(); + map["map2"] = map2; + + QByteArray arr = MsgPack::pack(map); + + QVariant unpacked = MsgPack::unpack(arr); + + QVERIFY(unpacked.toMap() == map); +} + +QTEST_APPLESS_MAIN(MixedTest) + +#include "mixed_test.moc" diff --git a/tests/pack/pack_test.cpp b/tests/pack/pack_test.cpp index 74b6c1d..70b2963 100644 --- a/tests/pack/pack_test.cpp +++ b/tests/pack/pack_test.cpp @@ -19,9 +19,6 @@ private Q_SLOTS: void test_str(); void test_bin(); void test_array(); - void test_map(); - void test_ext(); - void test_mixed(); }; void PackTest::test_bool() @@ -316,180 +313,6 @@ void PackTest::test_array() QVERIFY(p[4] == 0x00); } -void PackTest::test_map() -{ - QVariantMap map; - map.insert(QString("%1").QString::arg(0, 5), "v"); - QByteArray arr = MsgPack::pack(map); - QVERIFY(arr.size() == map.size() * 8 + 1); - quint8 *p = (quint8 *)arr.data(); - QVERIFY(p[0] == (0x80 | map.size())); - - for (int i = 1; i < 16; ++i) - map.insert(QString("%1").QString::arg(i, 5), "v"); - arr = MsgPack::pack(map); - QVERIFY(arr.size() == map.size() * 8 + 3); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xde); - QVERIFY(p[1] == 0x00); - QVERIFY(p[2] == 0x10); - - for (int i = 16; i < 65536; ++i) - map.insert(QString("%1").QString::arg(i, 5), "v"); - arr = MsgPack::pack(map); - QVERIFY(arr.size() == map.size() * 8 + 5); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xdf); - QVERIFY(p[1] == 0x00); - QVERIFY(p[2] == 0x01); - QVERIFY(p[3] == 0x00); - QVERIFY(p[4] == 0x00); -} - -class CustomType -{ -public: - CustomType() {} - CustomType(const CustomType &other) { m_size = other.m_size; } - ~CustomType() {} - - CustomType(int size) : m_size(size) {} - - int size() { return m_size; } - void setSize(int size) { m_size = size; } -private: - int m_size; -}; - -Q_DECLARE_METATYPE(CustomType) - -quint32 pack_custom_type(const QVariant &variant, QByteArray &data, bool write) -{ - CustomType ct = variant.value(); - if (write) { - data.resize(ct.size()); - quint8 *p = (quint8 *)data.data(); - for (int i = 0; i < ct.size(); ++i) - p[i] = 7; - } - - return ct.size(); -} - -void PackTest::test_ext() -{ - CustomType ct(1); - QVariant custom; - custom.setValue(ct); - - MsgPack::registerPacker((QMetaType::Type)qMetaTypeId(), - 3, pack_custom_type); - - QByteArray arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 2 + ct.size()); - quint8 *p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xd4); - QVERIFY(p[1] == 0x03); - QVERIFY(p[2] == 0x07); - - ct.setSize(2); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 2 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xd5); - QVERIFY(p[1] == 0x03); - QVERIFY(p[2] == 0x07); - QVERIFY(p[3] == 0x07); - - ct.setSize(4); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 2 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xd6); - QVERIFY(p[1] == 0x03); - QVERIFY(p[2] == 0x07); - QVERIFY(p[3] == 0x07); - QVERIFY(p[4] == 0x07); - QVERIFY(p[5] == 0x07); - - ct.setSize(8); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 2 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xd7); - QVERIFY(p[1] == 0x03); - for (int i = 0; i < ct.size(); ++i) - QVERIFY(p[2 + i] = 0x07); - - ct.setSize(16); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 2 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xd8); - QVERIFY(p[1] == 0x03); - for (int i = 0; i < ct.size(); ++i) - QVERIFY(p[2 + i] = 0x07); - - ct.setSize(3); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 3 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xc7); - QVERIFY(p[1] == 0x03); - QVERIFY(p[2] == 0x03); - for (int i = 0; i < ct.size(); ++i) - QVERIFY(p[3 + i] = 0x07); - - ct.setSize(256); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 4 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xc8); - QVERIFY(p[1] == 0x01); - QVERIFY(p[2] == 0x00); - QVERIFY(p[3] == 0x03); - for (int i = 0; i < ct.size(); ++i) - QVERIFY(p[4 + i] = 0x07); - - ct.setSize(65536); - custom.setValue(ct); - arr = MsgPack::pack(custom); - QVERIFY(arr.size() == 6 + ct.size()); - p = (quint8 *)arr.data(); - QVERIFY(p[0] == 0xc9); - QVERIFY(p[1] == 0x00); - QVERIFY(p[2] == 0x01); - QVERIFY(p[3] == 0x00); - QVERIFY(p[4] == 0x00); - QVERIFY(p[5] == 0x03); - for (int i = 0; i < ct.size(); ++i) - QVERIFY(p[6 + i] = 0x07); -} - -void PackTest::test_mixed() -{ - QVariantMap map; -// map["booleans"] = QVariantList() << false << true; -// map["list2"] = QVariantList() << (QVariantList() << "abc" << "def") -// << (QVariantList() << "qwe" << "rty"); -// map["integers"] = QVariantList() << 0 << 127 << -31 << 128 << 777; - map["bytearray"] = QByteArray("bytes"); - -// QVariantMap map2; -// map2["one"] = 1; -// map2["two"] = QVariantMap(); -// map["map2"] = map2; - - QByteArray arr = MsgPack::pack(map); - qDebug() << arr.toBase64(); -} - QTEST_APPLESS_MAIN(PackTest) #include "pack_test.moc" diff --git a/tests/unpack/CMakeLists.txt b/tests/unpack/CMakeLists.txt new file mode 100644 index 0000000..1805932 --- /dev/null +++ b/tests/unpack/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 unpack_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/unpack/unpack.pro b/tests/unpack/unpack.pro new file mode 100644 index 0000000..4a7e9b8 --- /dev/null +++ b/tests/unpack/unpack.pro @@ -0,0 +1,21 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-09-25T10:25:22 +# +#------------------------------------------------- + +QT += testlib + +QT -= gui + +TARGET = unpack_test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app +LIBS += -lqmsgpack +INCLUDEPATH += ../../src + + +SOURCES += unpack_test.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/unpack/unpack_test.cpp b/tests/unpack/unpack_test.cpp new file mode 100644 index 0000000..10e8c48 --- /dev/null +++ b/tests/unpack/unpack_test.cpp @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include + +class UnpackTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void test_booleans(); + void test_integers(); + void test_floats(); + void test_strings(); + void test_binary(); + void test_array(); +}; + + +void UnpackTest::test_booleans() +{ + QByteArray pack = MsgPack::pack(QVariantList() << true << false); + QVariantList u = MsgPack::unpack(pack).toList(); + QVERIFY(u[0] == true); + QVERIFY(u[1] == false); +} + +void UnpackTest::test_integers() +{ + QByteArray ints = QByteArray::fromBase64("3AAUAH//4cyAzP/Q39CAzQEAzf//0f9/" + "0YAAzgABAADO/////9L//3//0oAAAADP" + "AAAAAQAAAADP///////////T/////3//" + "///TgAAAAAAAAAA="); + QVariantList l = MsgPack::unpack(ints).toList(); + QVERIFY(l[0].toInt() == 0); + QVERIFY(l[1].toInt() == 127); + QVERIFY(l[2].toInt() == -1); + QVERIFY(l[3].toInt() == -31); + QVERIFY(l[4].toInt() == 128); + QVERIFY(l[5].toInt() == 255); + QVERIFY(l[6].toInt() == -33); + QVERIFY(l[7].toInt() == -128); + QVERIFY(l[8].toInt() == 256); + QVERIFY(l[9].toInt() == 65535); + QVERIFY(l[10].toInt() == -129); + QVERIFY(l[11].toInt() == -32768); + QVERIFY(l[12].toInt() == 65536); + QVERIFY(l[13].toUInt() == 4294967295); + QVERIFY(l[14].toInt() == -32769); + QVERIFY(l[15].toInt() == -2147483648); + QVERIFY(l[16].toLongLong() == 4294967296); + QVERIFY(l[17].toULongLong() == std::numeric_limits::max()); + QVERIFY(l[18].toLongLong() == -2147483649); + QVERIFY(l[19].toLongLong() == std::numeric_limits::min()); +} + +void UnpackTest::test_floats() +{ + QByteArray packed = QByteArray::fromBase64("k8sAAAAAAAAAAMtAHTMzMzMzM8tHM" + "0JhcsdNgg=="); + QVariantList l = MsgPack::unpack(packed).toList(); + QVERIFY(l[0].toDouble() == 0.0); + QVERIFY(l[1].toDouble() == 7.3); + QVERIFY(l[2].toDouble() == pow(10, 35)); +} + +void UnpackTest::test_strings() +{ + QStringList strs; + strs << "abc"; + QString s; + for (int i = 0; i < 8; ++i) + s += "xy"; + strs << s; + s = QString(); + for (int i = 0; i < 64; ++i) + s += "msgp"; + strs << s; + s = QString(); + for (int i = 0; i < 4096; ++i) + s += "messagepack test"; + strs << s; + strs << ""; + + QByteArray arr = MsgPack::pack(strs); + + QStringList l = MsgPack::unpack(arr).toStringList(); + QVERIFY(l[0] == strs[0]); + QVERIFY(l[1] == strs[1]); + QVERIFY(l[2] == strs[2]); + QVERIFY(l[3] == strs[3]); + QVERIFY(l[4].isEmpty()); +} + +void UnpackTest::test_binary() +{ + QVariantList l; + l << QByteArray(16, 'm'); + l << QByteArray(256, 's'); + l << QByteArray(65536, 'g'); + l << QByteArray(0, 'p'); + + QByteArray arr = MsgPack::pack(l); + QVariantList u = MsgPack::unpack(arr).toList(); + + QVERIFY(u[0].toByteArray() == l[0].toByteArray()); + QVERIFY(u[1].toByteArray() == l[1].toByteArray()); + QVERIFY(u[2].toByteArray() == l[2].toByteArray()); + QVERIFY(u[3].toByteArray().isEmpty()); +} + +void UnpackTest::test_array() +{ + QVariantList l; + QVERIFY(MsgPack::unpack(MsgPack::pack(l)).toList().isEmpty()); + + l << 0; + QByteArray pack = MsgPack::pack(l); + QVariantList lu = MsgPack::unpack(pack).toList(); + QVERIFY(lu.size() == 1); + QVERIFY(lu[0] == 0); + + l = QVariantList(); + for (int i = 0; i < 256; ++i) + l << i; + pack = MsgPack::pack(l); + lu = MsgPack::unpack(pack).toList(); + QVERIFY(lu.size() == 256); + for (int i = 0; i < 256; ++i) + QVERIFY(lu[i] == i); + + l = QVariantList(); + for(int i = 0; i < 65536; ++i) + l << i; + pack = MsgPack::pack(l); + lu = MsgPack::unpack(pack).toList(); + QVERIFY(lu.size() == 65536); + for (int i = 0; i < 65536; ++i) + QVERIFY(lu[i] == i); +} + +QTEST_APPLESS_MAIN(UnpackTest) + +#include "unpack_test.moc"