Replaced bit shift with memcpy on load.

This commit is contained in:
Takatoshi Kondo
2014-03-31 16:02:29 +09:00
parent bc33317b7e
commit dac5c60608
4 changed files with 175 additions and 136 deletions

View File

@@ -18,9 +18,11 @@
#ifndef MSGPACK_PACK_HPP
#define MSGPACK_PACK_HPP
#include "pack_define.h"
#include <stdexcept>
#include <limits.h>
#include <limits>
#include <cstring>
#include "sysdep.h"
namespace msgpack {
@@ -30,7 +32,6 @@ class packer {
public:
packer(Stream* s);
packer(Stream& s);
~packer();
public:
template <typename T>
@@ -169,9 +170,6 @@ inline packer<Stream>::packer(Stream* s) : m_stream(*s) { }
template <typename Stream>
inline packer<Stream>::packer(Stream& s) : m_stream(s) { }
template <typename Stream>
inline packer<Stream>::~packer() { }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d)

View File

@@ -132,53 +132,27 @@ typedef unsigned int _msgpack_atomic_counter_t;
((((uint64_t)x) >> 56) ) )
#endif
#define _msgpack_load16(cast, from) ((cast)( \
(((uint16_t)((uint8_t*)(from))[0]) << 8) | \
(((uint16_t)((uint8_t*)(from))[1]) ) ))
#define _msgpack_load32(cast, from) ((cast)( \
(((uint32_t)((uint8_t*)(from))[0]) << 24) | \
(((uint32_t)((uint8_t*)(from))[1]) << 16) | \
(((uint32_t)((uint8_t*)(from))[2]) << 8) | \
(((uint32_t)((uint8_t*)(from))[3]) ) ))
#define _msgpack_load64(cast, from) ((cast)( \
(((uint64_t)((uint8_t*)(from))[0]) << 56) | \
(((uint64_t)((uint8_t*)(from))[1]) << 48) | \
(((uint64_t)((uint8_t*)(from))[2]) << 40) | \
(((uint64_t)((uint8_t*)(from))[3]) << 32) | \
(((uint64_t)((uint8_t*)(from))[4]) << 24) | \
(((uint64_t)((uint8_t*)(from))[5]) << 16) | \
(((uint64_t)((uint8_t*)(from))[6]) << 8) | \
(((uint64_t)((uint8_t*)(from))[7]) ) ))
#else /* __LITTLE_ENDIAN__ */
#define _msgpack_be16(x) (x)
#define _msgpack_be32(x) (x)
#define _msgpack_be64(x) (x)
#define _msgpack_load16(cast, from) ((cast)( \
(((uint16_t)((uint8_t*)from)[0]) << 8) | \
(((uint16_t)((uint8_t*)from)[1]) ) ))
#define _msgpack_load32(cast, from) ((cast)( \
(((uint32_t)((uint8_t*)from)[0]) << 24) | \
(((uint32_t)((uint8_t*)from)[1]) << 16) | \
(((uint32_t)((uint8_t*)from)[2]) << 8) | \
(((uint32_t)((uint8_t*)from)[3]) ) ))
#define _msgpack_load64(cast, from) ((cast)( \
(((uint64_t)((uint8_t*)from)[0]) << 56) | \
(((uint64_t)((uint8_t*)from)[1]) << 48) | \
(((uint64_t)((uint8_t*)from)[2]) << 40) | \
(((uint64_t)((uint8_t*)from)[3]) << 32) | \
(((uint64_t)((uint8_t*)from)[4]) << 24) | \
(((uint64_t)((uint8_t*)from)[5]) << 16) | \
(((uint64_t)((uint8_t*)from)[6]) << 8) | \
(((uint64_t)((uint8_t*)from)[7]) ) ))
#endif
#define _msgpack_load16(cast, from, to) do { \
memcpy((cast*)(to), (from), sizeof(cast)); \
*(to) = _msgpack_be16(*(to)); \
} while (0);
#define _msgpack_load32(cast, from, to) do { \
memcpy((cast*)(to), (from), sizeof(cast)); \
*(to) = _msgpack_be32(*(to)); \
} while (0);
#define _msgpack_load64(cast, from, to) do { \
memcpy((cast*)(to), (from), sizeof(cast)); \
*(to) = _msgpack_be64(*(to)); \
} while (0);
#define _msgpack_store16(to, num) \
do { uint16_t val = _msgpack_be16(num); memcpy(to, &val, 2); } while(0)

