mirror of
https://github.com/romixlab/qmsgpack.git
synced 2025-08-01 03:14:27 +02:00
Started work on MsgPackStream
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
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)
|
||||
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)
|
||||
|
||||
add_library(qmsgpack SHARED ${qmsgpack_srcs} ${qmsgpack_headers})
|
||||
|
||||
|
@@ -28,7 +28,8 @@ SOURCES += msgpack.cpp \
|
||||
private/pack_p.cpp \
|
||||
private/unpack_p.cpp \
|
||||
private/qt_types_p.cpp \
|
||||
msgpack_ext.cpp
|
||||
msgpack_ext.cpp \
|
||||
stream.cpp
|
||||
|
||||
HEADERS += \
|
||||
msgpack.h \
|
||||
@@ -38,4 +39,5 @@ HEADERS += \
|
||||
msgpack_common.h \
|
||||
msgpack_export.h \
|
||||
private/qt_types_p.h \
|
||||
msgpack_ext.h
|
||||
msgpack_ext.h \
|
||||
stream.h
|
||||
|
@@ -1,146 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
#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
|
98
src/stream.cpp
Normal file
98
src/stream.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "stream.h"
|
||||
#include <QBuffer>
|
||||
|
||||
#undef CHECK_STREAM_PRECOND
|
||||
#ifndef QT_NO_DEBUG
|
||||
#define CHECK_STREAM_PRECOND(retVal) \
|
||||
if (!dev) { \
|
||||
qWarning("msgpack::Stream: No device"); \
|
||||
return retVal; \
|
||||
}
|
||||
#else
|
||||
#define CHECK_STREAM_PRECOND(retVal) \
|
||||
if (!dev) { \
|
||||
return retVal; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CHECK_STREAM_WRITE_PRECOND(retVal) \
|
||||
CHECK_STREAM_PRECOND(retVal) \
|
||||
if (q_status != Ok) \
|
||||
return retVal;
|
||||
|
||||
MsgPackStream::MsgPackStream() :
|
||||
dev(0), compatibility(false), owndev(false), q_status(Ok)
|
||||
{ }
|
||||
|
||||
MsgPackStream::MsgPackStream(QIODevice *d) :
|
||||
dev(d), compatibility(false), owndev(false)
|
||||
{ }
|
||||
|
||||
MsgPackStream::MsgPackStream(QByteArray *a, QIODevice::OpenMode mode) :
|
||||
compatibility(false), owndev(true), q_status(Ok)
|
||||
{
|
||||
QBuffer *buf = new QBuffer(a);
|
||||
buf->open(mode);
|
||||
dev = buf;
|
||||
}
|
||||
|
||||
MsgPackStream::MsgPackStream(const QByteArray &a) :
|
||||
compatibility(false), owndev(true), q_status(Ok)
|
||||
{
|
||||
QBuffer *buf = new QBuffer();
|
||||
buf->setData(a);
|
||||
buf->open(QIODevice::ReadOnly);
|
||||
dev = buf;
|
||||
}
|
||||
|
||||
MsgPackStream::~MsgPackStream()
|
||||
{
|
||||
if (owndev)
|
||||
delete dev;
|
||||
}
|
||||
|
||||
void MsgPackStream::setDevice(QIODevice *d)
|
||||
{
|
||||
if (owndev)
|
||||
delete dev;
|
||||
dev = d;
|
||||
owndev = false;
|
||||
}
|
||||
|
||||
bool MsgPackStream::atEnd() const
|
||||
{
|
||||
return dev ? dev->atEnd() : true;
|
||||
}
|
||||
|
||||
void MsgPackStream::setCompatibility(bool isEnabled)
|
||||
{
|
||||
compatibility = isEnabled;
|
||||
}
|
||||
|
||||
MsgPackStream::Status MsgPackStream::status() const
|
||||
{
|
||||
return q_status;
|
||||
}
|
||||
|
||||
void MsgPackStream::resetStatus()
|
||||
{
|
||||
q_status = Ok;
|
||||
}
|
||||
|
||||
void MsgPackStream::setStatus(Status status)
|
||||
{
|
||||
q_status = status;
|
||||
}
|
||||
|
||||
MsgPackStream &MsgPackStream::operator >>(quint8 &u8)
|
||||
{
|
||||
u8 = 0;
|
||||
CHECK_STREAM_PRECOND(*this)
|
||||
char c;
|
||||
if (!dev->getChar(&c))
|
||||
setStatus(ReadPastEnd);
|
||||
else
|
||||
u8 = quint8(c);
|
||||
return *this;
|
||||
}
|
||||
|
49
src/stream.h
Normal file
49
src/stream.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef STREAM_H
|
||||
#define STREAM_H
|
||||
#include <QIODevice>
|
||||
|
||||
class MsgPackStream
|
||||
{
|
||||
public:
|
||||
MsgPackStream();
|
||||
MsgPackStream(QIODevice *d);
|
||||
MsgPackStream(QByteArray *a, QIODevice::OpenMode mode);
|
||||
MsgPackStream(const QByteArray &a);
|
||||
virtual ~MsgPackStream();
|
||||
|
||||
void setDevice(QIODevice *d);
|
||||
QIODevice *device() const;
|
||||
bool atEnd() const;
|
||||
|
||||
void setCompatibility(bool isEnabled);
|
||||
|
||||
enum Status {Ok, ReadPastEnd, ReadCorruptData, WriteFailed};
|
||||
Status status() const;
|
||||
void resetStatus();
|
||||
void setStatus(Status status);
|
||||
|
||||
MsgPackStream &operator>>(bool &b);
|
||||
MsgPackStream &operator>>(quint8 &u8);
|
||||
MsgPackStream &operator>>(quint16 &u16);
|
||||
MsgPackStream &operator>>(quint32 &u32);
|
||||
MsgPackStream &operator>>(quint64 &u64);
|
||||
MsgPackStream &operator>>(qint8 &i8);
|
||||
MsgPackStream &operator>>(qint16 &i16);
|
||||
MsgPackStream &operator>>(qint32 &i32);
|
||||
MsgPackStream &operator>>(qint64 &i64);
|
||||
MsgPackStream &operator>>(float &f);
|
||||
MsgPackStream &operator>>(double &d);
|
||||
MsgPackStream &operator>>(QString &str);
|
||||
MsgPackStream &operator>>(QByteArray &array);
|
||||
MsgPackStream &operator>>(QVariantList &list);
|
||||
MsgPackStream &operator>>(QVariantMap &map);
|
||||
|
||||
|
||||
private:
|
||||
QIODevice *dev;
|
||||
bool compatibility;
|
||||
bool owndev;
|
||||
Status q_status;
|
||||
};
|
||||
|
||||
#endif // STREAM_H
|
@@ -8,7 +8,7 @@ if (Qt5Core_FOUND)
|
||||
set(TEST_LIBRARIES ${Qt5Test_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
set(TEST_SUBDIRS pack unpack mixed qttypes ext)
|
||||
set(TEST_SUBDIRS pack unpack mixed qttypes)
|
||||
|
||||
foreach(subdir ${TEST_SUBDIRS})
|
||||
add_subdirectory(${subdir})
|
||||
|
@@ -1,24 +0,0 @@
|
||||
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()
|
@@ -1,149 +0,0 @@
|
||||
#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"
|
Reference in New Issue
Block a user