CMake BUILD_TESTS variable added

TRUE and FALSE renamed to MTRUE and MFALSE
stream.h[cpp] renamed to msgpackstream.h[cpp]
QMap and QHash added to MsgPackStream + test
This commit is contained in:
Roman
2015-06-29 14:32:35 +03:00
parent 318aa870cd
commit ce6ddab5e4
11 changed files with 260 additions and 27 deletions

View File

@ -16,6 +16,6 @@ before_install:
script: script:
- mkdir build - mkdir build
- cd build - cd build
- cmake .. - if [ -z ${QT4_BUILD+x} ]; then cmake -DBUILD_TESTS=TRUE -DQT4_BUILD=FALSE ..; else cmake -DBUILD_TESTS=TRUE -DQT4_BUILD=TRUE ..; fi
- make - make
- make test - make test

View File

@ -80,14 +80,14 @@ set(MSGPACK_QT_LIB_VERSION_STRING "${QMSGPACK_MAJOR}.${QMSGPACK_MINOR}.${QMSGPAC
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
add_subdirectory(src) add_subdirectory(src)
#if (MSGPACK_BUILD_TESTS) if (BUILD_TESTS)
enable_testing() enable_testing()
add_subdirectory(tests) add_subdirectory(tests)
#endif () endif ()
install(EXPORT qmsgpack-export DESTINATION ${CMAKECONFIG_INSTALL_DIR} FILE MsgPackQtTargets.cmake) install(EXPORT qmsgpack-export DESTINATION ${CMAKECONFIG_INSTALL_DIR} FILE MsgPackQtTargets.cmake)
file(RELATIVE_PATH relInstallDir ${CMAKE_INSTALL_PREFIX}/$CMAKECONFIG_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}) file(RELATIVE_PATH relInstallDir ${CMAKE_INSTALL_PREFIX}/$CMAKECONFIG_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
add_custom_target(uninstall add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")

View File

@ -1,5 +1,5 @@
set(qmsgpack_srcs msgpack.cpp msgpack_common.cpp stream.cpp private/pack_p.cpp private/unpack_p.cpp private/qt_types_p.cpp) set(qmsgpack_srcs msgpack.cpp msgpack_common.cpp msgpackstream.cpp private/pack_p.cpp private/unpack_p.cpp private/qt_types_p.cpp)
set(qmsgpack_headers msgpack.h stream.h msgpack_common.h msgpack_export.h endianhelper.h) set(qmsgpack_headers msgpack.h msgpackstream.h msgpack_common.h msgpack_export.h endianhelper.h)
add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers}) add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers})
@ -31,4 +31,4 @@ install(TARGETS qmsgpack EXPORT qmsgpack-export
LIBRARY DESTINATION ${LIB_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/qmsgpack) PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/qmsgpack)

34
src/CMakeLists.txt~ Normal file
View File

@ -0,0 +1,34 @@
set(qmsgpack_srcs msgpack.cpp msgpack_common.cpp stream.cpp private/pack_p.cpp private/unpack_p.cpp private/qt_types_p.cpp)
set(qmsgpack_headers msgpack.h stream.h msgpack_common.h msgpack_export.h endianhelper.h)
add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers})
if (Qt5Core_FOUND)
target_link_libraries(qmsgpack Qt5::Core)
else ()
target_link_libraries(qmsgpack ${QT_LIBRARIES})
endif ()
if (Qt5Gui_FOUND)
target_link_libraries(qmsgpack Qt5::Gui)
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}
SOVERSION ${QMSGPACK_MAJOR})
endif ()
set_target_properties(qmsgpack PROPERTIES
DEFINE_SYMBOL MSGPACK_MAKE_LIB
PUBLIC_HEADER "${qmsgpack_headers}")
install(TARGETS qmsgpack EXPORT qmsgpack-export
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/qmsgpack)

View File

@ -36,8 +36,8 @@ const quint8 FIXARRAY = 0x90;
const quint8 FIXSTR = 0xa0; const quint8 FIXSTR = 0xa0;
const quint8 NIL = 0xc0; const quint8 NIL = 0xc0;
const quint8 NEVER_USED = 0xc1; const quint8 NEVER_USED = 0xc1;
const quint8 FALSE = 0xc2; const quint8 MFALSE = 0xc2;
const quint8 TRUE = 0xc3; const quint8 MTRUE = 0xc3;
const quint8 BIN8 = 0xc4; const quint8 BIN8 = 0xc4;
const quint8 BIN16 = 0xc5; const quint8 BIN16 = 0xc5;
const quint8 BIN32 = 0xc6; const quint8 BIN32 = 0xc6;

View File