View File

@@ -25,7 +25,7 @@
#include <memory>
#include <stdexcept>
#include <byteswap.h>
@@ -209,42 +209,37 @@ struct fix_tag {
};
template <typename T>
inline unsigned int load(const char* n, typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type* = nullptr) {
return static_cast<unsigned int>(*reinterpret_cast<const uint8_t*>(n)) & 0x0f;
struct value {
typedef T type;
};
template <>
struct value<fix_tag> {
typedef unsigned int type;
};
template <typename T>
inline void load(unsigned int& dst, const char* n, typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type* = nullptr) {
dst = static_cast<unsigned int>(*reinterpret_cast<const uint8_t*>(n)) & 0x0f;
}
template <typename T>
inline T load(const char* n, typename msgpack::enable_if<sizeof(T) == 1>::type* = nullptr) {
return static_cast<T>(*reinterpret_cast<const uint8_t*>(n));
inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 1>::type* = nullptr) {
dst = static_cast<T>(*reinterpret_cast<const uint8_t*>(n));
}
template <typename T>
inline T load(const char* n, typename msgpack::enable_if<sizeof(T) == 2>::type* = nullptr) {
return static_cast<T>(
(static_cast<uint16_t>(reinterpret_cast<const uint8_t*>(n)[0]) << 8) |
(static_cast<uint16_t>(reinterpret_cast<const uint8_t*>(n)[1]) ));
inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 2>::type* = nullptr) {
_msgpack_load16(T, n, &dst);
}
template <typename T>
inline T load(const char* n, typename msgpack::enable_if<sizeof(T) == 4>::type* = nullptr) {
return static_cast<T>(
(static_cast<uint32_t>(reinterpret_cast<const uint8_t*>(n)[0]) << 24) |
(static_cast<uint32_t>(reinterpret_cast<const uint8_t*>(n)[1]) << 16) |
(static_cast<uint32_t>(reinterpret_cast<const uint8_t*>(n)[2]) << 8) |
(static_cast<uint32_t>(reinterpret_cast<const uint8_t*>(n)[3]) ));
inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 4>::type* = nullptr) {
_msgpack_load32(T, n, &dst);
}
template <typename T>
inline T load(const char* n, typename msgpack::enable_if<sizeof(T) == 8>::type* = nullptr) {
return static_cast<T>(
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[0]) << 56) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[1]) << 48) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[2]) << 40) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[3]) << 32) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[4]) << 24) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[5]) << 16) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[6]) << 8) |
(static_cast<uint64_t>(reinterpret_cast<const uint8_t*>(n)[7]) ));
inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 8>::type* = nullptr) {
_msgpack_load64(T, n, &dst);
}
class context {
@@ -414,14 +409,14 @@ public:
//case CS_
case CS_FLOAT: {
union { uint32_t i; float f; } mem;
mem.i = load<uint32_t>(n);
load<uint32_t>(mem.i, n);
unpack_float(mem.f, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_DOUBLE: {
union { uint64_t i; double f; } mem;
mem.i = load<uint64_t>(n);
load<uint64_t>(mem.i, n);
#if defined(__arm__) && !(__ARM_EABI__) // arm-oabi
// https://github.com/msgpack/msgpack-perl/pull/1
mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
@@ -431,47 +426,65 @@ public:
if (ret != 0) return ret;
} break;
case CS_UINT_8: {
unpack_uint8(load<uint8_t>(n), obj);
uint8_t tmp;
load<uint8_t>(tmp, n);
unpack_uint8(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_UINT_16: {
unpack_uint16(load<uint16_t>(n), obj);
uint16_t tmp;
load<uint16_t>(tmp, n);
unpack_uint16(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_UINT_32: {
unpack_uint32(load<uint32_t>(n), obj);
uint32_t tmp;
load<uint32_t>(tmp, n);
unpack_uint32(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_UINT_64: {
unpack_uint64(load<uint64_t>(n), obj);
uint64_t tmp;
load<uint64_t>(tmp, n);
unpack_uint64(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_INT_8: {
unpack_int8(load<uint8_t>(n), obj);
int8_t tmp;
load<int8_t>(tmp, n);
unpack_int8(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_INT_16: {
unpack_int16(load<int16_t>(n), obj);
int16_t tmp;
load<int16_t>(tmp, n);
unpack_int16(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_INT_32: {
unpack_int32(load<int32_t>(n), obj);
int32_t tmp;
load<int32_t>(tmp, n);
unpack_int32(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_INT_64: {
unpack_int64(load<int64_t>(n), obj);
int64_t tmp;
load<int64_t>(tmp, n);
unpack_int64(tmp, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_STR_8:
trail_ = load<uint8_t>(n);
case CS_STR_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
trail_ = tmp;
if(trail_ == 0) {
unpack_str(user_, data, n, trail_, obj);
int ret = push_proc(obj, off);
@@ -481,9 +494,11 @@ public:
cs_ = ACS_STR_VALUE;
fixed_trail_again = true;
}
break;
case CS_BIN_8:
trail_ = load<uint8_t>(n);
} break;
case CS_BIN_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
trail_ = tmp;
if(trail_ == 0) {
unpack_bin(user_, data, n, trail_, obj);
int ret = push_proc(obj, off);
@@ -493,9 +508,11 @@ public:
cs_ = ACS_BIN_VALUE;
fixed_trail_again = true;
}
break;
case CS_STR_16:
trail_ = load<uint16_t>(n);
} break;
case CS_STR_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
trail_ = tmp;
if(trail_ == 0) {
unpack_str(user_, data, n, trail_, obj);
int ret = push_proc(obj, off);
@@ -505,9 +522,11 @@ public:
cs_ = ACS_STR_VALUE;
fixed_trail_again = true;
}
break;
case CS_BIN_16:
trail_ = load<uint16_t>(n);
} break;
case CS_BIN_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
trail_ = tmp;
if(trail_ == 0) {
unpack_bin(user_, data, n, trail_, obj);
int ret = push_proc(obj, off);
@@ -517,9 +536,9 @@ public:
cs_ = ACS_BIN_VALUE;
fixed_trail_again = true;
}
break;
} break;
case CS_STR_32:
trail_ = load<uint32_t>(n);
load<uint32_t>(trail_, n);
if(trail_ == 0) {
unpack_str(user_, data, n, trail_, obj);
int ret = push_proc(obj, off);
@@ -531,7 +550,7 @@ public:
}
break;
case CS_BIN_32:
trail_ = load<uint32_t>(n);
load<uint32_t>(trail_, n);
if(trail_ == 0) {
unpack_bin(user_, data, n, trail_, obj);
int ret = push_proc(obj, off);
@@ -599,19 +618,26 @@ private:
object& obj,
const char* load_pos,
size_t& off) {
if(top_ < MSGPACK_EMBED_STACK_SIZE /* FIXME */
&& f(user_, load<T>(load_pos), stack_[top_].obj())) {
if(load<T>(load_pos) == 0) {
obj = stack_[top_].obj();
int ret = push_proc(obj, off);
if (ret != 0) return ret;
if(top_ < MSGPACK_EMBED_STACK_SIZE /* FIXME */) {
typename value<T>::type tmp;
load<T>(tmp, load_pos);
if (f(user_, tmp, stack_[top_].obj())) {
if(tmp == 0) {
obj = stack_[top_].obj();
int ret = push_proc(obj, off);
if (ret != 0) return ret;
}
else {
stack_[top_].set_container_type(container_type);
stack_[top_].set_count(tmp);
++top_;
cs_ = CS_HEADER;
++current_;
}
}
else {
stack_[top_].set_container_type(container_type);
stack_[top_].set_count(load<T>(load_pos));
++top_;
cs_ = CS_HEADER;
++current_;
off = current_ - start_;
return -1;
}
}
else {

View File

@@ -260,11 +260,11 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
//case CS_
case CS_FLOAT: {
union { uint32_t i; float f; } mem;
mem.i = _msgpack_load32(uint32_t,n);
_msgpack_load32(uint32_t, n, &mem.i);
push_fixed_value(_float, mem.f); }
case CS_DOUBLE: {
union { uint64_t i; double f; } mem;
mem.i = _msgpack_load64(uint64_t,n);
_msgpack_load64(uint64_t, n, &mem.i);
#if defined(__arm__) && !(__ARM_EABI__) // arm-oabi
// https://github.com/msgpack/msgpack-perl/pull/1
mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
@@ -272,21 +272,38 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
push_fixed_value(_double, mem.f); }
case CS_UINT_8:
push_fixed_value(_uint8, *(uint8_t*)n);
case CS_UINT_16:
push_fixed_value(_uint16, _msgpack_load16(uint16_t,n));
case CS_UINT_32:
push_fixed_value(_uint32, _msgpack_load32(uint32_t,n));
case CS_UINT_64:
push_fixed_value(_uint64, _msgpack_load64(uint64_t,n));
case CS_UINT_16:{
uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp);
push_fixed_value(_uint16, tmp);
}
case CS_UINT_32:{
uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp);
push_fixed_value(_uint32, tmp);
}
case CS_UINT_64:{
uint64_t tmp;
_msgpack_load64(uint64_t,n,&tmp);
push_fixed_value(_uint64, tmp);
}
case CS_INT_8:
push_fixed_value(_int8, *(int8_t*)n);
case CS_INT_16:
push_fixed_value(_int16, _msgpack_load16(int16_t,n));
case CS_INT_32:
push_fixed_value(_int32, _msgpack_load32(int32_t,n));
case CS_INT_64:
push_fixed_value(_int64, _msgpack_load64(int64_t,n));
case CS_INT_16:{
int16_t tmp;
_msgpack_load16(int16_t,n,&tmp);
push_fixed_value(_int16, tmp);
}
case CS_INT_32:{
int32_t tmp;
_msgpack_load32(int32_t,n,&tmp);
push_fixed_value(_int32, tmp);
}
case CS_INT_64:{
int64_t tmp;
_msgpack_load64(int64_t,n,&tmp);
push_fixed_value(_int64, tmp);
}
//case CS_
//case CS_
@@ -312,14 +329,26 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
again_fixed_trail_if_zero(ACS_STR_VALUE, *(uint8_t*)n, _str_zero);
case CS_BIN_8:
again_fixed_trail_if_zero(ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero);
case CS_STR_16:
again_fixed_trail_if_zero(ACS_STR_VALUE, _msgpack_load16(uint16_t,n), _str_zero);
case CS_BIN_16:
again_fixed_trail_if_zero(ACS_BIN_VALUE, _msgpack_load16(uint16_t,n), _bin_zero);
case CS_STR_32:
again_fixed_trail_if_zero(ACS_STR_VALUE, _msgpack_load32(uint32_t,n), _str_zero);
case CS_BIN_32:
again_fixed_trail_if_zero(ACS_BIN_VALUE, _msgpack_load32(uint32_t,n), _bin_zero);
case CS_STR_16:{
uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp);
again_fixed_trail_if_zero(ACS_STR_VALUE, tmp, _str_zero);
}
case CS_BIN_16:{
uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp);
again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero);
}
case CS_STR_32:{
uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp);
again_fixed_trail_if_zero(ACS_STR_VALUE, tmp, _str_zero);
}
case CS_BIN_32:{
uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp);
again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero);
}
case ACS_STR_VALUE:
_str_zero:
push_variable_value(_str, data, n, trail);
@@ -327,17 +356,29 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
_bin_zero:
push_variable_value(_bin, data, n, trail);
case CS_ARRAY_16:
start_container(_array, _msgpack_load16(uint16_t,n), CT_ARRAY_ITEM);
case CS_ARRAY_32:
case CS_ARRAY_16:{
uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp);
start_container(_array, tmp, CT_ARRAY_ITEM);
}
case CS_ARRAY_32:{
/* FIXME security guard */
start_container(_array, _msgpack_load32(uint32_t,n), CT_ARRAY_ITEM);
uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp);
start_container(_array, tmp, CT_ARRAY_ITEM);
}
case CS_MAP_16:
start_container(_map, _msgpack_load16(uint16_t,n), CT_MAP_KEY);
case CS_MAP_32:
case CS_MAP_16:{
uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp);
start_container(_map, tmp, CT_MAP_KEY);
}
case CS_MAP_32:{
/* FIXME security guard */
start_container(_map, _msgpack_load32(uint32_t,n), CT_MAP_KEY);
uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp);
start_container(_map, tmp, CT_MAP_KEY);
}
default:
goto _failed;