diff --git a/main.cpp b/main.cpp index 5580da3..ab84625 100644 --- a/main.cpp +++ b/main.cpp @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) QCoreApplication a(argc, argv); qDebug() << "MsgPack"; - qDebug() << MsgPack::deserialize(QByteArray::fromHex("fffeece1e0")); + qDebug() << MsgPack::deserialize(QByteArray::fromHex("92cd0100cd0200")); return a.exec(); } diff --git a/msgpack.cpp b/msgpack.cpp index 1ff2eb6..4b19a32 100644 --- a/msgpack.cpp +++ b/msgpack.cpp @@ -1,29 +1,14 @@ #include "msgpack.h" #include +#include "private/msgpack_p.h" -QVariantList MsgPack::deserialize(const QByteArray &data) +QVariant MsgPack::deserialize(const QByteArray &data) { - QVariantList d; - int i = 0; - quint8 *p = (quint8 *)data.data(); - while (i < data.size()) { - if (p[i] <= 127) { // positive fixint 0x00 - 0x7f - quint32 val = (quint32)p[i]; - d.append(QVariant(val)); - i += 1; - } - if (p[i] >= 0xe0) { // negative fixint 0xe0 - 0xff - quint8 val8 = (quint8)p[i]; - val8 &= ~((1 << 7) | (1 << 6) | (1 << 5)); - qint32 val = 31 - val8; - val ^= 0xffffffff; - d.append(QVariant((qint32)val)); - i += 1; - } + quint8 *end = p + data.size() - 1; + qDebug() << "deserialize size:" << data.size(); + MsgPackPrivate::unpack(p, end); - } - - return d; + return MsgPackPrivate::unpack(p, end); } diff --git a/msgpack.h b/msgpack.h index 635a0dc..5e8e23c 100644 --- a/msgpack.h +++ b/msgpack.h @@ -6,7 +6,7 @@ namespace MsgPack { - QVariantList deserialize(const QByteArray &data); + QVariant deserialize(const QByteArray &data); } #endif // MSGPACK_H diff --git a/private/msgpack_p.cpp b/private/msgpack_p.cpp index 097438a..851e036 100644 --- a/private/msgpack_p.cpp +++ b/private/msgpack_p.cpp @@ -1,6 +1,286 @@ #include "msgpack_p.h" +#include -static quint8 MsgPackPrivate::data_sizes[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // fixmap upto 15 elements - +MsgPackPrivate::type_parser_f MsgPackPrivate::parsers[32] = { + unpack_nil, + unpack_never_used, + unpack_false, unpack_true, + unpack_bin8, unpack_bin16, unpack_bin32, + unpack_ext8, unpack_ext16, unpack_ext32, + unpack_float32, unpack_float64, + unpack_uint8, unpack_uint16, unpack_uint32, unpack_uint64, + unpack_int8, unpack_int16, unpack_int32, unpack_int64, + unpack_fixext1, unpack_fixext2, unpack_fixext4, unpack_fixext8, unpack_fixext16, + unpack_str8, unpack_str16, unpack_str32, + unpack_array16, unpack_array32, + unpack_map16, unpack_map32 }; + +QVariant MsgPackPrivate::unpack(quint8 *p, quint8 *end) +{ + QVariantList d; + int typesz = 0; + + while (p <= end) { + typesz = 0; + d.append(unpack_type(p, end, typesz)); + p += typesz; + //qDebug() << "unpack typesz:" << typesz; + } + + if (p - end > 1) + return QVariant(); + + if (d.length() == 1) + return d[0]; + return d; +} + +QVariant MsgPackPrivate::unpack_type(quint8 *p, quint8 *end, int &sz) +{ + QVariant d; + + if (*p <= 127) { // positive fixint 0x00 - 0x7f + d = unpack_positive_fixint(p, end, sz); + } else if (*p >= 0xe0) { // negative fixint 0xe0 - 0xff + d = unpack_negative_fixint(p, end, sz); + } else if (*p >= 0x80 && *p <= 0x8f) { // fixmap 1000xxxx 0x80 - 0x8f + d = unpack_fixmap(p, end, sz); + } else if (*p >= 0x90 && *p <= 0x9f) { // fixarray 1001xxxx 0x90 - 0x9f + d = unpack_fixarray(p, end, sz); + } else if (*p >= 0xa0 && *p <= 0xbf) { // fixstr 101xxxxx 0xa0 - 0xbf + d = unpack_fixstr(p, end, sz); + } else { // all other types + d = (parsers[*p - 0xc0])(p, end, sz); + } + + //qDebug() << "unpack type res:" << d << sz; + return d; +} + +QVariant MsgPackPrivate::unpack_positive_fixint(quint8 *p, quint8 *end, int &sz) +{ + Q_UNUSED(end) + quint32 val = (quint32)*p; + sz = 1; + return QVariant(val); +} + +QVariant MsgPackPrivate::unpack_negative_fixint(quint8 *p, quint8 *end, int &sz) +{ + Q_UNUSED(end) + quint8 val8 = (quint8)*p; + val8 &= ~((1 << 7) | (1 << 6) | (1 << 5)); + qint32 val = 31 - val8; + val ^= 0xffffffff; + sz = 1; + return QVariant(val); +} + +QVariant MsgPackPrivate::unpack_fixmap(quint8 *p, quint8 *end, int &sz) +{ + Q_UNUSED(end) +} + +QVariant MsgPackPrivate::unpack_fixarray(quint8 *p, quint8 *end, int &sz) +{ + int len = (*p++) & 0x0f; // 0b00001111 + sz++; + + int elemsz = 0; + QVariantList arr; + + for (int i = 0; i < len; ++i) { + elemsz = 0; + arr.append(unpack_type(p, end, elemsz)); + p += elemsz; + sz += elemsz; + } +//qDebug() << "unpack_fixarray len:" << len << arr << sz; + return arr; +} + +QVariant MsgPackPrivate::unpack_fixstr(quint8 *p, quint8 *end, int &sz) +{ + Q_UNUSED(end) + int len = (*p) & 0x1f; // 0b00011111 + QString str = QString::fromUtf8((char*)(p + 1), len); + sz = len + 1; + return QVariant(str); +} + +QVariant MsgPackPrivate::unpack_nil(quint8 *p, quint8 *end, int &sz) +{ + Q_UNUSED(end) + sz = 1; + return QVariant(0); +} + +QVariant MsgPackPrivate::unpack_never_used(quint8 *p, quint8 *end, int &sz) +{ + Q_UNUSED(end) + sz = 1; + return QVariant(); +} + +QVariant MsgPackPrivate::unpack_false(quint8 *p, quint8 *end, int &sz) +{ + sz = 1; + return QVariant(false); +} + +QVariant MsgPackPrivate::unpack_true(quint8 *p, quint8 *end, int &sz) +{ + sz = 1; + return QVariant(true); +} + +QVariant MsgPackPrivate::unpack_bin8(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_bin16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_bin32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_ext8(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_ext16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_ext32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_float32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_float64(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_uint8(quint8 *p, quint8 *end, int &sz) +{ + quint32 val; + val = *(++p); + sz = 2; + return val; +} + +QVariant MsgPackPrivate::unpack_uint16(quint8 *p, quint8 *end, int &sz) +{ + quint32 val; + val = *(++p); + val |= *(++p) << 8; + sz = 3; + return val; +} + +QVariant MsgPackPrivate::unpack_uint32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_uint64(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_int8(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_int16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_int32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_int64(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_fixext1(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_fixext2(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_fixext4(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_fixext8(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_fixext16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_str8(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_str16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_str32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_array16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_array32(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_map16(quint8 *p, quint8 *end, int &sz) +{ + +} + +QVariant MsgPackPrivate::unpack_map32(quint8 *p, quint8 *end, int &sz) +{ + +} + + + diff --git a/private/msgpack_p.h b/private/msgpack_p.h index 02ce193..dacbb3c 100644 --- a/private/msgpack_p.h +++ b/private/msgpack_p.h @@ -5,29 +5,52 @@ /* parser functions: * QVariant _type_(quint8 *p, int &i); * parses some type, which data is stored at p - * + * fill sz with type size */ namespace MsgPackPrivate { -/* data sizes for types from 0x7f to 0xe0 - * (without positive and negative fixint) - ** fixed size types: - * possible values: 1, 2, 3, 4, 5, 6, 9, 10, 18 - bytes - * 254 - size is in next 1 byte - * 253 - 2 - * 251 - 4 - ** ext formats: - * 126 - size is in next byte + 1 type byte - * 125 - 2 byte size + 1 type byte - * 123 - 4 byte size + 1 type byte - */ - - static quint8 data_sizes[96]; - - QVariant positive_fixint(quint8 *p); - - +typedef QVariant (* type_parser_f)(quint8 *p, quint8 *end, int &sz); +extern type_parser_f parsers[32]; +QVariant unpack(quint8 *p, quint8 *end); +QVariant unpack_type(quint8 *p, quint8 *end, int &sz); +QVariant unpack_positive_fixint(quint8 *p, quint8 *end, int &sz); +QVariant unpack_negative_fixint(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixmap(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixarray(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixstr(quint8 *p, quint8 *end, int &sz); +QVariant unpack_nil(quint8 *p, quint8 *end, int &sz); +QVariant unpack_never_used(quint8 *p, quint8 *end, int &sz); +QVariant unpack_false(quint8 *p, quint8 *end, int &sz); +QVariant unpack_true(quint8 *p, quint8 *end, int &sz); +QVariant unpack_bin8(quint8 *p, quint8 *end, int &sz); +QVariant unpack_bin16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_bin32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_ext8(quint8 *p, quint8 *end, int &sz); +QVariant unpack_ext16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_ext32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_float32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_float64(quint8 *p, quint8 *end, int &sz); +QVariant unpack_uint8(quint8 *p, quint8 *end, int &sz); +QVariant unpack_uint16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_uint32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_uint64(quint8 *p, quint8 *end, int &sz); +QVariant unpack_int8(quint8 *p, quint8 *end, int &sz); +QVariant unpack_int16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_int32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_int64(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixext1(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixext2(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixext4(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixext8(quint8 *p, quint8 *end, int &sz); +QVariant unpack_fixext16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_str8(quint8 *p, quint8 *end, int &sz); +QVariant unpack_str16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_str32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_array16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_array32(quint8 *p, quint8 *end, int &sz); +QVariant unpack_map16(quint8 *p, quint8 *end, int &sz); +QVariant unpack_map32(quint8 *p, quint8 *end, int &sz); } #endif // MSGPACK_P_H diff --git a/qmsgpack.pro.user b/qmsgpack.pro.user new file mode 100644 index 0000000..e3da53a --- /dev/null +++ b/qmsgpack.pro.user @@ -0,0 +1,263 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.3 GCC 64bit + Desktop Qt 5.3 GCC 64bit + qt.53.gcc_64_kit + 0 + 0 + 0 + + /home/roman/build/build-qmsgpack-Desktop_Qt_5_3_GCC_64bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/roman/build/build-qmsgpack-Desktop_Qt_5_3_GCC_64bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + qmsgpack + + Qt4ProjectManager.Qt4RunConfiguration:/home/roman/git/msgpack-qt/qmsgpack.pro + + qmsgpack.pro + false + false + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {478d7604-9791-49cc-a5a5-2eb4eeaa05bd} + + + ProjectExplorer.Project.Updater.FileVersion + 15 + +