@ -36,8 +36,8 @@ const quint8 FIXARRAY = 0x90;
const quint8 FIXSTR = 0xa0; const quint8 FIXSTR = 0xa0;
const quint8 NIL = 0xc0; const quint8 NIL = 0xc0;
const quint8 NEVER_USED = 0xc1; const quint8 NEVER_USED = 0xc1;
const quint8 FALSE = 0xc2; const quint8 MFALSE = 0xc2;
const quint8 TRUE = 0xc3; const quint8 MTRUE = 0xc3;
const quint8 BIN8 = 0xc4; const quint8 BIN8 = 0xc4;
const quint8 BIN16 = 0xc5; const quint8 BIN16 = 0xc5;
const quint8 BIN32 = 0xc6; const quint8 BIN32 = 0xc6;

View File

@ -1,6 +1,6 @@
#include "stream.h" #include "msgpackstream.h"
#include <QBuffer>
#include "private/pack_p.h" #include "private/pack_p.h"
#include <QBuffer>
#include <QDebug> #include <QDebug>
#undef CHECK_STREAM_PRECOND #undef CHECK_STREAM_PRECOND
@ -27,7 +27,7 @@ MsgPackStream::MsgPackStream() :
{ } { }
MsgPackStream::MsgPackStream(QIODevice *d) : MsgPackStream::MsgPackStream(QIODevice *d) :
dev(d), owndev(false) dev(d), owndev(false), q_status(Ok)
{ } { }
MsgPackStream::MsgPackStream(QByteArray *a, QIODevice::OpenMode mode) : MsgPackStream::MsgPackStream(QByteArray *a, QIODevice::OpenMode mode) :
@ -89,10 +89,10 @@ MsgPackStream &MsgPackStream::operator>>(bool &b)
b = false; b = false;
setStatus(ReadPastEnd); setStatus(ReadPastEnd);
} else { } else {
if (p[0] != MsgPack::FirstByte::TRUE || if (p[0] != MsgPack::FirstByte::MTRUE ||
p[0] != MsgPack::FirstByte::FALSE) p[0] != MsgPack::FirstByte::MFALSE)
setStatus(ReadCorruptData); setStatus(ReadCorruptData);
b = (p[0] == MsgPack::FirstByte::TRUE); b = (p[0] == MsgPack::FirstByte::MTRUE);
} }
return *this; return *this;
} }
@ -273,6 +273,7 @@ MsgPackStream &MsgPackStream::operator>>(QString &str)
} }
str = QString::fromUtf8((const char*) data, len); str = QString::fromUtf8((const char*) data, len);
delete[] data; delete[] data;
return *this;
} }
MsgPackStream &MsgPackStream::operator>>(QByteArray &array) MsgPackStream &MsgPackStream::operator>>(QByteArray &array)
@ -318,11 +319,23 @@ bool MsgPackStream::readBytes(char *data, uint len)
return dev->read(data, len) == len; return dev->read(data, len) == len;
} }
bool MsgPackStream::readNil()
{
CHECK_STREAM_PRECOND(false);
quint8 b;
if (dev->read((char *)&b, 1) != 1 ||
b != MsgPack::FirstByte::NIL) {
setStatus(ReadCorruptData);
return false;
}
return true;
}
MsgPackStream &MsgPackStream::operator<<(bool b) MsgPackStream &MsgPackStream::operator<<(bool b)
{ {
CHECK_STREAM_WRITE_PRECOND(*this); CHECK_STREAM_WRITE_PRECOND(*this);
quint8 m = b == true ? quint8 m = b == true ?
MsgPack::FirstByte::TRUE : MsgPack::FirstByte::FALSE; MsgPack::FirstByte::MTRUE : MsgPack::FirstByte::MFALSE;
if (dev->write((char *)&m, 1) != 1) if (dev->write((char *)&m, 1) != 1)
setStatus(WriteFailed); setStatus(WriteFailed);
return *this; return *this;
@ -433,8 +446,21 @@ MsgPackStream &MsgPackStream::operator<<(QByteArray array)
bool MsgPackStream::writeBytes(const char *data, uint len) bool MsgPackStream::writeBytes(const char *data, uint len)
{ {
CHECK_STREAM_WRITE_PRECOND(false); CHECK_STREAM_WRITE_PRECOND(false);
if (dev->write(data, len) != len) if (dev->write(data, len) != len) {
setStatus(WriteFailed); setStatus(WriteFailed);
return false;
}
return true;
}
bool MsgPackStream::writeNil()
{
CHECK_STREAM_WRITE_PRECOND(false);
quint8 b = MsgPack::FirstByte::NIL;
if (dev->write((char *)&b, 1) != 1) {
setStatus(WriteFailed);
return false;
}
return true; return true;
} }

View File

@ -37,6 +37,7 @@ public:
MsgPackStream &operator>>(QString &str); MsgPackStream &operator>>(QString &str);
MsgPackStream &operator>>(QByteArray &array); MsgPackStream &operator>>(QByteArray &array);
bool readBytes(char *data, uint len); bool readBytes(char *data, uint len);
bool readNil();
MsgPackStream &operator<<(bool b); MsgPackStream &operator<<(bool b);
MsgPackStream &operator<<(quint32 u32); MsgPackStream &operator<<(quint32 u32);
@ -49,6 +50,7 @@ public:
MsgPackStream &operator<<(const char *str); MsgPackStream &operator<<(const char *str);
MsgPackStream &operator<<(QByteArray array); MsgPackStream &operator<<(QByteArray array);
bool writeBytes(const char *data, uint len); bool writeBytes(const char *data, uint len);
bool writeNil();
private: private:
QIODevice *dev; QIODevice *dev;
@ -76,10 +78,12 @@ MsgPackStream& operator<<(MsgPackStream& s, const QList<T> &list)
_msgpack_store32(p + 1, len); _msgpack_store32(p + 1, len);
s.writeBytes((const char *)p, 5); s.writeBytes((const char *)p, 5);
} }
if (s.status() != MsgPackStream::Ok) if (s.status() != MsgPackStream::Ok)
return s; return s;
for (int i = 0; i < list.size(); ++i) for (int i = 0; i < list.size(); ++i)
s << list[i]; s << list[i];
return s; return s;
} }
@ -87,6 +91,7 @@ template <typename T>
MsgPackStream& operator>>(MsgPackStream& s, QList<T> &list) MsgPackStream& operator>>(MsgPackStream& s, QList<T> &list)
{ {
list.clear(); list.clear();
quint8 p[5]; quint8 p[5];
quint32 len; quint32 len;
s.readBytes((char *)p, 1); s.readBytes((char *)p, 1);
@ -99,6 +104,7 @@ MsgPackStream& operator>>(MsgPackStream& s, QList<T> &list)
s.readBytes((char *)p + 1, 4); s.readBytes((char *)p + 1, 4);
len = _msgpack_load32(quint32, p + 1); len = _msgpack_load32(quint32, p + 1);
} }
for (quint32 i = 0; i < len; ++i) { for (quint32 i = 0; i < len; ++i) {
T t; T t;
s >> t; s >> t;
@ -106,6 +112,133 @@ MsgPackStream& operator>>(MsgPackStream& s, QList<T> &list)
if (s.atEnd()) if (s.atEnd())
break; break;
} }
return s;
}
template <class Key, class T>
MsgPackStream& operator<<(MsgPackStream &s, const QHash<Key, T> &hash)
{
quint32 len = 0;
QHashIterator<Key, T> it(hash);
while (it.hasNext()) {
it.next();
len++;
}
quint8 p[5];
if (len <= 15) {
p[0] = MsgPack::FirstByte::FIXMAP | len;
s.writeBytes((const char *)p, 1);
} else if (len <= std::numeric_limits<quint16>::max()) {
p[0] = MsgPack::FirstByte::MAP16;
_msgpack_store16(p + 1, len);
s.writeBytes((const char *)p, 3);
} else {
p[0] = MsgPack::FirstByte::MAP32;
_msgpack_store32(p + 1, len);
s.writeBytes((const char *)p, 5);
}
it.toFront();
while (it.hasNext()) {
it.next();
s << it.key() << it.value();
}
return s;
}
template <class Key, class T>
MsgPackStream& operator>>(MsgPackStream& s, QHash<Key, T> &hash)
{
hash.clear();
quint8 p[5];
quint32 len;
s.readBytes((char *)p, 1);
if (p[0] >= 0x80 && p[0] <= 0x8f) {
len = p[0] & 0xf;
} else if (p[0] == MsgPack::FirstByte::MAP16) {
s.readBytes((char *)p + 1, 2);
len = _msgpack_load16(quint16, p + 1);
} else if (p[0] == MsgPack::FirstByte::MAP32) {
s.readBytes((char *)p + 1, 4);
len = _msgpack_load32(quint32, p + 1);
}
for (quint32 i = 0; i < len; ++i) {
Key key;
T t;
s >> key >> t;
hash.insert(key, t);
if (s.atEnd())
break;
}
return s;
}
template <class Key, class T>
MsgPackStream& operator<<(MsgPackStream &s, const QMap<Key, T> &map)
{
quint32 len = 0;
QMapIterator<Key, T> it(map);
while (it.hasNext()) {
it.next();
len++;
}
quint8 p[5];
if (len <= 15) {
p[0] = MsgPack::FirstByte::FIXMAP | len;
s.writeBytes((const char *)p, 1);
} else if (len <= std::numeric_limits<quint16>::max()) {
p[0] = MsgPack::FirstByte::MAP16;
_msgpack_store16(p + 1, len);
s.writeBytes((const char *)p, 3);
} else {
p[0] = MsgPack::FirstByte::MAP32;
_msgpack_store32(p + 1, len);
s.writeBytes((const char *)p, 5);
}
it.toFront();
while (it.hasNext()) {
it.next();
s << it.key() << it.value();
}
return s;
}
template <class Key, class T>
MsgPackStream& operator>>(MsgPackStream& s, QMap<Key, T> &map)
{
map.clear();
quint8 p[5];
quint32 len;
s.readBytes((char *)p, 1);
if (p[0] >= 0x80 && p[0] <= 0x8f) {
len = p[0] & 0xf;
} else if (p[0] == MsgPack::FirstByte::MAP16) {
s.readBytes((char *)p + 1, 2);
len = _msgpack_load16(quint16, p + 1);
} else if (p[0] == MsgPack::FirstByte::MAP32) {
s.readBytes((char *)p + 1, 4);
len = _msgpack_load32(quint32, p + 1);
}
for (quint32 i = 0; i < len; ++i) {
Key key;
T t;
s >> key >> t;
map.insert(key, t);
if (s.atEnd())
break;
}
return s; return s;
} }

