diff --git a/main.cpp b/main.cpp index ab84625..7594430 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("92cd0100cd0200")); + qDebug() << MsgPack::deserialize(QByteArray::fromHex("c403010203")); return a.exec(); } diff --git a/msgpack-qt.pro.user b/msgpack-qt.pro.user new file mode 100644 index 0000000..b1032d6 --- /dev/null +++ b/msgpack-qt.pro.user @@ -0,0 +1,233 @@ + + + + + + EnvironmentId + {293bfe28-51d8-4f1a-a70e-1e515004ec8c} + + + 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-msgpack-qt-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-msgpack-qt-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 + + + 2 + + msgpack-qt + + Qt4ProjectManager.Qt4RunConfiguration:/home/roman/git/msgpack-qt/msgpack-qt.pro + + msgpack-qt.pro + false + false + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 16 + + + Version + 16 + + diff --git a/msgpack.cpp b/msgpack.cpp index 4b19a32..05949a0 100644 --- a/msgpack.cpp +++ b/msgpack.cpp @@ -6,9 +6,7 @@ QVariant MsgPack::deserialize(const QByteArray &data) { quint8 *p = (quint8 *)data.data(); quint8 *end = p + data.size() - 1; - qDebug() << "deserialize size:" << data.size(); - - MsgPackPrivate::unpack(p, end); + //qDebug() << "deserialize size:" << data.size(); return MsgPackPrivate::unpack(p, end); } diff --git a/private/msgpack_p.cpp b/private/msgpack_p.cpp index 851e036..bb1bf96 100644 --- a/private/msgpack_p.cpp +++ b/private/msgpack_p.cpp @@ -1,7 +1,7 @@ #include "msgpack_p.h" #include -MsgPackPrivate::type_parser_f MsgPackPrivate::parsers[32] = { +MsgPackPrivate::type_parser_f MsgPackPrivate::unpackers[32] = { unpack_nil, unpack_never_used, unpack_false, unpack_true, @@ -23,9 +23,8 @@ QVariant MsgPackPrivate::unpack(quint8 *p, quint8 *end) while (p <= end) { typesz = 0; - d.append(unpack_type(p, end, typesz)); + d.append(unpack_type(p, typesz)); p += typesz; - //qDebug() << "unpack typesz:" << typesz; } if (p - end > 1) @@ -36,251 +35,323 @@ QVariant MsgPackPrivate::unpack(quint8 *p, quint8 *end) return d; } -QVariant MsgPackPrivate::unpack_type(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_type(quint8 *p, int &sz) { QVariant d; if (*p <= 127) { // positive fixint 0x00 - 0x7f - d = unpack_positive_fixint(p, end, sz); + d = unpack_positive_fixint(p, sz); } else if (*p >= 0xe0) { // negative fixint 0xe0 - 0xff - d = unpack_negative_fixint(p, end, sz); + d = unpack_negative_fixint(p, sz); } else if (*p >= 0x80 && *p <= 0x8f) { // fixmap 1000xxxx 0x80 - 0x8f - d = unpack_fixmap(p, end, sz); + d = unpack_fixmap(p, sz); } else if (*p >= 0x90 && *p <= 0x9f) { // fixarray 1001xxxx 0x90 - 0x9f - d = unpack_fixarray(p, end, sz); + d = unpack_fixarray(p, sz); } else if (*p >= 0xa0 && *p <= 0xbf) { // fixstr 101xxxxx 0xa0 - 0xbf - d = unpack_fixstr(p, end, sz); + d = unpack_fixstr(p, sz); } else { // all other types - d = (parsers[*p - 0xc0])(p, end, sz); + d = (unpackers[*p - 0xc0])(p, sz); } //qDebug() << "unpack type res:" << d << sz; return d; } -QVariant MsgPackPrivate::unpack_positive_fixint(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_positive_fixint(quint8 *p, int &sz) { - Q_UNUSED(end) quint32 val = (quint32)*p; sz = 1; - return QVariant(val); + return val; } -QVariant MsgPackPrivate::unpack_negative_fixint(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_negative_fixint(quint8 *p, int &sz) { - Q_UNUSED(end) quint8 val8 = (quint8)*p; val8 &= ~((1 << 7) | (1 << 6) | (1 << 5)); - qint32 val = 31 - val8; - val ^= 0xffffffff; + qint32 val = 0xffffffff; + val &= (0xffffffe0 | val8); sz = 1; - return QVariant(val); + return val; } -QVariant MsgPackPrivate::unpack_fixmap(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_fixmap(quint8 *p, int &sz) { - Q_UNUSED(end) + } -QVariant MsgPackPrivate::unpack_fixarray(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_array_len(quint8 *p, int &sz, int len) { - 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)); + arr.append(unpack_type(p, elemsz)); p += elemsz; sz += elemsz; } -//qDebug() << "unpack_fixarray len:" << len << arr << sz; return arr; } -QVariant MsgPackPrivate::unpack_fixstr(quint8 *p, quint8 *end, int &sz) +quint32 MsgPackPrivate::unpack_uint8(quint8 *p) +{ + return *p; +} + + +quint32 MsgPackPrivate::unpack_uint16(quint8 *p) +{ + quint32 val = 0; + quint8 *pv = (quint8 *)&val; + pv[1] = *(p); pv[0] = *(++p); + return val; +} + + +quint32 MsgPackPrivate::unpack_uint32(quint8 *p) +{ + quint32 val = 0; + quint8 *pv = (quint8 *)&val; + pv[3] = *(p); pv[2] = *(++p); + pv[1] = *(++p); pv[0] = *(++p); + return val; +} + +QVariant MsgPackPrivate::unpack_fixarray(quint8 *p, int &sz) +{ + int len = (*p++) & 0x0f; // 0b00001111 + sz++; + + return unpack_array_len(p, sz, len); +} + +QVariant MsgPackPrivate::unpack_fixstr(quint8 *p, 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) +QVariant MsgPackPrivate::unpack_nil(quint8 *p, int &sz) { - Q_UNUSED(end) + Q_UNUSED(p) sz = 1; - return QVariant(0); + return 0; } -QVariant MsgPackPrivate::unpack_never_used(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_never_used(quint8 *p, int &sz) { - Q_UNUSED(end) + Q_UNUSED(p) sz = 1; return QVariant(); } -QVariant MsgPackPrivate::unpack_false(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_false(quint8 *p, int &sz) { + Q_UNUSED(p) sz = 1; - return QVariant(false); + return false; } -QVariant MsgPackPrivate::unpack_true(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_true(quint8 *p, int &sz) { + Q_UNUSED(p) sz = 1; - return QVariant(true); + return true; } -QVariant MsgPackPrivate::unpack_bin8(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_bin8(quint8 *p, int &sz) +{ + quint32 len = unpack_uint8(++p); + QByteArray arr((const char *)(++p), len); + sz = len + 2; + return arr; +} + +QVariant MsgPackPrivate::unpack_bin16(quint8 *p, int &sz) +{ + quint32 len = unpack_uint16(++p); + QByteArray arr((const char *)(++p), len); + sz = len + 2; + return arr; +} + +QVariant MsgPackPrivate::unpack_bin32(quint8 *p, int &sz) +{ + quint32 len = unpack_uint32(++p); + QByteArray arr((const char *)(++p), len); + sz = len + 2; + return arr; +} + +QVariant MsgPackPrivate::unpack_ext8(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_bin16(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_ext16(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_bin32(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_ext32(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_ext8(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_float32(quint8 *p, int &sz) { - + float val = 0; + quint8 *vp = ( (quint8 *)&val ) + 3; + for (int i = 0; i < 4; ++i) + *(vp--) = *(++p); + sz = 5; + return val; } -QVariant MsgPackPrivate::unpack_ext16(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_float64(quint8 *p, int &sz) { - + double val = 0; + quint8 *vp = ( (quint8 *)&val ) + 7; + for (int i = 0; i < 8; ++i) + *(vp--) = *(++p); + sz = 9; + return val; } -QVariant MsgPackPrivate::unpack_ext32(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_uint8(quint8 *p, int &sz) { - + sz = 2; + return unpack_uint8(++p); } -QVariant MsgPackPrivate::unpack_float32(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_uint16(quint8 *p, int &sz) { - + sz = 3; + return unpack_uint16(++p); } -QVariant MsgPackPrivate::unpack_float64(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_uint32(quint8 *p, int &sz) { - + sz = 5; + return unpack_uint32(++p); } -QVariant MsgPackPrivate::unpack_uint8(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_uint64(quint8 *p, int &sz) { - quint32 val; - val = *(++p); + quint64 val = 0; + for (int i = 56; i >= 0; i -= 8) + val |= (quint64)(*(++p)) << i; + sz = 9; + return val; +} + +QVariant MsgPackPrivate::unpack_int8(quint8 *p, int &sz) +{ + qint32 val = 0xffffff00; + val |= *(++p); sz = 2; return val; } -QVariant MsgPackPrivate::unpack_uint16(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_int16(quint8 *p, int &sz) { - quint32 val; - val = *(++p); - val |= *(++p) << 8; + qint32 val = 0xffff0000; + quint8 *pv = (quint8 *)&val; + pv[1] = *(++p); pv[0] = *(++p); sz = 3; return val; } -QVariant MsgPackPrivate::unpack_uint32(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_int32(quint8 *p, int &sz) +{ + qint32 val = 0; + quint8 *pv = (quint8 *)&val; + pv[3] = *(++p); pv[2] = *(++p); + pv[1] = *(++p); pv[0] = *(++p); + sz = 5; + return val; +} + +QVariant MsgPackPrivate::unpack_int64(quint8 *p, int &sz) +{ + qint64 val = 0; + for (int i = 56; i >= 0; i -= 8) + val |= (quint64)(*(++p)) << i; + sz = 9; + return val; +} + +QVariant MsgPackPrivate::unpack_fixext1(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_uint64(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_fixext2(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_int8(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_fixext4(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_int16(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_fixext8(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_int32(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_fixext16(quint8 *p, int &sz) { } -QVariant MsgPackPrivate::unpack_int64(quint8 *p, quint8 *end, int &sz) +QVariant MsgPackPrivate::unpack_str8(quint8 *p, int &sz) +{ + quint32 len = unpack_uint8(++p); + QString str = QString::fromUtf8((char*)(p + 1), len); + sz = len + 1; + return QVariant(str); +} + +QVariant MsgPackPrivate::unpack_str16(quint8 *p, int &sz) +{ + quint32 len = unpack_uint16(++p); + QString str = QString::fromUtf8((char*)(p + 1), len); + sz = len + 1; + return QVariant(str); +} + +QVariant MsgPackPrivate::unpack_str32(quint8 *p, int &sz) +{ + quint32 len = unpack_uint32(++p); + QString str = QString::fromUtf8((char*)(p + 1), len); + sz = len + 1; + return QVariant(str); +} + +QVariant MsgPackPrivate::unpack_array16(quint8 *p, int &sz) +{ + quint32 len = unpack_uint16(++p); + return unpack_array_len(p, sz, len); +} + +QVariant MsgPackPrivate::unpack_array32(quint8 *p, int &sz) +{ + quint32 len = unpack_uint32(++p); + return unpack_array_len(p, sz, len); +} + +QVariant MsgPackPrivate::unpack_map16(quint8 *p, 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) +QVariant MsgPackPrivate::unpack_map32(quint8 *p, int &sz) { } - diff --git a/private/msgpack_p.h b/private/msgpack_p.h index dacbb3c..e6ae808 100644 --- a/private/msgpack_p.h +++ b/private/msgpack_p.h @@ -2,55 +2,67 @@ #define MSGPACK_P_H #include -/* parser functions: - * QVariant _type_(quint8 *p, int &i); - * parses some type, which data is stored at p - * fill sz with type size - */ + namespace MsgPackPrivate { -typedef QVariant (* type_parser_f)(quint8 *p, quint8 *end, int &sz); -extern type_parser_f parsers[32]; +/* unpack functions: + * QVariant _type_(quint8 *p, int &sz); + * parses some type, which data is stored at p + * fill sz with type size (sz is there at the moment of calling + * parser function) + */ +typedef QVariant (* type_parser_f)(quint8 *p, int &sz); +extern type_parser_f unpackers[32]; + +// goes from p to end unpacking types with unpack_type function below 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); +// unpack some type, can be called recursively from other unpack functions +QVariant unpack_type(quint8 *p, int &sz); + +QVariant unpack_array_len(quint8 *p, int &sz, int len); +quint32 unpack_uint8(quint8 *p); +quint32 unpack_uint16(quint8 *p); +quint32 unpack_uint32(quint8 *p); + + +QVariant unpack_positive_fixint(quint8 *p, int &sz); +QVariant unpack_negative_fixint(quint8 *p, int &sz); +QVariant unpack_fixmap(quint8 *p, int &sz); +QVariant unpack_fixarray(quint8 *p, int &sz); +QVariant unpack_fixstr(quint8 *p, int &sz); +QVariant unpack_nil(quint8 *p, int &sz); +QVariant unpack_never_used(quint8 *p, int &sz); +QVariant unpack_false(quint8 *p, int &sz); +QVariant unpack_true(quint8 *p, int &sz); +QVariant unpack_bin8(quint8 *p, int &sz); +QVariant unpack_bin16(quint8 *p, int &sz); +QVariant unpack_bin32(quint8 *p, int &sz); +QVariant unpack_ext8(quint8 *p, int &sz); +QVariant unpack_ext16(quint8 *p, int &sz); +QVariant unpack_ext32(quint8 *p, int &sz); +QVariant unpack_float32(quint8 *p, int &sz); +QVariant unpack_float64(quint8 *p, int &sz); +QVariant unpack_uint8(quint8 *p, int &sz); +QVariant unpack_uint16(quint8 *p, int &sz); +QVariant unpack_uint32(quint8 *p, int &sz); +QVariant unpack_uint64(quint8 *p, int &sz); +QVariant unpack_int8(quint8 *p, int &sz); +QVariant unpack_int16(quint8 *p, int &sz); +QVariant unpack_int32(quint8 *p, int &sz); +QVariant unpack_int64(quint8 *p, int &sz); +QVariant unpack_fixext1(quint8 *p, int &sz); +QVariant unpack_fixext2(quint8 *p, int &sz); +QVariant unpack_fixext4(quint8 *p, int &sz); +QVariant unpack_fixext8(quint8 *p, int &sz); +QVariant unpack_fixext16(quint8 *p, int &sz); +QVariant unpack_str8(quint8 *p, int &sz); +QVariant unpack_str16(quint8 *p, int &sz); +QVariant unpack_str32(quint8 *p, int &sz); +QVariant unpack_array16(quint8 *p, int &sz); +QVariant unpack_array32(quint8 *p, int &sz); +QVariant unpack_map16(quint8 *p, int &sz); +QVariant unpack_map32(quint8 *p, int &sz); } #endif // MSGPACK_P_H