some bug fixes (++ optimized out)

This commit is contained in:
Roman
2014-09-24 22:18:37 +04:00
parent 1ee73e8cf8
commit 93f45f9b0b
7 changed files with 27 additions and 982 deletions

View File

@ -1,307 +0,0 @@
#include "pack_p.h"
#include "private/sysdep.h"
#include <QDebug>
QHash<QMetaType::Type, MsgPackPrivate::packer_t> MsgPackPrivate::user_packers;
quint8 *MsgPackPrivate::pack(const QVariant &v, quint8 *p, bool wr)
{
QMetaType::Type t = (QMetaType::Type)v.type();
if (t == QMetaType::Int)
p = pack_int(v.toInt(), p, wr);
else if (t == QMetaType::UInt)
p = pack_uint(v.toInt(), p, wr);
else if (t == QMetaType::Bool)
p = pack_bool(v, p, wr);
else if (t == QMetaType::QString)
p = pack_string(v.toString(), p, wr);
else if (t == QMetaType::QVariantList)
p = pack_list(v.toList(), p, wr);
else if (t == QMetaType::LongLong)
p = pack_longlong(v.toLongLong(), p, wr);
else if (t == QMetaType::ULongLong)
p = pack_ulonglong(v.toULongLong(), p, wr);
else if (t == QMetaType::Double)
p = pack_double(v.toDouble(), p, wr);
else if (t == QMetaType::QByteArray)
p = pack_array(v.toByteArray(), p, wr);
else if (t == QMetaType::QVariantMap)
p = pack_map(v.toMap(), p, wr);
else {
if (user_packers.contains(t))
p = pack_user(v, p, wr);
else
qWarning() << "MsgPack::pack can't pack type:" << t;
}
return p;
}
quint8 *MsgPackPrivate::pack_int(qint32 i, quint8 *p, bool wr)
{
if (i >= -32 && i <= 127) {
qint32 val = _msgpack_be32(i);
if (wr) *p = *( (quint8 *)&val + 3 );
p++;
} else if (i >= -128 && i <= 255) {
if (wr) *p = i > 0 ? 0xcc : 0xd0;
p++;
if (wr) *p = i;
p++;
} else if (i >= -32768 && i <= 65535) {
if (wr) *p = i > 0 ? 0xcd : 0xd1;
p++;
if (wr) _msgpack_store16(p, i);
p += 2;
} else {
if (wr) *p = i > 0 ? 0xce : 0xd2;
p++;
if (wr) _msgpack_store32(p, i);
p += 4;
}
return p;
}
quint8 *MsgPackPrivate::pack_uint(quint32 i, quint8 *p, bool wr)
{
if (i <= 127) {
qint32 val = _msgpack_be32(i);
if (wr) *p = *( (quint8 *)&val + 3 );
p++;
} else if (i <= 255) {
if (wr) *p = 0xcc;
p++;
if (wr) *p = i;
p++;
} else if (i <= 65535) {
if (wr) *p = 0xcd;
p++;
if (wr) _msgpack_store16(p, i);
p += 2;
} else {
if (wr) *p = 0xce;
p++;
if (wr) _msgpack_store32(p, i);
p += 4;
}
return p;
}
quint8 *MsgPackPrivate::pack_longlong(qint64 i, quint8 *p, bool wr)
{
if (i >= -2147483648 && i <= 2147483647)
return p = pack_int(i, p, wr);
if (wr) *p = 0xd3;
p++;
if (wr) _msgpack_store64(p, i);
return p += 8;
}
quint8 *MsgPackPrivate::pack_ulonglong(quint64 i, quint8 *p, bool wr)
{
if (i <= 4294967295)
return pack_uint(i, p, wr);
if (wr) *p = 0xcf;
p++;
if (wr) _msgpack_store64(p, i);
return p += 8;
}
quint8 *MsgPackPrivate::pack_bool(const QVariant &v, quint8 *p, bool wr)
{
if (wr)
*p = v.toBool() ? 0xc3 : 0xc2;
return p + 1;
}
quint8 *MsgPackPrivate::pack_list(const QVariantList &list, quint8 *p, bool wr)
{
int len = list.length();
if (len <= 15) {
if (wr) *p = 0x90 | len;
p++;
} else {
if (len <= 65535) {
if (wr) *p = 0xdc;
p++;
_msgpack_store16(p, len);
p += 2;
} else {
if (wr) *p = 0xdd;
p++;
_msgpack_store32(p, len);
p += 4;
}
}
foreach (QVariant item, list)
p = pack(item, p, wr);
return p;
}
quint8 *MsgPackPrivate::pack_string(const QString &str, quint8 *p, bool wr)
{
int len = str.length();
if (len <= 31) {
if (wr) *p = 0xa0 | len;
p++;
} else if (len <= 255) {
if (wr) *p = 0xd9;
p++;
if (wr) *p = len;
p++;
} else if (len <= 65535) {
if (wr) *p = 0xda;
p++;
if (wr) _msgpack_store16(p, len);
p += 2;
} else {
if (wr) *p = 0xdb;
p++;
if (wr) _msgpack_store32(p, len);
p += 4;
}
if (wr) memcpy(p, str.toUtf8().data(), len);
p += len;
return p;
}
quint8 *MsgPackPrivate::pack_double(double i, quint8 *p, bool wr)
{
if (wr) *p = 0xcb;
p++;
if (wr) {
quint8 *d = (quint8 *)&i;
#ifdef __LITTLE_ENDIAN__
for (int i = 0; i < 8; ++i)
*(p + 7 - i) = *(d + i);
#else
for (int i = 0; i < 8; ++i)
*(p + i) = *(d + i);
#endif
}
return p += 8;
}
quint8 *MsgPackPrivate::pack_array(const QByteArray &arr, quint8 *p, bool wr)
{
int len = arr.length();
if (len <= 255) {
if (wr) *p = 0xc4;
p++;
if (wr) *p = len;
p++;
} else if (len <= 65535) {
if (wr) *p = 0xc5;
p++;
if (wr) _msgpack_store16(p, len);
p += 2;
} else {
if (wr) *p = 0xc6;
p++;
if (wr) _msgpack_store32(p, len);
p += 4;
}
if (wr) memcpy(p, arr.data(), len);
p += len;
return p;
}
quint8 *MsgPackPrivate::pack_map(const QVariantMap &map, quint8 *p, bool wr)
{
QMapIterator<QString, QVariant> it(map);
int len = 0;
while (it.hasNext()) {
it.next();
len++;
}
if (len <= 15) {
if (wr) *p = 0x80 | len;
p++;
} else if (len <= 65535) {
if (wr) *p = 0xde;
p++;
if (wr) _msgpack_store16(p, len);
p += 2;
} else {
if (wr) *p = 0xdf;
p++;
if (wr) _msgpack_store32(p, len);
p += 4;
}
it.toFront();
while (it.hasNext()) {
it.next();
p = pack(it.key(), p, wr);
p = pack(it.value(), p, wr);
}
return p;
}
bool MsgPackPrivate::register_packer(QMetaType::Type q_type, qint8 msgpack_type, MsgPack::pack_user_f packer)
{
if (user_packers.contains(q_type)) {
qWarning() << "MsgPack::packer for qtype" << q_type << "already exist";
return false;
}
if (packer == 0) {
qWarning() << "MsgPack::packer for qtype" << q_type << "is invalid";
return false;
}
packer_t p;
p.packer = packer;
p.type = msgpack_type;
user_packers.insert(q_type, p);
return true;
}
quint8 *MsgPackPrivate::pack_user(const QVariant &v, quint8 *p, bool wr)
{
QMetaType::Type t = (QMetaType::Type)v.type() == QMetaType::User ?
(QMetaType::Type)v.userType() : (QMetaType::Type)v.type();
QByteArray data;
packer_t pt = user_packers[t];
quint32 len = pt.packer(v, data, wr);
if (len == 1) {
if (wr) *p = 0xd4;
p++;
} else if (len == 2) {
if (wr) *p = 0xd5;
p++;
} else if (len == 4) {
if (wr) *p = 0xd6;
p++;
} else if (len == 8) {
if (wr) *p = 0xd7;
p++;
} else if (len == 16) {
if (wr) *p = 0xd8;
p++;
} else if (len <= 255) {
if (wr) *p = 0xc7;
p++;
if (wr) *p = len;
p++;
} else if (len <= 65535) {
if (wr) *p = 0xc8;
p++;
if (wr) _msgpack_store16(p, len);
p += 2;
} else {
if (wr) *p = 0xc9;
p++;
if (wr) _msgpack_store32(p, len);
p += 4;
}
if (wr) *p = pt.type;
p++;
if (wr)
memcpy(p, data.data(), len);
return p += len;
}