View File

@ -1,9 +1,8 @@
#include "qt_types_p.h" #include "qt_types_p.h"
#include "pack_p.h" #include "pack_p.h"
#include "unpack_p.h" #include "unpack_p.h"
#include "stream.h" #include "msgpackstream.h"
#include "../endianhelper.h" #include "endianhelper.h"
#include <QDebug> #include <QDebug>
#ifdef QT_GUI_LIB #ifdef QT_GUI_LIB
@ -182,7 +181,6 @@ QVariant MsgPackPrivate::unpack_qpoint(const QByteArray &data)
MsgPackStream stream(data); MsgPackStream stream(data);
qint32 x, y; qint32 x, y;
stream >> x >> y; stream >> x >> y;
qDebug() << "unpack qpoint stream" << (stream.status() == MsgPackStream::Ok);
return QPoint(x, y); return QPoint(x, y);
} }

View File

@ -216,7 +216,7 @@ void PackTest::test_float()
void PackTest::test_str() void PackTest::test_str()
{ {
QString str = QStringLiteral("msgpack rocks"); QString str = QString("msgpack rocks");
QByteArray arr = MsgPack::pack(str); QByteArray arr = MsgPack::pack(str);
QVERIFY(arr.size() == 14); QVERIFY(arr.size() == 14);
quint8 *p = (quint8 *)arr.data(); quint8 *p = (quint8 *)arr.data();

View File

@ -1,7 +1,6 @@
#include <QString> #include <QString>
#include <QtTest> #include <QtTest>
#include <QDebug> #include <msgpackstream.h>
#include <stream.h>
#include <msgpack.h> #include <msgpack.h>
#include <limits> #include <limits>
@ -18,6 +17,7 @@ private Q_SLOTS:
void test_double(); void test_double();
void test_bin(); void test_bin();
void test_array(); void test_array();
void test_map();
}; };
void StreamTest::test_unpack_integers() void StreamTest::test_unpack_integers()
@ -142,7 +142,7 @@ void StreamTest::test_pack_integers()
void StreamTest::test_unpack_string() void StreamTest::test_unpack_string()
{ {
QString str = QStringLiteral("msgpack rocks"); QString str = QString("msgpack rocks");
QByteArray packed = MsgPack::pack(str); QByteArray packed = MsgPack::pack(str);
QString str2; QString str2;
@ -367,5 +367,47 @@ void StreamTest::test_array()
} }
} }
void StreamTest::test_map()
{
QMap<QString, int> map, map2;
QByteArray ba;
map.insert("m0", 0);
{
MsgPackStream stream(&ba, QIODevice::WriteOnly);
stream << map;
MsgPackStream stream2(ba);
stream2 >> map2;
}
QVERIFY(ba.length() == 5);
quint8 *p = (quint8 *)ba.data();
QVERIFY(p[0] == 0x80 | 1);
QVERIFY(map == map2);
for (int i = 1; i < 16; ++i)
map.insert(QString("m%1").QString::arg(i), i);
{
MsgPackStream stream(&ba, QIODevice::WriteOnly);
stream << map;
MsgPackStream stream2(ba);
stream2 >> map2;
}
p = (quint8 *)ba.data();
QVERIFY(p[0] == 0xde);
QVERIFY(map == map2);
for (int i = 16; i < 65536; ++i)
map.insert(QString("m%1").QString::arg(i), i);
{
MsgPackStream stream(&ba, QIODevice::WriteOnly);
stream << map;
MsgPackStream stream2(ba);
stream2 >> map2;
}
p = (quint8 *)ba.data();
QVERIFY(p[0] == 0xdf);
QVERIFY(map == map2);
}
QTEST_APPLESS_MAIN(StreamTest) QTEST_APPLESS_MAIN(StreamTest)
#include "stream_test.moc" #include "stream_test.moc"