Started work on MsgPackStream

This commit is contained in:
Roman
2015-05-02 00:06:35 +03:00
parent 3b0d6e3c31
commit 1ae96715cf
9 changed files with 154 additions and 344 deletions

View File

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

View File

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

View File

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

View File

@@ -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
View 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
View 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

View File

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

View File

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

View File

@@ -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"