View File

@ -1,36 +0,0 @@
#ifndef PACK_P_H
#define PACK_P_H
#include <QVariant>
#include "../msgpack_common.h"
namespace MsgPackPrivate {
/* if wr (write) == false, packer just moves pointer forward
*
*/
typedef struct {
MsgPack::pack_user_f packer;
qint8 type;
} packer_t;
bool register_packer(QMetaType::Type q_type, qint8 msgpack_type, MsgPack::pack_user_f packer);
extern QHash<QMetaType::Type, packer_t> user_packers;
quint8 * pack(const QVariant &v, quint8 *p, bool wr);
quint8 * pack_int(qint32 i, quint8 *p, bool wr);
quint8 * pack_uint(quint32 i, quint8 *p, bool wr);
quint8 * pack_longlong(qint64 i, quint8 *p, bool wr);
quint8 * pack_ulonglong(quint64 i, quint8 *p, bool wr);
quint8 * pack_bool(const QVariant &v, quint8 *p, bool wr);
quint8 * pack_list(const QVariantList &list, quint8 *p, bool wr);
quint8 * pack_string(const QString &str, quint8 *p, bool wr);
quint8 * pack_double(double i, quint8 *p, bool wr);
quint8 * pack_array(const QByteArray &arr, quint8 *p, bool wr);
quint8 * pack_map(const QVariantMap &map, quint8 *p, bool wr);
quint8 * pack_user(const QVariant &v, quint8 *p, bool wr);
}
#endif // PACK_P_H

View File

@ -1,152 +0,0 @@
/*
* MessagePack system dependencies
*
* Copyright (C) 2008-2010 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_SYSDEP_H__
#define MSGPACK_SYSDEP_H__
#include <qglobal.h>
#ifndef _WIN32
#include <arpa/inet.h> /* __BYTE_ORDER */
#endif
#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define __LITTLE_ENDIAN__
#elif __BYTE_ORDER == __BIG_ENDIAN
#define __BIG_ENDIAN__
#elif _WIN32
#define __LITTLE_ENDIAN__
#endif
#endif
#ifdef __LITTLE_ENDIAN__
#ifdef _WIN32
# if defined(ntohs)
# define _msgpack_be16(x) ntohs(x)
# elif defined(_byteswap_ushort) || (defined(_MSC_VER) && _MSC_VER >= 1400)
# define _msgpack_be16(x) ((uint16_t)_byteswap_ushort((unsigned short)x))
# else
# define _msgpack_be16(x) ( \
((((quint16)x) << 8) ) | \
((((quint16)x) >> 8) ) )
# endif
#else
# define _msgpack_be16(x) ntohs(x)
#endif
#ifdef _WIN32
# if defined(ntohl)
# define _msgpack_be32(x) ntohl(x)
# elif defined(_byteswap_ulong) || (defined(_MSC_VER) && _MSC_VER >= 1400)
# define _msgpack_be32(x) ((uint32_t)_byteswap_ulong((unsigned long)x))
# else
# define _msgpack_be32(x) \
( ((((quint32)x) << 24) ) | \
((((quint32)x) << 8) & 0x00ff0000U ) | \
((((quint32)x) >> 8) & 0x0000ff00U ) | \
((((quint32)x) >> 24) ) )
# endif
#else
# define _msgpack_be32(x) ntohl(x)
#endif
#if defined(_byteswap_uint64) || (defined(_MSC_VER) && _MSC_VER >= 1400)
# define _msgpack_be64(x) (_byteswap_uint64(x))
#elif defined(bswap_64)
# define _msgpack_be64(x) bswap_64(x)
#elif defined(__DARWIN_OSSwapInt64)
# define _msgpack_be64(x) __DARWIN_OSSwapInt64(x)
#else
#define _msgpack_be64(x) \
( ((((quint64)x) << 56) ) | \
((((quint64)x) << 40) & 0x00ff000000000000ULL ) | \
((((quint64)x) << 24) & 0x0000ff0000000000ULL ) | \
((((quint64)x) << 8) & 0x000000ff00000000ULL ) | \
((((quint64)x) >> 8) & 0x00000000ff000000ULL ) | \
((((quint64)x) >> 24) & 0x0000000000ff0000ULL ) | \
((((quint64)x) >> 40) & 0x000000000000ff00ULL ) | \
((((quint64)x) >> 56) ) )
#endif
#define _msgpack_load16(cast, from) ((cast)( \
(((quint16)((quint8*)(from))[0]) << 8) | \
(((quint16)((quint8*)(from))[1]) ) ))
#define _msgpack_load32(cast, from) ((cast)( \
(((quint32)((quint8*)(from))[0]) << 24) | \
(((quint32)((quint8*)(from))[1]) << 16) | \
(((quint32)((quint8*)(from))[2]) << 8) | \
(((quint32)((quint8*)(from))[3]) ) ))
#define _msgpack_load64(cast, from) ((cast)( \
(((quint64)((quint8*)(from))[0]) << 56) | \
(((quint64)((quint8*)(from))[1]) << 48) | \
(((quint64)((quint8*)(from))[2]) << 40) | \
(((quint64)((quint8*)(from))[3]) << 32) | \
(((quint64)((quint8*)(from))[4]) << 24) | \
(((quint64)((quint8*)(from))[5]) << 16) | \
(((quint64)((quint8*)(from))[6]) << 8) | \
(((quint64)((quint8*)(from))[7]) ) ))
#else
#define _msgpack_be16(x) (x)
#define _msgpack_be32(x) (x)
#define _msgpack_be64(x) (x)
#define _msgpack_load16(cast, from) ((cast)( \
(((quint16)((quint8*)from)[0]) << 8) | \
(((quint16)((quint8*)from)[1]) ) ))
#define _msgpack_load32(cast, from) ((cast)( \
(((quint32)((quint8*)from)[0]) << 24) | \
(((quint32)((quint8*)from)[1]) << 16) | \
(((quint32)((quint8*)from)[2]) << 8) | \
(((quint32)((quint8*)from)[3]) ) ))
#define _msgpack_load64(cast, from) ((cast)( \
(((quint64)((quint8*)from)[0]) << 56) | \
(((quint64)((quint8*)from)[1]) << 48) | \
(((quint64)((quint8*)from)[2]) << 40) | \
(((quint64)((quint8*)from)[3]) << 32) | \
(((quint64)((quint8*)from)[4]) << 24) | \
(((quint64)((quint8*)from)[5]) << 16) | \
(((quint64)((quint8*)from)[6]) << 8) | \
(((quint64)((quint8*)from)[7]) ) ))
#endif
#define _msgpack_store16(to, num) \
do { quint16 val = _msgpack_be16(num); memcpy(to, &val, 2); } while(0)
#define _msgpack_store32(to, num) \
do { quint32 val = _msgpack_be32(num); memcpy(to, &val, 4); } while(0)
#define _msgpack_store64(to, num) \
do { quint64 val = _msgpack_be64(num); memcpy(to, &val, 8); } while(0)
/*
#define _msgpack_load16(cast, from) \
({ cast val; memcpy(&val, (char*)from, 2); _msgpack_be16(val); })
#define _msgpack_load32(cast, from) \
({ cast val; memcpy(&val, (char*)from, 4); _msgpack_be32(val); })
#define _msgpack_load64(cast, from) \
({ cast val; memcpy(&val, (char*)from, 8); _msgpack_be64(val); })
*/
#endif /* msgpack/sysdep.h */

View File

@ -1,388 +0,0 @@
#include "unpack_p.h"
#include "sysdep.h"
#include <QDebug>
MsgPackPrivate::type_parser_f MsgPackPrivate::unpackers[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
};
QHash<qint8, MsgPack::unpack_user_f> MsgPackPrivate::user_unpackers;
QVariant MsgPackPrivate::unpack(quint8 *p, quint8 *end)
{
QVariantList d;
QVariant v;
while (p <= end) {
p = unpack_type(v, p);
d.append(v);
}
if (p - end > 1)
return QVariant();
if (d.length() == 1)
return d[0];
return d;
}
quint8 *MsgPackPrivate::unpack_type(QVariant &v, quint8 *p)
{
if (*p <= 127) { // positive fixint 0x00 - 0x7f
p = unpack_positive_fixint(v, p);
} else if (*p >= 0xe0) { // negative fixint 0xe0 - 0xff
p = unpack_negative_fixint(v, p);
} else if (*p >= 0x80 && *p <= 0x8f) { // fixmap 1000xxxx 0x80 - 0x8f
p = unpack_fixmap(v, p);
} else if (*p >= 0x90 && *p <= 0x9f) { // fixarray 1001xxxx 0x90 - 0x9f
p = unpack_fixarray(v, p);
} else if (*p >= 0xa0 && *p <= 0xbf) { // fixstr 101xxxxx 0xa0 - 0xbf
p = unpack_fixstr(v, p);
} else { // all other types
p = (unpackers[*p - 0xc0])(v, p);
}
//qDebug() << "unpack type res:" << d << sz;
return p;
}
quint8 * MsgPackPrivate::unpack_nil(QVariant &v, quint8 *p)
{
Q_UNUSED(p)
Q_UNUSED(v)
return p + 1;
}
quint8 * MsgPackPrivate::unpack_never_used(QVariant &v, quint8 *p)
{
Q_UNUSED(p)
Q_UNUSED(v)
return p + 1;
}
quint8 * MsgPackPrivate::unpack_false(QVariant &v, quint8 *p)
{
Q_UNUSED(p)
v = false;
return p + 1;
}
quint8 * MsgPackPrivate::unpack_true(QVariant &v, quint8 *p)
{
Q_UNUSED(p)
v = true;
return p + 1;
}
quint8 * MsgPackPrivate::unpack_positive_fixint(QVariant &v, quint8 *p)
{
v = (quint32)*p;
return p + 1;
}
quint8 * MsgPackPrivate::unpack_negative_fixint(QVariant &v, quint8 *p)
{
v = (qint8)*p;
return p + 1;
}
quint8 * MsgPackPrivate::unpack_uint8(QVariant &v, quint8 *p)
{
v = (quint8)*(++p);
return p++;
}
quint8 * MsgPackPrivate::unpack_uint16(QVariant &v, quint8 *p)
{
p++;
v = _msgpack_load16(quint16, p);
return p + 2;
}
quint8 * MsgPackPrivate::unpack_uint32(QVariant &v, quint8 *p)
{
p++;
v = _msgpack_load32(quint32, p);
return p + 4;
}
quint8 * MsgPackPrivate::unpack_uint64(QVariant &v, quint8 *p)
{
p++;
v = _msgpack_load64(quint64, p);
return p + 8;
}
quint8 * MsgPackPrivate::unpack_int8(QVariant &v, quint8 *p)
{
v = (qint8)*(++p);
return p + 1;
}
quint8 * MsgPackPrivate::unpack_int16(QVariant &v, quint8 *p)
{
p++;
v = _msgpack_load16(qint16, p);
return p + 2;
}
quint8 * MsgPackPrivate::unpack_int32(QVariant &v, quint8 *p)
{
p++;
v = _msgpack_load32(quint32, p);
return p + 4;
}
quint8 * MsgPackPrivate::unpack_int64(QVariant &v, quint8 *p)
{
p++;
v = _msgpack_load64(qint64, p);
return p + 8;
}
quint8 * MsgPackPrivate::unpack_float32(QVariant &v, quint8 *p)
{
float f;
quint8 *fp = (quint8 *)&f;
p++;
#ifdef __LITTLE_ENDIAN__
for (int i = 0; i < 4; ++i)
*(fp + 3 - i) = *(p + i);
#else
for (int i = 0; i < 4; ++i)
*(fp + i) = *(p + i);
#endif
v = f;
return p + 4;
}
quint8 * MsgPackPrivate::unpack_float64(QVariant &v, quint8 *p)
{
double d;
quint8 *fd = (quint8 *)&d;
p++;
#ifdef __LITTLE_ENDIAN__
for (int i = 0; i < 8; ++i)
*(fd + 7 - i) = *(p + i);
#else
for (int i = 0; i < 4; ++i)
*(fp + i) = *(p + i);
#endif
v = d;
return p + 8;
}
quint8 * MsgPackPrivate::unpack_fixstr(QVariant &v, quint8 *p)
{
int len = (*p) & 0x1f; // 0b00011111
p++;
v = QString::fromUtf8((char*)p, len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_str8(QVariant &v, quint8 *p)
{
int len = *(++p);
v = QString::fromUtf8((char*)(++p), len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_str16(QVariant &v, quint8 *p)
{
p++;
int len = _msgpack_load16(int, p);
p += 2;
v = QString::fromUtf8((char*)p, len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_str32(QVariant &v, quint8 *p)
{
p++;
int len = _msgpack_load32(int, p);
p += 4;
v = QString::fromUtf8((char*)p, len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_bin8(QVariant &v, quint8 *p)
{
int len = *(++p);
v = QByteArray((char*)(++p), len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_bin16(QVariant &v, quint8 *p)
{
p++;
int len = _msgpack_load16(int, p);
p += 2;
v = QByteArray((char*)p, len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_bin32(QVariant &v, quint8 *p)
{
p++;
int len = _msgpack_load32(int, p);
p += 4;
v = QByteArray((char*)p, len);
return p + len;
}
quint8 * MsgPackPrivate::unpack_array_len(QVariant &v, quint8 *p, quint32 len)
{
QVariantList arr;
QVariant vu;
for (quint32 i = 0; i < len; ++i) {
p = unpack_type(vu, p);
arr.append(vu);
}
v = arr;
return p;
}
quint8 * MsgPackPrivate::unpack_fixarray(QVariant &v, quint8 *p)
{
quint32 len = (*p++) & 0x0f; // 0b00001111
return unpack_array_len(v, p, len);
}
quint8 * MsgPackPrivate::unpack_array16(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load16(quint32, p);
return unpack_array_len(v, p += 2, len);
}
quint8 * MsgPackPrivate::unpack_array32(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load32(quint32, p);
return unpack_array_len(v, p += 4, len);
}
quint8 * MsgPackPrivate::unpack_map_len(QVariant &v, quint8 *p, quint32 len)
{
QMap<QString, QVariant> map;
QVariant key, val;
for (quint32 i = 0; i < len; ++i) {
p = unpack_type(key, p);
p = unpack_true(val, p);
map.insert(key.toString(), val);
}
v = map;
return p;
}
quint8 * MsgPackPrivate::unpack_fixmap(QVariant &v, quint8 *p)
{
quint32 len = (*p++) & 0x0f; // 0b00001111
return unpack_map_len(v, p ,len);
}
quint8 * MsgPackPrivate::unpack_map16(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load16(quint32, p);
return unpack_map_len(v, p += 2, len);
}
quint8 * MsgPackPrivate::unpack_map32(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load32(quint32, p);
return unpack_map_len(v, p + 4, len);
}
quint8 *MsgPackPrivate::unpack_ext(QVariant &v, quint8 *p, qint8 type, quint32 len)
{
if (!user_unpackers.contains(type)) {
qWarning() << "MsgPack::unpack() unpacker for type" << type << "doesn't exist";
return p + len;
}
QByteArray data((char *)p, len);
v = user_unpackers[type](data);
return p + len;
}
quint8 * MsgPackPrivate::unpack_fixext1(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
return unpack_ext(v, p + 1, type, 1);
}
quint8 * MsgPackPrivate::unpack_fixext2(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
return unpack_ext(v, p + 1, type, 2);
}
quint8 * MsgPackPrivate::unpack_fixext4(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
return unpack_ext(v, p + 1, type, 4);
}
quint8 * MsgPackPrivate::unpack_fixext8(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
return unpack_ext(v, p + 1, type, 8);
}
quint8 * MsgPackPrivate::unpack_fixext16(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
return unpack_ext(v, p + 1, type, 16);
}
quint8 * MsgPackPrivate::unpack_ext8(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
quint32 len = *(p++);
return unpack_ext(v, p + 1, type, len);
}
quint8 * MsgPackPrivate::unpack_ext16(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
quint32 len = _msgpack_load16(quint32, p);
p += 2;
return unpack_ext(v, p + 1, type, len);
}
quint8 * MsgPackPrivate::unpack_ext32(QVariant &v, quint8 *p)
{
qint8 type = *(++p);
quint32 len = _msgpack_load32(quint32, p);
p += 4;
return unpack_ext(v, p + 1, type, len);
}
bool MsgPackPrivate::register_unpacker(qint8 msgpack_type, MsgPack::unpack_user_f unpacker)
{
if (user_unpackers.contains(msgpack_type)) {
qWarning() << "MsgPack::unpacker for type" << msgpack_type << "already exists";
return false;
}
if (unpacker == 0) {
qWarning() << "MsgPack::unpacker for type" << msgpack_type << "is invalid";
return false;
}
user_unpackers.insert(msgpack_type, unpacker);
return true;
}

View File

@ -1,75 +0,0 @@
#ifndef MSGPACK_P_H
#define MSGPACK_P_H
#include <QVariant>
#include "../msgpack_common.h"
namespace MsgPackPrivate
{
/* unpack functions:
* quint8 * _type_(QVariant &v, quint8 *p);
* parses some type, which data is stored at p
* type data goes to v
* return pointer to last byte + 1
*/
typedef quint8 * (* type_parser_f)(QVariant &v, quint8 *p);
extern type_parser_f unpackers[32];
bool register_unpacker(qint8 msgpack_type, MsgPack::unpack_user_f unpacker);
extern QHash<qint8, MsgPack::unpack_user_f> user_unpackers;
// goes from p to end unpacking types with unpack_type function below
QVariant unpack(quint8 *p, quint8 *end);
// unpack some type, can be called recursively from other unpack functions
quint8 * unpack_type(QVariant &v, quint8 *p);
quint8 * unpack_nil(QVariant &v, quint8 *p);
quint8 * unpack_never_used(QVariant &v, quint8 *p);
quint8 * unpack_false(QVariant &v, quint8 *p);
quint8 * unpack_true(QVariant &v, quint8 *p);
quint8 * unpack_positive_fixint(QVariant &v, quint8 *p);
quint8 * unpack_negative_fixint(QVariant &v, quint8 *p);
quint8 * unpack_uint8(QVariant &v, quint8 *p);
quint8 * unpack_uint16(QVariant &v, quint8 *p);
quint8 * unpack_uint32(QVariant &v, quint8 *p);
quint8 * unpack_uint64(QVariant &v, quint8 *p);
quint8 * unpack_int8(QVariant &v, quint8 *p);
quint8 * unpack_int16(QVariant &v, quint8 *p);
quint8 * unpack_int32(QVariant &v, quint8 *p);
quint8 * unpack_int64(QVariant &v, quint8 *p);
quint8 * unpack_float32(QVariant &v, quint8 *p);
quint8 * unpack_float64(QVariant &v, quint8 *p);
quint8 * unpack_fixstr(QVariant &v, quint8 *p);
quint8 * unpack_str8(QVariant &v, quint8 *p);
quint8 * unpack_str16(QVariant &v, quint8 *p);
quint8 * unpack_str32(QVariant &v, quint8 *p);
quint8 * unpack_bin8(QVariant &v, quint8 *p);
quint8 * unpack_bin16(QVariant &v, quint8 *p);
quint8 * unpack_bin32(QVariant &v, quint8 *p);
quint8 * unpack_array_len(QVariant &v, quint8 *p, quint32 len);
quint8 * unpack_fixarray(QVariant &v, quint8 *p);
quint8 * unpack_array16(QVariant &v, quint8 *p);
quint8 * unpack_array32(QVariant &v, quint8 *p);
quint8 * unpack_map_len(QVariant &v, quint8 *p, quint32 len);
quint8 * unpack_fixmap(QVariant &v, quint8 *p);
quint8 * unpack_map16(QVariant &v, quint8 *p);
quint8 * unpack_map32(QVariant &v, quint8 *p);
quint8 * unpack_ext(QVariant &v, quint8 *p, qint8 type, quint32 len);
quint8 * unpack_fixext1(QVariant &v, quint8 *p);
quint8 * unpack_fixext2(QVariant &v, quint8 *p);
quint8 * unpack_fixext4(QVariant &v, quint8 *p);
quint8 * unpack_fixext8(QVariant &v, quint8 *p);
quint8 * unpack_fixext16(QVariant &v, quint8 *p);
quint8 * unpack_ext8(QVariant &v, quint8 *p);
quint8 * unpack_ext16(QVariant &v, quint8 *p);
quint8 * unpack_ext32(QVariant &v, quint8 *p);
}
#endif // MSGPACK_P_H

View File

@ -1,5 +1,6 @@
#include "pack_p.h"
#include "private/sysdep.h"
#include <limits>
#include <QDebug>
QHash<QMetaType::Type, MsgPackPrivate::packer_t> MsgPackPrivate::user_packers;
@ -10,7 +11,7 @@ quint8 *MsgPackPrivate::pack(const QVariant &v, quint8 *p, bool wr)
if (t == QMetaType::Int)
p = pack_int(v.toInt(), p, wr);
else if (t == QMetaType::UInt)
p = pack_uint(v.toInt(), p, wr);
p = pack_uint(v.toUInt(), p, wr);
else if (t == QMetaType::Bool)
p = pack_bool(v, p, wr);
else if (t == QMetaType::QString)
@ -43,12 +44,14 @@ quint8 *MsgPackPrivate::pack_int(qint32 i, quint8 *p, bool wr)
qint32 val = _msgpack_be32(i);
if (wr) *p = *( (quint8 *)&val + 3 );
p++;
} else if (i >= -128 && i <= 255) {
} else if (i >= std::numeric_limits<qint8>::min()
&& i <= std::numeric_limits<quint8>::max()) {
if (wr) *p = i > 0 ? 0xcc : 0xd0;
p++;
if (wr) *p = i;
p++;
} else if (i >= -32768 && i <= 65535) {
} else if (i >= std::numeric_limits<qint16>::min() &&
i <= std::numeric_limits<quint16>::max()) {
if (wr) *p = i > 0 ? 0xcd : 0xd1;
p++;
if (wr) _msgpack_store16(p, i);
@ -69,12 +72,12 @@ quint8 *MsgPackPrivate::pack_uint(quint32 i, quint8 *p, bool wr)
qint32 val = _msgpack_be32(i);
if (wr) *p = *( (quint8 *)&val + 3 );
p++;
} else if (i <= 255) {
} else if (i <= std::numeric_limits<quint8>::max()) {
if (wr) *p = 0xcc;
p++;
if (wr) *p = i;
p++;
} else if (i <= 65535) {
} else if (i <= std::numeric_limits<quint16>::max()) {
if (wr) *p = 0xcd;
p++;
if (wr) _msgpack_store16(p, i);
@ -91,22 +94,23 @@ quint8 *MsgPackPrivate::pack_uint(quint32 i, quint8 *p, bool wr)
quint8 *MsgPackPrivate::pack_longlong(qint64 i, quint8 *p, bool wr)
{
if (i >= -2147483648 && i <= 2147483647)
if (i >= std::numeric_limits<qint32>::min()
&& i <= std::numeric_limits<quint32>::max())
return p = pack_int(i, p, wr);
if (wr) *p = 0xd3;
p++;
if (wr) _msgpack_store64(p, i);
return p += 8;
return p + 8;
}
quint8 *MsgPackPrivate::pack_ulonglong(quint64 i, quint8 *p, bool wr)
{
if (i <= 4294967295)
if (i <= std::numeric_limits<quint32>::max())
return pack_uint(i, p, wr);
if (wr) *p = 0xcf;
p++;
if (wr) _msgpack_store64(p, i);
return p += 8;
return p + 8;
}
quint8 *MsgPackPrivate::pack_bool(const QVariant &v, quint8 *p, bool wr)
@ -122,7 +126,7 @@ quint8 *MsgPackPrivate::pack_list(const QVariantList &list, quint8 *p, bool wr)
if (len <= 15) {
if (wr) *p = 0x90 | len;
p++;
} else if (len <= 65535) {
} else if (len <= std::numeric_limits<quint16>::max()) {
if (wr) *p = 0xdc;
p++;
if (wr) _msgpack_store16(p, len);
@ -144,12 +148,12 @@ quint8 *MsgPackPrivate::pack_string(const QString &str, quint8 *p, bool wr)
if (len <= 31) {
if (wr) *p = 0xa0 | len;
p++;
} else if (len <= 255) {
} else if (len <= std::numeric_limits<quint8>::max()) {
if (wr) *p = 0xd9;
p++;
if (wr) *p = len;
p++;
} else if (len <= 65535) {
} else if (len <= std::numeric_limits<quint16>::max()) {
if (wr) *p = 0xda;
p++;
if (wr) _msgpack_store16(p, len);
@ -161,9 +165,8 @@ quint8 *MsgPackPrivate::pack_string(const QString &str, quint8 *p, bool wr)
p += 4;
}
if (wr) memcpy(p, str.toUtf8().data(), len);
p += len;
return p;
return p + len;
}
quint8 *MsgPackPrivate::pack_double(double i, quint8 *p, bool wr)
@ -180,18 +183,18 @@ quint8 *MsgPackPrivate::pack_double(double i, quint8 *p, bool wr)
*(p + i) = *(d + i);
#endif
}
return p += 8;
return p + 8;
}
quint8 *MsgPackPrivate::pack_array(const QByteArray &arr, quint8 *p, bool wr)
{
int len = arr.length();
if (len <= 255) {
if (len <= std::numeric_limits<quint8>::max()) {
if (wr) *p = 0xc4;
p++;
if (wr) *p = len;
p++;
} else if (len <= 65535) {
} else if (len <= std::numeric_limits<quint16>::max()) {
if (wr) *p = 0xc5;
p++;
if (wr) _msgpack_store16(p, len);
@ -220,7 +223,7 @@ quint8 *MsgPackPrivate::pack_map(const QVariantMap &map, quint8 *p, bool wr)
if (len <= 15) {
if (wr) *p = 0x80 | len;
p++;
} else if (len <= 65535) {
} else if (len <= std::numeric_limits<quint16>::max()) {
if (wr) *p = 0xde;
p++;
if (wr) _msgpack_store16(p, len);
@ -281,12 +284,12 @@ quint8 *MsgPackPrivate::pack_user(const QVariant &v, quint8 *p, bool wr)
} else if (len == 16) {
if (wr) *p = 0xd8;
p++;
} else if (len <= 255) {
} else if (len <= std::numeric_limits<quint8>::max()) {
if (wr) *p = 0xc7;
p++;
if (wr) *p = len;
p++;
} else if (len <= 65535) {
} else if (len <= std::numeric_limits<quint16>::max()) {
if (wr) *p = 0xc8;
p++;
if (wr) _msgpack_store16(p, len);

View File

@ -100,7 +100,7 @@ quint8 * MsgPackPrivate::unpack_negative_fixint(QVariant &v, quint8 *p)
quint8 * MsgPackPrivate::unpack_uint8(QVariant &v, quint8 *p)
{
v = (quint8)*(++p);
return p++;
return p + 1;
}
quint8 * MsgPackPrivate::unpack_uint16(QVariant &v, quint8 *p)
@ -264,14 +264,14 @@ quint8 * MsgPackPrivate::unpack_array16(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load16(quint32, p);
return unpack_array_len(v, p += 2, len);
return unpack_array_len(v, p + 2, len);
}
quint8 * MsgPackPrivate::unpack_array32(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load32(quint32, p);
return unpack_array_len(v, p += 4, len);
return unpack_array_len(v, p + 4, len);
}
quint8 * MsgPackPrivate::unpack_map_len(QVariant &v, quint8 *p, quint32 len)
@ -299,7 +299,7 @@ quint8 * MsgPackPrivate::unpack_map16(QVariant &v, quint8 *p)
{
p++;
quint32 len = _msgpack_load16(quint32, p);
return unpack_map_len(v, p += 2, len);
return unpack_map_len(v, p + 2, len);
}
quint8 * MsgPackPrivate::unpack_map32(QVariant &v, quint8 *p)