Untabified.

Adjust line break positions.
This commit is contained in:
Takatoshi Kondo
2014-07-12 00:17:31 +09:00
parent 0889e6117e
commit b0df21295c
75 changed files with 17125 additions and 17125 deletions

View File

@@ -19,20 +19,20 @@
#define MSGPACK_CPP03_DEFINE_HPP #define MSGPACK_CPP03_DEFINE_HPP
#define MSGPACK_DEFINE(...) \ #define MSGPACK_DEFINE(...) \
template <typename Packer> \ template <typename Packer> \
void msgpack_pack(Packer& pk) const \ void msgpack_pack(Packer& pk) const \
{ \ { \
msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \ msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \
} \ } \
void msgpack_unpack(msgpack::object const& o) \ void msgpack_unpack(msgpack::object const& o) \
{ \ { \
msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \ msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \
}\ }\
template <typename MSGPACK_OBJECT> \ template <typename MSGPACK_OBJECT> \
void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \ void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \
{ \ { \
msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \
} }
// MSGPACK_ADD_ENUM must be used in the global namespace. // MSGPACK_ADD_ENUM must be used in the global namespace.
#define MSGPACK_ADD_ENUM(enum) \ #define MSGPACK_ADD_ENUM(enum) \
@@ -71,72 +71,72 @@ struct define;
template <> template <>
struct define<> { struct define<> {
typedef define<> value_type; typedef define<> value_type;
typedef tuple<> tuple_type; typedef tuple<> tuple_type;
template <typename Packer> template <typename Packer>
void msgpack_pack(Packer& pk) const void msgpack_pack(Packer& pk) const
{ {
pk.pack_array(0); pk.pack_array(0);
} }
void msgpack_unpack(msgpack::object const& o) void msgpack_unpack(msgpack::object const& o)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
} }
void msgpack_object(msgpack::object* o, msgpack::zone* z) const void msgpack_object(msgpack::object* o, msgpack::zone* z) const
{ {
o->type = type::ARRAY; o->type = type::ARRAY;
o->via.array.ptr = nullptr; o->via.array.ptr = nullptr;
o->via.array.size = 0; o->via.array.size = 0;
} }
}; };
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> { struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
typedef define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type; typedef define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type; typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type;
define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) : define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) :
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
template <typename Packer> template <typename Packer>
void msgpack_pack(Packer& pk) const void msgpack_pack(Packer& pk) const
{ {
pk.pack_array(<%=i+1%>); pk.pack_array(<%=i+1%>);
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
pk.pack(a<%=j%>);<%}%> pk.pack(a<%=j%>);<%}%>
} }
void msgpack_unpack(msgpack::object const& o) void msgpack_unpack(msgpack::object const& o)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
const size_t size = o.via.array.size; const size_t size = o.via.array.size;
if(size > 0) { if(size > 0) {
msgpack::object *ptr = o.via.array.ptr; msgpack::object *ptr = o.via.array.ptr;
switch(size) { switch(size) {
default:<%(i).downto(0) {|j|%> default:<%(i).downto(0) {|j|%>
case <%=j+1%>: ptr[<%=j%>].convert(a<%=j%>);<%}%> case <%=j+1%>: ptr[<%=j%>].convert(a<%=j%>);<%}%>
} }
} }
} }
void msgpack_object(msgpack::object* o, msgpack::zone* z) const void msgpack_object(msgpack::object* o, msgpack::zone* z) const
{ {
o->type = type::ARRAY; o->type = type::ARRAY;
o->via.array.ptr = static_cast<object*>(z->allocate_align(sizeof(object)*<%=i+1%>)); o->via.array.ptr = static_cast<object*>(z->allocate_align(sizeof(object)*<%=i+1%>));
o->via.array.size = <%=i+1%>; o->via.array.size = <%=i+1%>;
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%> o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%>
} }
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
A<%=j%>& a<%=j%>;<%}%> A<%=j%>& a<%=j%>;<%}%>
}; };
<%}%> <%}%>
inline define<> make_define() inline define<> make_define()
{ {
return define<>(); return define<>();
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>) define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>)
{ {
return define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>); return define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
} }
<%}%> <%}%>

View File

@@ -39,40 +39,40 @@ struct const_tuple_element;
template <typename T> template <typename T>
struct tuple_type { struct tuple_type {
typedef T type; typedef T type;
typedef T value_type; typedef T value_type;
typedef T& reference; typedef T& reference;
typedef const T& const_reference; typedef const T& const_reference;
typedef const T& transparent_reference; typedef const T& transparent_reference;
}; };
template <typename T> template <typename T>
struct tuple_type<T&> { struct tuple_type<T&> {
typedef T type; typedef T type;
typedef T& value_type; typedef T& value_type;
typedef T& reference; typedef T& reference;
typedef const T& const_reference; typedef const T& const_reference;
typedef T& transparent_reference; typedef T& transparent_reference;
}; };
template <typename T> template <typename T>
struct tuple_type<const T&> { struct tuple_type<const T&> {
typedef T type; typedef T type;
typedef T& value_type; typedef T& value_type;
typedef T& reference; typedef T& reference;
typedef const T& const_reference; typedef const T& const_reference;
typedef const T& transparent_reference; typedef const T& transparent_reference;
}; };
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>> template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> { struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
tuple_element(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : m_x(x.a<%=j%>) {} tuple_element(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : m_x(x.a<%=j%>) {}
typename tuple_type<A<%=j%>>::reference get() { return m_x; } typename tuple_type<A<%=j%>>::reference get() { return m_x; }
typename tuple_type<A<%=j%>>::const_reference get() const { return m_x; } typename tuple_type<A<%=j%>>::const_reference get() const { return m_x; }
private: private:
typename tuple_type<A<%=j%>>::reference m_x; typename tuple_type<A<%=j%>>::reference m_x;
}; };
<%}%> <%}%>
<%}%> <%}%>
@@ -81,34 +81,34 @@ private:
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>> template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> { struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
const_tuple_element(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : m_x(x.a<%=j%>) {} const_tuple_element(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : m_x(x.a<%=j%>) {}
typename tuple_type<A<%=j%>>::const_reference get() const { return m_x; } typename tuple_type<A<%=j%>>::const_reference get() const { return m_x; }
private: private:
typename tuple_type<A<%=j%>>::const_reference m_x; typename tuple_type<A<%=j%>>::const_reference m_x;
}; };
<%}%> <%}%>
<%}%> <%}%>
template <> template <>
struct tuple<> { struct tuple<> {
tuple() {} tuple() {}
tuple(object const& o) { o.convert(*this); } tuple(object const& o) { o.convert(*this); }
typedef tuple<> value_type; typedef tuple<> value_type;
}; };
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> { struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type; typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
tuple() {} tuple() {}
tuple(typename tuple_type<A0>::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference _a<%=j%><%}%>) : tuple(typename tuple_type<A0>::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference _a<%=j%><%}%>) :
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
tuple(object const& o) { o.convert(*this); } tuple(object const& o) { o.convert(*this); }
template <int N> typename tuple_element<value_type, N>::reference get() template <int N> typename tuple_element<value_type, N>::reference get()
{ return tuple_element<value_type, N>(*this).get(); } { return tuple_element<value_type, N>(*this).get(); }
template <int N> typename const_tuple_element<value_type, N>::const_reference get() const template <int N> typename const_tuple_element<value_type, N>::const_reference get() const
{ return const_tuple_element<value_type, N>(*this).get(); } { return const_tuple_element<value_type, N>(*this).get(); }
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
A<%=j%> a<%=j%>;<%}%> A<%=j%> a<%=j%>;<%}%>
}; };
template <int N, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <int N, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
@@ -121,73 +121,73 @@ inline typename type::const_tuple_element<type::tuple<A0<%1.upto(i) {|j|%>, A<%=
inline tuple<> make_tuple() inline tuple<> make_tuple()
{ {
return tuple<>(); return tuple<>();
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>) tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>)
{ {
return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>); return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
} }
<%}%> <%}%>
} // namespace type } // namespace type
inline type::tuple<>& operator>> ( inline type::tuple<>& operator>> (
object const& o, object const& o,
type::tuple<>& v) { type::tuple<>& v) {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
return v; return v;
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> ( type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> (
object const& o, object const& o,
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) { type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.array.size < <%=i+1%>) { throw type_error(); } if(o.via.array.size < <%=i+1%>) { throw type_error(); }
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
o.via.array.ptr[<%=j%>].convert<typename type::tuple_type<A<%=j%>>::type>(v.template get<<%=j%>>());<%}%> o.via.array.ptr[<%=j%>].convert<typename type::tuple_type<A<%=j%>>::type>(v.template get<<%=j%>>());<%}%>
return v; return v;
} }
<%}%> <%}%>
template <typename Stream> template <typename Stream>
const packer<Stream>& operator<< ( const packer<Stream>& operator<< (
packer<Stream>& o, packer<Stream>& o,
const type::tuple<>& v) { const type::tuple<>& v) {
o.pack_array(0); o.pack_array(0);
return o; return o;
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
const packer<Stream>& operator<< ( const packer<Stream>& operator<< (
packer<Stream>& o, packer<Stream>& o,
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) { const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
o.pack_array(<%=i+1%>); o.pack_array(<%=i+1%>);
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
o.pack(v.template get<<%=j%>>());<%}%> o.pack(v.template get<<%=j%>>());<%}%>
return o; return o;
} }
<%}%> <%}%>
inline void operator<< ( inline void operator<< (
object::with_zone& o, object::with_zone& o,
const type::tuple<>& v) { const type::tuple<>& v) {
o.type = type::ARRAY; o.type = type::ARRAY;
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
inline void operator<< ( inline void operator<< (
object::with_zone& o, object::with_zone& o,
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) { const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
o.type = type::ARRAY; o.type = type::ARRAY;
o.via.array.ptr = static_cast<object*>(o.zone->allocate_align(sizeof(object)*<%=i+1%>)); o.via.array.ptr = static_cast<object*>(o.zone->allocate_align(sizeof(object)*<%=i+1%>));
o.via.array.size = <%=i+1%>; o.via.array.size = <%=i+1%>;
<%0.upto(i) {|j|%> <%0.upto(i) {|j|%>
o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%> o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%>
} }
<%}%> <%}%>
@@ -200,11 +200,11 @@ inline void operator<< (
//<%0.upto(GENERATION_LIMIT) {|i|%> //<%0.upto(GENERATION_LIMIT) {|i|%>
//template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> //template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
//inline std::ostream& operator<< (std::ostream& o, //inline std::ostream& operator<< (std::ostream& o,
// const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) { // const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
// return o << "[" // return o << "["
// <%0.upto(i) {|j|%> // <%0.upto(i) {|j|%>
// <<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%> // <<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%>
// << "]"; // << "]";
//} //}
//<%}%> //<%}%>

View File

@@ -3,17 +3,17 @@
// //
// Copyright (C) 2008-2010 FURUHASHI Sadayuki // Copyright (C) 2008-2010 FURUHASHI Sadayuki
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
#ifndef MSGPACK_CPP03_ZONE_HPP #ifndef MSGPACK_CPP03_ZONE_HPP
#define MSGPACK_CPP03_ZONE_HPP #define MSGPACK_CPP03_ZONE_HPP
@@ -36,182 +36,182 @@
namespace msgpack { namespace msgpack {
class zone { class zone {
struct finalizer { struct finalizer {
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {} finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
void operator()() { m_func(m_data); } void operator()() { m_func(m_data); }
void (*m_func)(void*); void (*m_func)(void*);
void* m_data; void* m_data;
}; };
struct finalizer_array { struct finalizer_array {
finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {} finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {}
void call() { void call() {
finalizer* fin = m_tail; finalizer* fin = m_tail;
for(; fin != m_array; --fin) (*(fin-1))(); for(; fin != m_array; --fin) (*(fin-1))();
} }
~finalizer_array() { ~finalizer_array() {
call(); call();
::free(m_array); ::free(m_array);
} }
void clear() { void clear() {
call(); call();
m_tail = m_array; m_tail = m_array;
} }
void push(void (*func)(void* data), void* data) void push(void (*func)(void* data), void* data)
{ {
finalizer* fin = m_tail; finalizer* fin = m_tail;
if(fin == m_end) { if(fin == m_end) {
push_expand(func, data); push_expand(func, data);
return; return;
} }
fin->m_func = func; fin->m_func = func;
fin->m_data = data; fin->m_data = data;
++m_tail; ++m_tail;
} }
void push_expand(void (*func)(void*), void* data) { void push_expand(void (*func)(void*), void* data) {
const size_t nused = m_end - m_array; const size_t nused = m_end - m_array;
size_t nnext; size_t nnext;
if(nused == 0) { if(nused == 0) {
nnext = (sizeof(finalizer) < 72/2) ? nnext = (sizeof(finalizer) < 72/2) ?
72 / sizeof(finalizer) : 8; 72 / sizeof(finalizer) : 8;
} else { } else {
nnext = nused * 2; nnext = nused * 2;
} }
finalizer* tmp = finalizer* tmp =
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext)); static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
if(!tmp) { if(!tmp) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_array = tmp; m_array = tmp;
m_end = tmp + nnext; m_end = tmp + nnext;
m_tail = tmp + nused; m_tail = tmp + nused;
new (m_tail) finalizer(func, data); new (m_tail) finalizer(func, data);
++m_tail; ++m_tail;
} }
finalizer* m_tail; finalizer* m_tail;
finalizer* m_end; finalizer* m_end;
finalizer* m_array; finalizer* m_array;
}; };
struct chunk { struct chunk {
chunk* m_next; chunk* m_next;
}; };
struct chunk_list { struct chunk_list {
chunk_list(size_t chunk_size) chunk_list(size_t chunk_size)
{ {
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size)); chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
if(!c) { if(!c) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_head = c; m_head = c;
m_free = chunk_size; m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk); m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = nullptr; c->m_next = nullptr;
} }
~chunk_list() ~chunk_list()
{ {
chunk* c = m_head; chunk* c = m_head;
while(true) { while(true) {
chunk* n = c->m_next; chunk* n = c->m_next;
::free(c); ::free(c);
if(n) { if(n) {
c = n; c = n;
} else { } else {
break; break;
} }
} }
} }
void clear(size_t chunk_size) void clear(size_t chunk_size)
{ {
chunk* c = m_head; chunk* c = m_head;
while(true) { while(true) {
chunk* n = c->m_next; chunk* n = c->m_next;
if(n) { if(n) {
::free(c); ::free(c);
c = n; c = n;
} else { } else {
break; break;
} }
} }
m_head->m_next = nullptr; m_head->m_next = nullptr;
m_free = chunk_size; m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk); m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
} }
size_t m_free; size_t m_free;
char* m_ptr; char* m_ptr;
chunk* m_head; chunk* m_head;
}; };
size_t m_chunk_size; size_t m_chunk_size;
chunk_list m_chunk_list; chunk_list m_chunk_list;
finalizer_array m_finalizer_array; finalizer_array m_finalizer_array;
public: public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) /* throw() */; zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) /* throw() */;
public: public:
static zone* create(size_t chunk_size); static zone* create(size_t chunk_size);
static void destroy(zone* zone); static void destroy(zone* zone);
void* allocate_align(size_t size); void* allocate_align(size_t size);
void* allocate_no_align(size_t size); void* allocate_no_align(size_t size);
void push_finalizer(void (*func)(void*), void* data); void push_finalizer(void (*func)(void*), void* data);
template <typename T> template <typename T>
void push_finalizer(msgpack::unique_ptr<T> obj); void push_finalizer(msgpack::unique_ptr<T> obj);
void clear(); void clear();
void swap(zone& o); void swap(zone& o);
static void* operator new(std::size_t size) throw(std::bad_alloc) static void* operator new(std::size_t size) throw(std::bad_alloc)
{ {
void* p = ::malloc(size); void* p = ::malloc(size);
if (!p) throw std::bad_alloc(); if (!p) throw std::bad_alloc();
return p; return p;
} }
static void operator delete(void *p) throw() static void operator delete(void *p) throw()
{ {
::free(p); ::free(p);
} }
static void* operator new(std::size_t size, void* place) throw() static void* operator new(std::size_t size, void* place) throw()
{ {
return ::operator new(size, place); return ::operator new(size, place);
} }
static void operator delete(void* p, void* place) throw() static void operator delete(void* p, void* place) throw()
{ {
::operator delete(p, place); ::operator delete(p, place);
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>); T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>);
<%}%> <%}%>
private: private:
void undo_allocate(size_t size); void undo_allocate(size_t size);
template <typename T> template <typename T>
static void object_destructor(void* obj); static void object_destructor(void* obj);
void* allocate_expand(size_t size); void* allocate_expand(size_t size);
}; };
inline zone* zone::create(size_t chunk_size) inline zone* zone::create(size_t chunk_size)
{ {
zone* z = static_cast<zone*>(::malloc(sizeof(zone) + chunk_size)); zone* z = static_cast<zone*>(::malloc(sizeof(zone) + chunk_size));
if (!z) { if (!z) {
return nullptr; return nullptr;
} }
new (z) zone(chunk_size); new (z) zone(chunk_size);
return z; return z;
} }
inline void zone::destroy(zone* z) inline void zone::destroy(zone* z)
{ {
z->~zone(); z->~zone();
::free(z); ::free(z);
} }
inline zone::zone(size_t chunk_size) /* throw() */ :m_chunk_size(chunk_size), m_chunk_list(m_chunk_size) inline zone::zone(size_t chunk_size) /* throw() */ :m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
@@ -220,98 +220,98 @@ inline zone::zone(size_t chunk_size) /* throw() */ :m_chunk_size(chunk_size), m_
inline void* zone::allocate_align(size_t size) inline void* zone::allocate_align(size_t size)
{ {
return allocate_no_align( return allocate_no_align(
((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
} }
inline void* zone::allocate_no_align(size_t size) inline void* zone::allocate_no_align(size_t size)
{ {
if(m_chunk_list.m_free < size) { if(m_chunk_list.m_free < size) {
return allocate_expand(size); return allocate_expand(size);
} }
char* ptr = m_chunk_list.m_ptr; char* ptr = m_chunk_list.m_ptr;
m_chunk_list.m_free -= size; m_chunk_list.m_free -= size;
m_chunk_list.m_ptr += size; m_chunk_list.m_ptr += size;
return ptr; return ptr;
} }
inline void* zone::allocate_expand(size_t size) inline void* zone::allocate_expand(size_t size)
{ {
chunk_list* const cl = &m_chunk_list; chunk_list* const cl = &m_chunk_list;
size_t sz = m_chunk_size; size_t sz = m_chunk_size;
while(sz < size) { while(sz < size) {
sz *= 2; sz *= 2;
} }
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz)); chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk); char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = cl->m_head; c->m_next = cl->m_head;
cl->m_head = c; cl->m_head = c;
cl->m_free = sz - size; cl->m_free = sz - size;
cl->m_ptr = ptr + size; cl->m_ptr = ptr + size;
return ptr; return ptr;
} }
inline void zone::push_finalizer(void (*func)(void*), void* data) inline void zone::push_finalizer(void (*func)(void*), void* data)
{ {
m_finalizer_array.push(func, data); m_finalizer_array.push(func, data);
} }
template <typename T> template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{ {
m_finalizer_array.push(&zone::object_destructor<T>, obj.get()); m_finalizer_array.push(&zone::object_destructor<T>, obj.get());
obj.release(); obj.release();
} }
inline void zone::clear() inline void zone::clear()
{ {
m_finalizer_array.clear(); m_finalizer_array.clear();
m_chunk_list.clear(m_chunk_size); m_chunk_list.clear(m_chunk_size);
} }
inline void zone::swap(zone& o) inline void zone::swap(zone& o)
{ {
std::swap(*this, o); std::swap(*this, o);
} }
template <typename T> template <typename T>
void zone::object_destructor(void* obj) void zone::object_destructor(void* obj)
{ {
reinterpret_cast<T*>(obj)->~T(); reinterpret_cast<T*>(obj)->~T();
} }
inline void zone::undo_allocate(size_t size) inline void zone::undo_allocate(size_t size)
{ {
m_chunk_list.m_ptr -= size; m_chunk_list.m_ptr -= size;
m_chunk_list.m_free += size; m_chunk_list.m_free += size;
} }
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>) T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
{ {
void* x = allocate_align(sizeof(T)); void* x = allocate_align(sizeof(T));
try { try {
m_finalizer_array.push(&zone::object_destructor<T>, x); m_finalizer_array.push(&zone::object_destructor<T>, x);
} catch (...) { } catch (...) {
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
try { try {
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; --m_finalizer_array.m_tail;
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
} }
<%}%> <%}%>

View File

@@ -4,55 +4,55 @@
class old_class { class old_class {
public: public:
old_class() : value("default") { } old_class() : value("default") { }
std::string value; std::string value;
MSGPACK_DEFINE(value); MSGPACK_DEFINE(value);
}; };
class new_class { class new_class {
public: public:
new_class() : value("default"), flag(-1) { } new_class() : value("default"), flag(-1) { }
std::string value; std::string value;
int flag; int flag;
MSGPACK_DEFINE(value, flag); MSGPACK_DEFINE(value, flag);
}; };
int main(void) int main(void)
{ {
{ {
old_class oc; old_class oc;
new_class nc; new_class nc;
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, oc); msgpack::pack(sbuf, oc);
msgpack::zone zone; msgpack::zone zone;
msgpack::object obj; msgpack::object obj;
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj); msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj);
obj.convert(&nc); obj.convert(&nc);
std::cout << obj << " value=" << nc.value << " flag=" << nc.flag << std::endl; std::cout << obj << " value=" << nc.value << " flag=" << nc.flag << std::endl;
} }
{ {
new_class nc; new_class nc;
old_class oc; old_class oc;
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, nc); msgpack::pack(sbuf, nc);
msgpack::zone zone; msgpack::zone zone;
msgpack::object obj; msgpack::object obj;
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj); msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj);
obj.convert(&oc); obj.convert(&oc);
std::cout << obj << " value=" << oc.value << std::endl; std::cout << obj << " value=" << oc.value << std::endl;
} }
} }

View File

@@ -4,83 +4,83 @@
#include <sstream> #include <sstream>
namespace myprotocol { namespace myprotocol {
using namespace msgpack::type; using namespace msgpack::type;
using msgpack::define; using msgpack::define;
struct Get : define< tuple<uint32_t, std::string> > { struct Get : define< tuple<uint32_t, std::string> > {
Get() { } Get() { }
Get(uint32_t f, const std::string& k) : Get(uint32_t f, const std::string& k) :
define_type(msgpack_type(f, k)) { } define_type(msgpack_type(f, k)) { }
uint32_t& flags() { return msgpack::type::get<0>(*this); } uint32_t& flags() { return msgpack::type::get<0>(*this); }
std::string& key() { return msgpack::type::get<1>(*this); } std::string& key() { return msgpack::type::get<1>(*this); }
}; };
struct Put : define< tuple<uint32_t, std::string, raw_ref> > { struct Put : define< tuple<uint32_t, std::string, raw_ref> > {
Put() { } Put() { }
Put(uint32_t f, const std::string& k, const char* valref, uint32_t vallen) : Put(uint32_t f, const std::string& k, const char* valref, uint32_t vallen) :
define_type(msgpack_type( f, k, raw_ref(valref,vallen) )) { } define_type(msgpack_type( f, k, raw_ref(valref,vallen) )) { }
uint32_t& flags() { return msgpack::type::get<0>(*this); } uint32_t& flags() { return msgpack::type::get<0>(*this); }
std::string& key() { return msgpack::type::get<1>(*this); } std::string& key() { return msgpack::type::get<1>(*this); }
raw_ref& value() { return msgpack::type::get<2>(*this); } raw_ref& value() { return msgpack::type::get<2>(*this); }
}; };
struct MultiGet : define< std::vector<Get> > { struct MultiGet : define< std::vector<Get> > {
}; };
} }
int main(void) int main(void)
{ {
// send Get request // send Get request
std::stringstream stream; std::stringstream stream;
{ {
myprotocol::Get req; myprotocol::Get req;
req.flags() = 0; req.flags() = 0;
req.key() = "key0"; req.key() = "key0";
msgpack::pack(stream, req); msgpack::pack(stream, req);
} }
stream.seekg(0); stream.seekg(0);
// receive Get request // receive Get request
{ {
std::string buffer(stream.str()); std::string buffer(stream.str());
msgpack::zone mempool; msgpack::zone mempool;
msgpack::object o = msgpack::object o =
msgpack::unpack(buffer.data(), buffer.size(), mempool); msgpack::unpack(buffer.data(), buffer.size(), mempool);
myprotocol::Get req; myprotocol::Get req;
msgpack::convert(req, o); msgpack::convert(req, o);
std::cout << "received: " << o << std::endl; std::cout << "received: " << o << std::endl;
} }
stream.str(""); stream.str("");
// send MultiGet request // send MultiGet request
{ {
myprotocol::MultiGet req; myprotocol::MultiGet req;
req.push_back( myprotocol::Get(1, "key1") ); req.push_back( myprotocol::Get(1, "key1") );
req.push_back( myprotocol::Get(2, "key2") ); req.push_back( myprotocol::Get(2, "key2") );
req.push_back( myprotocol::Get(3, "key3") ); req.push_back( myprotocol::Get(3, "key3") );
msgpack::pack(stream, req); msgpack::pack(stream, req);
} }
stream.seekg(0); stream.seekg(0);
// receive MultiGet request // receive MultiGet request
{ {
std::string buffer(stream.str()); std::string buffer(stream.str());
msgpack::zone mempool; msgpack::zone mempool;
msgpack::object o = msgpack::object o =
msgpack::unpack(buffer.data(), buffer.size(), mempool); msgpack::unpack(buffer.data(), buffer.size(), mempool);
myprotocol::MultiGet req; myprotocol::MultiGet req;
msgpack::convert(req, o); msgpack::convert(req, o);
std::cout << "received: " << o << std::endl; std::cout << "received: " << o << std::endl;
} }
} }

View File

@@ -3,35 +3,35 @@
int main(void) int main(void)
{ {
/* msgpack::sbuffer is a simple buffer implementation. */ /* msgpack::sbuffer is a simple buffer implementation. */
msgpack_sbuffer sbuf; msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf); msgpack_sbuffer_init(&sbuf);
/* serialize values into the buffer using msgpack_sbuffer_write callback function. */ /* serialize values into the buffer using msgpack_sbuffer_write callback function. */
msgpack_packer pk; msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_array(&pk, 3); msgpack_pack_array(&pk, 3);
msgpack_pack_int(&pk, 1); msgpack_pack_int(&pk, 1);
msgpack_pack_true(&pk); msgpack_pack_true(&pk);
msgpack_pack_str(&pk, 7); msgpack_pack_str(&pk, 7);
msgpack_pack_str_body(&pk, "example", 7); msgpack_pack_str_body(&pk, "example", 7);
/* deserialize the buffer into msgpack_object instance. */ /* deserialize the buffer into msgpack_object instance. */
/* deserialized object is valid during the msgpack_zone instance alive. */ /* deserialized object is valid during the msgpack_zone instance alive. */
msgpack_zone mempool; msgpack_zone mempool;
msgpack_zone_init(&mempool, 2048); msgpack_zone_init(&mempool, 2048);
msgpack_object deserialized; msgpack_object deserialized;
msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized); msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);
/* print the deserialized object. */ /* print the deserialized object. */
msgpack_object_print(stdout, deserialized); msgpack_object_print(stdout, deserialized);
puts(""); puts("");
msgpack_zone_destroy(&mempool); msgpack_zone_destroy(&mempool);
msgpack_sbuffer_destroy(&sbuf); msgpack_sbuffer_destroy(&sbuf);
return 0; return 0;
} }

View File

@@ -5,33 +5,33 @@
int main(void) int main(void)
{ {
msgpack::type::tuple<int, bool, std::string> src(1, true, "example"); msgpack::type::tuple<int, bool, std::string> src(1, true, "example");
// serialize the object into the buffer. // serialize the object into the buffer.
// any classes that implements write(const char*,size_t) can be a buffer. // any classes that implements write(const char*,size_t) can be a buffer.
std::stringstream buffer; std::stringstream buffer;
msgpack::pack(buffer, src); msgpack::pack(buffer, src);
// send the buffer ... // send the buffer ...
buffer.seekg(0); buffer.seekg(0);
// deserialize the buffer into msgpack::object instance. // deserialize the buffer into msgpack::object instance.
std::string str(buffer.str()); std::string str(buffer.str());
// deserialized object is valid during the msgpack::zone instance alive. // deserialized object is valid during the msgpack::zone instance alive.
msgpack::zone mempool; msgpack::zone mempool;
msgpack::object deserialized; msgpack::object deserialized;
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized); msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
// msgpack::object supports ostream. // msgpack::object supports ostream.
std::cout << deserialized << std::endl; std::cout << deserialized << std::endl;
// convert msgpack::object instance into the original type. // convert msgpack::object instance into the original type.
// if the type is mismatched, it throws msgpack::type_error exception. // if the type is mismatched, it throws msgpack::type_error exception.
msgpack::type::tuple<int, bool, std::string> dst; msgpack::type::tuple<int, bool, std::string> dst;
deserialized.convert(&dst); deserialized.convert(&dst);
return 0; return 0;
} }

View File

@@ -9,59 +9,59 @@
#include <boost/timer/timer.hpp> #include <boost/timer/timer.hpp>
void test_map_pack_unpack() { void test_map_pack_unpack() {
std::cout << "[TEST][map_pack_unpack]" << std::endl; std::cout << "[TEST][map_pack_unpack]" << std::endl;
// setup // setup
std::cout << "Setting up map data..." << std::endl; std::cout << "Setting up map data..." << std::endl;
std::map<int, int> m1; std::map<int, int> m1;
int const num = 30000000L; int const num = 30000000L;
for (int i = 0; i < num; ++i) m1[i] = i; for (int i = 0; i < num; ++i) m1[i] = i;
std::cout << "Start packing..." << std::endl; std::cout << "Start packing..." << std::endl;
std::stringstream buffer; std::stringstream buffer;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::pack(buffer, m1); msgpack::pack(buffer, m1);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Pack finished..." << std::endl; std::cout << "Pack finished..." << std::endl;
buffer.seekg(0); buffer.seekg(0);
std::string str(buffer.str()); std::string str(buffer.str());
// deserialized object is valid during the msgpack::zone instance alive. // deserialized object is valid during the msgpack::zone instance alive.
msgpack::zone mempool; msgpack::zone mempool;
msgpack::object deserialized; msgpack::object deserialized;
std::cout << "Start unpacking..." << std::endl; std::cout << "Start unpacking..." << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized); msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Unpack finished..." << std::endl; std::cout << "Unpack finished..." << std::endl;
msgpack::unpacked unpacked; msgpack::unpacked unpacked;
std::cout << "Start unpacking...by void unpack(unpacked* result, const char* data, size_t len, size_t* offset = NULL)" << std::endl; std::cout << "Start unpacking...by void unpack(unpacked* result, const char* data, size_t len, size_t* offset = NULL)" << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::unpack(&unpacked, str.data(), str.size()); msgpack::unpack(&unpacked, str.data(), str.size());
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Unpack finished..." << std::endl; std::cout << "Unpack finished..." << std::endl;
std::map<int, int> m2; std::map<int, int> m2;
std::cout << "Start converting..." << std::endl; std::cout << "Start converting..." << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
deserialized.convert(&m2); deserialized.convert(&m2);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Convert finished..." << std::endl; std::cout << "Convert finished..." << std::endl;
} }
int main(void) int main(void)
{ {
test_map_pack_unpack(); test_map_pack_unpack();
} }

View File

@@ -10,81 +10,81 @@
template <typename T, std::size_t level> template <typename T, std::size_t level>
struct vecvec { struct vecvec {
typedef std::vector<typename vecvec<T, level - 1>::type> type; typedef std::vector<typename vecvec<T, level - 1>::type> type;
static void fill(type& v, std::size_t num_of_elems, T const& val) { static void fill(type& v, std::size_t num_of_elems, T const& val) {
for (int elem = 0; elem < num_of_elems; ++elem) { for (int elem = 0; elem < num_of_elems; ++elem) {
typename vecvec<T, level - 1>::type child; typename vecvec<T, level - 1>::type child;
vecvec<T, level - 1>::fill(child, num_of_elems, val); vecvec<T, level - 1>::fill(child, num_of_elems, val);
v.push_back(child); v.push_back(child);
} }
} }
}; };
template <typename T> template <typename T>
struct vecvec<T, 0> { struct vecvec<T, 0> {
typedef std::vector<T> type; typedef std::vector<T> type;
static void fill(type& v, std::size_t num_of_elems, T const& val) { static void fill(type& v, std::size_t num_of_elems, T const& val) {
for (int elem = 0; elem < num_of_elems; ++elem) { for (int elem = 0; elem < num_of_elems; ++elem) {
v.push_back(val); v.push_back(val);
} }
} }
}; };
void test_array_of_array() { void test_array_of_array() {
std::cout << "[TEST][array_of_array]" << std::endl; std::cout << "[TEST][array_of_array]" << std::endl;
// setup // setup
int const depth = 16; int const depth = 16;
std::cout << "Setting up array data..." << std::endl; std::cout << "Setting up array data..." << std::endl;
typename vecvec<int, depth>::type v1; typename vecvec<int, depth>::type v1;
vecvec<int, depth>::fill(v1, 3, 42); vecvec<int, depth>::fill(v1, 3, 42);
std::cout << "Start packing..." << std::endl; std::cout << "Start packing..." << std::endl;
std::stringstream buffer; std::stringstream buffer;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::pack(buffer, v1); msgpack::pack(buffer, v1);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Pack finished..." << std::endl; std::cout << "Pack finished..." << std::endl;
buffer.seekg(0); buffer.seekg(0);
std::string str(buffer.str()); std::string str(buffer.str());
// deserialized object is valid during the msgpack::zone instance alive. // deserialized object is valid during the msgpack::zone instance alive.
msgpack::zone mempool; msgpack::zone mempool;
msgpack::object deserialized; msgpack::object deserialized;
std::cout << "Start unpacking..." << std::endl; std::cout << "Start unpacking..." << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized); msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Unpack finished..." << std::endl; std::cout << "Unpack finished..." << std::endl;
msgpack::unpacked unpacked; msgpack::unpacked unpacked;
std::cout << "Start unpacking...by void unpack(unpacked* result, const char* data, size_t len, size_t* offset = NULL)" << std::endl; std::cout << "Start unpacking...by void unpack(unpacked* result, const char* data, size_t len, size_t* offset = NULL)" << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::unpack(&unpacked, str.data(), str.size()); msgpack::unpack(&unpacked, str.data(), str.size());
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Unpack finished..." << std::endl; std::cout << "Unpack finished..." << std::endl;
typename vecvec<int, depth>::type v2; typename vecvec<int, depth>::type v2;
std::cout << "Start converting..." << std::endl; std::cout << "Start converting..." << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
deserialized.convert(&v2); deserialized.convert(&v2);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
std::cout << "Convert finished..." << std::endl; std::cout << "Convert finished..." << std::endl;
} }
int main(void) int main(void)
{ {
test_array_of_array(); test_array_of_array();
} }

View File

@@ -3,34 +3,34 @@
void test() void test()
{ {
size_t size = 10000000; size_t size = 10000000;
msgpack_sbuffer buf; msgpack_sbuffer buf;
msgpack_sbuffer_init(&buf); msgpack_sbuffer_init(&buf);
msgpack_packer * pk = msgpack_packer_new(&buf, msgpack_sbuffer_write); msgpack_packer * pk = msgpack_packer_new(&buf, msgpack_sbuffer_write);
msgpack_pack_array(pk, size); msgpack_pack_array(pk, size);
{ {
int idx = 0; int idx = 0;
for (; idx < size; ++idx) for (; idx < size; ++idx)
msgpack_pack_uint32(pk, 1); msgpack_pack_uint32(pk, 1);
} }
msgpack_packer_free(pk); msgpack_packer_free(pk);
size_t upk_pos = 0; size_t upk_pos = 0;
msgpack_unpacked msg; msgpack_unpacked msg;
msgpack_unpacked_init(&msg); msgpack_unpacked_init(&msg);
while (msgpack_unpack_next(&msg, buf.data, buf.size, &upk_pos)) { while (msgpack_unpack_next(&msg, buf.data, buf.size, &upk_pos)) {
} }
msgpack_sbuffer_destroy(&buf); msgpack_sbuffer_destroy(&buf);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int i = 0; int i = 0;
for (; i < 10; ++i) test(); for (; i < 10; ++i) test();
return 0; return 0;
} }

View File

@@ -3,35 +3,35 @@
void test() void test()
{ {
uint64_t test_u64 = 0xFFF0000000000001LL; uint64_t test_u64 = 0xFFF0000000000001LL;
size_t size = 10000000; size_t size = 10000000;
msgpack_sbuffer buf; msgpack_sbuffer buf;
msgpack_sbuffer_init(&buf); msgpack_sbuffer_init(&buf);
msgpack_packer * pk = msgpack_packer_new(&buf, msgpack_sbuffer_write); msgpack_packer * pk = msgpack_packer_new(&buf, msgpack_sbuffer_write);
msgpack_pack_array(pk, size); msgpack_pack_array(pk, size);
{ {
int idx = 0; int idx = 0;
for (; idx < size; ++idx) for (; idx < size; ++idx)
msgpack_pack_uint64(pk, test_u64); msgpack_pack_uint64(pk, test_u64);
} }
msgpack_packer_free(pk); msgpack_packer_free(pk);
size_t upk_pos = 0; size_t upk_pos = 0;
msgpack_unpacked msg; msgpack_unpacked msg;
msgpack_unpacked_init(&msg); msgpack_unpacked_init(&msg);
while (msgpack_unpack_next(&msg, buf.data, buf.size, &upk_pos)) { while (msgpack_unpack_next(&msg, buf.data, buf.size, &upk_pos)) {
} }
msgpack_sbuffer_destroy(&buf); msgpack_sbuffer_destroy(&buf);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int i = 0; int i = 0;
for (; i < 10; ++i) test(); for (; i < 10; ++i) test();
return 0; return 0;
} }

View File

@@ -9,125 +9,125 @@
class Server { class Server {
public: public:
Server(int sock) : m_sock(sock) { } Server(int sock) : m_sock(sock) { }
~Server() { } ~Server() { }
typedef std::auto_ptr<msgpack::zone> auto_zone; typedef std::auto_ptr<msgpack::zone> auto_zone;
void socket_readable() void socket_readable()
{ {
m_pac.reserve_buffer(1024); m_pac.reserve_buffer(1024);
ssize_t count = ssize_t count =
read(m_sock, m_pac.buffer(), m_pac.buffer_capacity()); read(m_sock, m_pac.buffer(), m_pac.buffer_capacity());
if(count <= 0) { if(count <= 0) {
if(count == 0) { if(count == 0) {
throw std::runtime_error("connection closed"); throw std::runtime_error("connection closed");
} }
if(errno == EAGAIN || errno == EINTR) { if(errno == EAGAIN || errno == EINTR) {
return; return;
} }
throw std::runtime_error(strerror(errno)); throw std::runtime_error(strerror(errno));
} }
m_pac.buffer_consumed(count); m_pac.buffer_consumed(count);
msgpack::unpacked result; msgpack::unpacked result;
while (m_pac.next(&result)) { while (m_pac.next(&result)) {
msgpack::object msg = result.get(); msgpack::object msg = result.get();
auto_zone& life = result.zone(); auto_zone& life = result.zone();
process_message(msg, life); process_message(msg, life);
} }
if(m_pac.message_size() > 10*1024*1024) { if(m_pac.message_size() > 10*1024*1024) {
throw std::runtime_error("message is too large"); throw std::runtime_error("message is too large");
} }
} }
private: private:
void process_message(msgpack::object msg, auto_zone& life) void process_message(msgpack::object msg, auto_zone& life)
{ {
std::cout << "message reached: " << msg << std::endl; std::cout << "message reached: " << msg << std::endl;
} }
private: private:
int m_sock; int m_sock;
msgpack::unpacker m_pac; msgpack::unpacker m_pac;
}; };
static void* run_server(void* arg) static void* run_server(void* arg)
try { try {
Server* srv = reinterpret_cast<Server*>(arg); Server* srv = reinterpret_cast<Server*>(arg);
while(true) { while(true) {
srv->socket_readable(); srv->socket_readable();
} }
return NULL; return NULL;
} catch (std::exception& e) { } catch (std::exception& e) {
std::cerr << "error while processing client packet: " std::cerr << "error while processing client packet: "
<< e.what() << std::endl; << e.what() << std::endl;
return NULL; return NULL;
} catch (...) { } catch (...) {
std::cerr << "error while processing client packet: " std::cerr << "error while processing client packet: "
<< "unknown error" << std::endl; << "unknown error" << std::endl;
return NULL; return NULL;
} }
struct fwriter { struct fwriter {
fwriter(int fd) : m_fp( fdopen(fd, "w") ) { } fwriter(int fd) : m_fp( fdopen(fd, "w") ) { }
void write(const char* buf, size_t buflen) void write(const char* buf, size_t buflen)
{ {
size_t count = fwrite(buf, buflen, 1, m_fp); size_t count = fwrite(buf, buflen, 1, m_fp);
if(count < 1) { if(count < 1) {
std::cout << buflen << std::endl; std::cout << buflen << std::endl;
std::cout << count << std::endl; std::cout << count << std::endl;
throw std::runtime_error(strerror(errno)); throw std::runtime_error(strerror(errno));
} }
} }
void flush() { fflush(m_fp); } void flush() { fflush(m_fp); }
void close() { fclose(m_fp); } void close() { fclose(m_fp); }
private: private:
FILE* m_fp; FILE* m_fp;
}; };
int main(void) int main(void)
{ {
int pair[2]; int pair[2];
pipe(pair); pipe(pair);
// run server thread // run server thread
Server srv(pair[0]); Server srv(pair[0]);
pthread_t thread; pthread_t thread;
pthread_create(&thread, NULL, pthread_create(&thread, NULL,
run_server, reinterpret_cast<void*>(&srv)); run_server, reinterpret_cast<void*>(&srv));
// client thread: // client thread:
fwriter writer(pair[1]); fwriter writer(pair[1]);
msgpack::packer<fwriter> pk(writer); msgpack::packer<fwriter> pk(writer);
typedef msgpack::type::tuple<std::string, std::string, std::string> put_t; typedef msgpack::type::tuple<std::string, std::string, std::string> put_t;
typedef msgpack::type::tuple<std::string, std::string> get_t; typedef msgpack::type::tuple<std::string, std::string> get_t;
put_t req1("put", "apple", "red"); put_t req1("put", "apple", "red");
put_t req2("put", "lemon", "yellow"); put_t req2("put", "lemon", "yellow");
get_t req3("get", "apple"); get_t req3("get", "apple");
pk.pack(req1); pk.pack(req1);
pk.pack(req2); pk.pack(req2);
pk.pack(req3); pk.pack(req3);
writer.flush(); writer.flush();
writer.close(); writer.close();
pthread_join(thread, NULL); pthread_join(thread, NULL);
} }

View File

@@ -26,27 +26,27 @@ namespace msgpack {
inline bool& operator>> (object const& o, bool& v) inline bool& operator>> (object const& o, bool& v)
{ {
if(o.type != type::BOOLEAN) { throw type_error(); } if(o.type != type::BOOLEAN) { throw type_error(); }
v = o.via.boolean; v = o.via.boolean;
return v; return v;
} }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const bool& v) inline packer<Stream>& operator<< (packer<Stream>& o, const bool& v)
{ {
if(v) { o.pack_true(); } if(v) { o.pack_true(); }
else { o.pack_false(); } else { o.pack_false(); }
return o; return o;
} }
inline void operator<< (object& o, bool v) inline void operator<< (object& o, bool v)
{ {
o.type = type::BOOLEAN; o.type = type::BOOLEAN;
o.via.boolean = v; o.via.boolean = v;
} }
inline void operator<< (object::with_zone& o, bool v) inline void operator<< (object::with_zone& o, bool v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
} // namespace msgpack } // namespace msgpack

View File

@@ -28,91 +28,91 @@ namespace msgpack {
// --- Pack ( from tuple to packer stream --- // --- Pack ( from tuple to packer stream ---
template <typename Stream, typename Tuple, std::size_t N> template <typename Stream, typename Tuple, std::size_t N>
struct StdTuplePacker { struct StdTuplePacker {
static void pack( static void pack(
packer<Stream>& o, packer<Stream>& o,
const Tuple& v) { const Tuple& v) {
StdTuplePacker<Stream, Tuple, N-1>::pack(o, v); StdTuplePacker<Stream, Tuple, N-1>::pack(o, v);
o.pack(std::get<N-1>(v)); o.pack(std::get<N-1>(v));
} }
}; };
template <typename Stream, typename Tuple> template <typename Stream, typename Tuple>
struct StdTuplePacker<Stream, Tuple, 1> { struct StdTuplePacker<Stream, Tuple, 1> {
static void pack ( static void pack (
packer<Stream>& o, packer<Stream>& o,
const Tuple& v) { const Tuple& v) {
o.pack(std::get<0>(v)); o.pack(std::get<0>(v));
} }
}; };
template <typename Stream, typename... Args> template <typename Stream, typename... Args>
const packer<Stream>& operator<< ( const packer<Stream>& operator<< (
packer<Stream>& o, packer<Stream>& o,
const std::tuple<Args...>& v) { const std::tuple<Args...>& v) {
o.pack_array(sizeof...(Args)); o.pack_array(sizeof...(Args));
StdTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v); StdTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v);
return o; return o;
} }
// --- Convert from tuple to object --- // --- Convert from tuple to object ---
template <typename Tuple, std::size_t N> template <typename Tuple, std::size_t N>
struct StdTupleConverter { struct StdTupleConverter {
static void convert( static void convert(
object const& o, object const& o,
Tuple& v) { Tuple& v) {
StdTupleConverter<Tuple, N-1>::convert(o, v); StdTupleConverter<Tuple, N-1>::convert(o, v);
o.via.array.ptr[N-1].convert<typename std::remove_reference<decltype(std::get<N-1>(v))>::type>(std::get<N-1>(v)); o.via.array.ptr[N-1].convert<typename std::remove_reference<decltype(std::get<N-1>(v))>::type>(std::get<N-1>(v));
} }
}; };
template <typename Tuple> template <typename Tuple>
struct StdTupleConverter<Tuple, 1> { struct StdTupleConverter<Tuple, 1> {
static void convert ( static void convert (
object const& o, object const& o,
Tuple& v) { Tuple& v) {
o.via.array.ptr[0].convert<typename std::remove_reference<decltype(std::get<0>(v))>::type>(std::get<0>(v)); o.via.array.ptr[0].convert<typename std::remove_reference<decltype(std::get<0>(v))>::type>(std::get<0>(v));
} }
}; };
template <typename... Args> template <typename... Args>
std::tuple<Args...>& operator>> ( std::tuple<Args...>& operator>> (
object const& o, object const& o,
std::tuple<Args...>& v) { std::tuple<Args...>& v) {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.array.size < sizeof...(Args)) { throw type_error(); } if(o.via.array.size < sizeof...(Args)) { throw type_error(); }
StdTupleConverter<decltype(v), sizeof...(Args)>::convert(o, v); StdTupleConverter<decltype(v), sizeof...(Args)>::convert(o, v);
return v; return v;
} }
// --- Convert from tuple to object with zone --- // --- Convert from tuple to object with zone ---
template <typename Tuple, std::size_t N> template <typename Tuple, std::size_t N>
struct StdTupleToObjectWithZone { struct StdTupleToObjectWithZone {
static void convert( static void convert(
object::with_zone& o, object::with_zone& o,
const Tuple& v) { const Tuple& v) {
StdTupleToObjectWithZone<Tuple, N-1>::convert(o, v); StdTupleToObjectWithZone<Tuple, N-1>::convert(o, v);
o.via.array.ptr[N-1] = object(std::get<N-1>(v), o.zone); o.via.array.ptr[N-1] = object(std::get<N-1>(v), o.zone);
} }
}; };
template <typename Tuple> template <typename Tuple>
struct StdTupleToObjectWithZone<Tuple, 1> { struct StdTupleToObjectWithZone<Tuple, 1> {
static void convert ( static void convert (
object::with_zone& o, object::with_zone& o,
const Tuple& v) { const Tuple& v) {
o.via.array.ptr[0] = object(std::get<0>(v), o.zone); o.via.array.ptr[0] = object(std::get<0>(v), o.zone);
} }
}; };
template <typename... Args> template <typename... Args>
inline void operator<< ( inline void operator<< (
object::with_zone& o, object::with_zone& o,
std::tuple<Args...>& v) { std::tuple<Args...>& v) {
o.type = type::ARRAY; o.type = type::ARRAY;
o.via.array.ptr = static_cast<object*>(o.zone->allocate_align(sizeof(object)*sizeof...(Args))); o.via.array.ptr = static_cast<object*>(o.zone->allocate_align(sizeof(object)*sizeof...(Args)));
o.via.array.size = sizeof...(Args); o.via.array.size = sizeof...(Args);
StdTupleToObjectWithZone<decltype(v), sizeof...(Args)>::convert(o, v); StdTupleToObjectWithZone<decltype(v), sizeof...(Args)>::convert(o, v);
} }
} // msgpack } // msgpack

View File

@@ -27,47 +27,47 @@ namespace msgpack {
template <typename T> template <typename T>
inline std::deque<T>& operator>> (object const& o, std::deque<T>& v) inline std::deque<T>& operator>> (object const& o, std::deque<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.array.size); v.resize(o.via.array.size);
object* p = o.via.array.ptr; object* p = o.via.array.ptr;
object* const pend = o.via.array.ptr + o.via.array.size; object* const pend = o.via.array.ptr + o.via.array.size;
typename std::deque<T>::iterator it = v.begin(); typename std::deque<T>::iterator it = v.begin();
for(; p < pend; ++p, ++it) { for(; p < pend; ++p, ++it) {
p->convert(*it); p->convert(*it);
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::deque<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::deque<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename std::deque<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::deque<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const std::deque<T>& v) inline void operator<< (object::with_zone& o, const std::deque<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename std::deque<T>::const_iterator it(v.begin()); typename std::deque<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,46 +21,46 @@
#include <type_traits> #include <type_traits>
#define MSGPACK_DEFINE(...) \ #define MSGPACK_DEFINE(...) \
template <typename Packer> \ template <typename Packer> \
void msgpack_pack(Packer& pk) const \ void msgpack_pack(Packer& pk) const \
{ \ { \
msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \ msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \
} \ } \
void msgpack_unpack(msgpack::object const& o) \ void msgpack_unpack(msgpack::object const& o) \
{ \ { \
msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \ msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \
}\ }\
template <typename MSGPACK_OBJECT> \ template <typename MSGPACK_OBJECT> \
void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \ void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \
{ \ { \
msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \
} }
// MSGPACK_ADD_ENUM must be used in the global namespace. // MSGPACK_ADD_ENUM must be used in the global namespace.
#define MSGPACK_ADD_ENUM(enum) \ #define MSGPACK_ADD_ENUM(enum) \
namespace msgpack { \ namespace msgpack { \
template <> \ template <> \
inline enum& operator>> (object const& o, enum& v) \ inline enum& operator>> (object const& o, enum& v) \
{ \ { \
int tmp; \ int tmp; \
o >> tmp; \ o >> tmp; \
v = static_cast<enum>(tmp); \ v = static_cast<enum>(tmp); \
return v; \ return v; \
} \ } \
template <> \ template <> \
inline void operator<< (object::with_zone& o, const enum& v) \ inline void operator<< (object::with_zone& o, const enum& v) \
{ \ { \
int tmp = static_cast<std::underlying_type<enum>::type>(v); \ int tmp = static_cast<std::underlying_type<enum>::type>(v); \
o << tmp; \ o << tmp; \
} \ } \
namespace detail { \ namespace detail { \
template <typename Stream> \ template <typename Stream> \
struct packer_serializer<Stream, enum> { \ struct packer_serializer<Stream, enum> { \
static packer<Stream>& pack(packer<Stream>& o, const enum& v) { \ static packer<Stream>& pack(packer<Stream>& o, const enum& v) { \
return o << static_cast<std::underlying_type<enum>::type>(v); \ return o << static_cast<std::underlying_type<enum>::type>(v); \
} \ } \
}; \ }; \
} \ } \
} }
namespace msgpack { namespace msgpack {
@@ -68,100 +68,100 @@ namespace type {
template <typename Tuple, std::size_t N> template <typename Tuple, std::size_t N>
struct define_imp { struct define_imp {
template <typename Packer> template <typename Packer>
static void pack(Packer& pk, Tuple const& t) { static void pack(Packer& pk, Tuple const& t) {
define_imp<Tuple, N-1>::pack(pk, t); define_imp<Tuple, N-1>::pack(pk, t);
pk.pack(std::get<N-1>(t)); pk.pack(std::get<N-1>(t));
} }
static void unpack(msgpack::object const& o, Tuple& t) { static void unpack(msgpack::object const& o, Tuple& t) {
define_imp<Tuple, N-1>::unpack(o, t); define_imp<Tuple, N-1>::unpack(o, t);
const size_t size = o.via.array.size; const size_t size = o.via.array.size;
if(size <= N-1) { return; } if(size <= N-1) { return; }
o.via.array.ptr[N-1].convert(std::get<N-1>(t)); o.via.array.ptr[N-1].convert(std::get<N-1>(t));
} }
static void object(msgpack::object* o, msgpack::zone* z, Tuple const& t) { static void object(msgpack::object* o, msgpack::zone* z, Tuple const& t) {
define_imp<Tuple, N-1>::object(o, z, t); define_imp<Tuple, N-1>::object(o, z, t);
o->via.array.ptr[N-1] = msgpack::object(std::get<N-1>(t), z); o->via.array.ptr[N-1] = msgpack::object(std::get<N-1>(t), z);
} }
}; };
template <typename Tuple> template <typename Tuple>
struct define_imp<Tuple, 1> { struct define_imp<Tuple, 1> {
template <typename Packer> template <typename Packer>
static void pack(Packer& pk, Tuple const& t) { static void pack(Packer& pk, Tuple const& t) {
pk.pack(std::get<0>(t)); pk.pack(std::get<0>(t));
} }
static void unpack(msgpack::object const& o, Tuple& t) { static void unpack(msgpack::object const& o, Tuple& t) {
const size_t size = o.via.array.size; const size_t size = o.via.array.size;
if(size <= 0) { return; } if(size <= 0) { return; }
o.via.array.ptr[0].convert(std::get<0>(t)); o.via.array.ptr[0].convert(std::get<0>(t));
} }
static void object(msgpack::object* o, msgpack::zone* z, Tuple const& t) { static void object(msgpack::object* o, msgpack::zone* z, Tuple const& t) {
o->via.array.ptr[0] = msgpack::object(std::get<0>(t), z); o->via.array.ptr[0] = msgpack::object(std::get<0>(t), z);
} }
}; };
template <typename... Args> template <typename... Args>
struct define { struct define {
typedef define<Args...> value_type; typedef define<Args...> value_type;
typedef tuple<Args...> tuple_type; typedef tuple<Args...> tuple_type;
define(Args&... args) : define(Args&... args) :
a(args...) {} a(args...) {}
template <typename Packer> template <typename Packer>
void msgpack_pack(Packer& pk) const void msgpack_pack(Packer& pk) const
{ {
pk.pack_array(sizeof...(Args)); pk.pack_array(sizeof...(Args));
define_imp<tuple<Args&...>, sizeof...(Args)>::pack(pk, a); define_imp<tuple<Args&...>, sizeof...(Args)>::pack(pk, a);
} }
void msgpack_unpack(msgpack::object const& o) void msgpack_unpack(msgpack::object const& o)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
define_imp<tuple<Args&...>, sizeof...(Args)>::unpack(o, a); define_imp<tuple<Args&...>, sizeof...(Args)>::unpack(o, a);
} }
void msgpack_object(msgpack::object* o, msgpack::zone* z) const void msgpack_object(msgpack::object* o, msgpack::zone* z) const
{ {
o->type = type::ARRAY; o->type = type::ARRAY;
o->via.array.ptr = static_cast<object*>(z->allocate_align(sizeof(object)*sizeof...(Args))); o->via.array.ptr = static_cast<object*>(z->allocate_align(sizeof(object)*sizeof...(Args)));
o->via.array.size = sizeof...(Args); o->via.array.size = sizeof...(Args);
define_imp<tuple<Args&...>, sizeof...(Args)>::object(o, z, a); define_imp<tuple<Args&...>, sizeof...(Args)>::object(o, z, a);
} }
tuple<Args&...> a; tuple<Args&...> a;
}; };
template <> template <>
struct define<> { struct define<> {
typedef define<> value_type; typedef define<> value_type;
typedef tuple<> tuple_type; typedef tuple<> tuple_type;
template <typename Packer> template <typename Packer>
void msgpack_pack(Packer& pk) const void msgpack_pack(Packer& pk) const
{ {
pk.pack_array(0); pk.pack_array(0);
} }
void msgpack_unpack(msgpack::object const& o) void msgpack_unpack(msgpack::object const& o)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
} }
void msgpack_object(msgpack::object* o, msgpack::zone* z) const void msgpack_object(msgpack::object* o, msgpack::zone* z) const
{ {
o->type = type::ARRAY; o->type = type::ARRAY;
o->via.array.ptr = NULL; o->via.array.ptr = NULL;
o->via.array.size = 0; o->via.array.size = 0;
} }
}; };
inline define<> make_define() inline define<> make_define()
{ {
return define<>(); return define<>();
} }
template <typename... Args> template <typename... Args>
define<Args...> make_define(Args&... args) define<Args...> make_define(Args&... args)
{ {
return define<Args...>(args...); return define<Args...>(args...);
} }
} // namespace type } // namespace type

View File

@@ -26,157 +26,157 @@
namespace msgpack { namespace msgpack {
namespace type { namespace type {
// tuple // tuple
using std::get; using std::get;
using std::tuple_size; using std::tuple_size;
using std::tuple_element; using std::tuple_element;
using std::uses_allocator; using std::uses_allocator;
using std::ignore; using std::ignore;
using std::make_tuple; using std::make_tuple;
using std::tie; using std::tie;
using std::forward_as_tuple; using std::forward_as_tuple;
using std::swap; using std::swap;
template< class... Types > template< class... Types >
class tuple : public std::tuple<Types...> { class tuple : public std::tuple<Types...> {
public: public:
using base = std::tuple<Types...>; using base = std::tuple<Types...>;
using base::tuple; using base::tuple;
tuple() = default; tuple() = default;
tuple(tuple const&) = default; tuple(tuple const&) = default;
tuple(tuple&&) = default; tuple(tuple&&) = default;
template<typename... OtherTypes> template<typename... OtherTypes>
tuple(tuple<OtherTypes...> const& other):base(static_cast<std::tuple<OtherTypes...> const&>(other)) {} tuple(tuple<OtherTypes...> const& other):base(static_cast<std::tuple<OtherTypes...> const&>(other)) {}
template<typename... OtherTypes> template<typename... OtherTypes>
tuple(tuple<OtherTypes...> && other):base(static_cast<std::tuple<OtherTypes...> &&>(other)) {} tuple(tuple<OtherTypes...> && other):base(static_cast<std::tuple<OtherTypes...> &&>(other)) {}
tuple& operator=(tuple const&) = default; tuple& operator=(tuple const&) = default;
tuple& operator=(tuple&&) = default; tuple& operator=(tuple&&) = default;
template<typename... OtherTypes> template<typename... OtherTypes>
tuple& operator=(tuple<OtherTypes...> const& other) { tuple& operator=(tuple<OtherTypes...> const& other) {
*static_cast<base*>(this) = static_cast<std::tuple<OtherTypes...> const&>(other); *static_cast<base*>(this) = static_cast<std::tuple<OtherTypes...> const&>(other);
return *this; return *this;
} }
template<typename... OtherTypes> template<typename... OtherTypes>
tuple& operator=(tuple<OtherTypes...> && other) { tuple& operator=(tuple<OtherTypes...> && other) {
*static_cast<base*>(this) = static_cast<std::tuple<OtherTypes...> &&>(other); *static_cast<base*>(this) = static_cast<std::tuple<OtherTypes...> &&>(other);
return *this; return *this;
} }
template< std::size_t I> template< std::size_t I>
typename tuple_element<I, base >::type& typename tuple_element<I, base >::type&
get() { return std::get<I>(*this); } get() { return std::get<I>(*this); }
template< std::size_t I> template< std::size_t I>
typename tuple_element<I, base >::type const& typename tuple_element<I, base >::type const&
get() const { return std::get<I>(*this); } get() const { return std::get<I>(*this); }
template< std::size_t I> template< std::size_t I>
typename tuple_element<I, base >::type&& typename tuple_element<I, base >::type&&
get() && { return std::get<I>(*this); } get() && { return std::get<I>(*this); }
}; };
template< class... Tuples > template< class... Tuples >
auto tuple_cat(Tuples&&... args) -> auto tuple_cat(Tuples&&... args) ->
decltype( decltype(
std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...) std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...)
) { ) {
return std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...); return std::tuple_cat(std::forward<typename std::remove_reference<Tuples>::type::base>(args)...);
} }
} // namespace type } // namespace type
// --- Pack ( from tuple to packer stream --- // --- Pack ( from tuple to packer stream ---
template <typename Stream, typename Tuple, std::size_t N> template <typename Stream, typename Tuple, std::size_t N>
struct MsgpackTuplePacker { struct MsgpackTuplePacker {
static void pack( static void pack(
packer<Stream>& o, packer<Stream>& o,
const Tuple& v) { const Tuple& v) {
MsgpackTuplePacker<Stream, Tuple, N-1>::pack(o, v); MsgpackTuplePacker<Stream, Tuple, N-1>::pack(o, v);
o.pack(type::get<N-1>(v)); o.pack(type::get<N-1>(v));
} }
}; };
template <typename Stream, typename Tuple> template <typename Stream, typename Tuple>
struct MsgpackTuplePacker<Stream, Tuple, 1> { struct MsgpackTuplePacker<Stream, Tuple, 1> {
static void pack ( static void pack (
packer<Stream>& o, packer<Stream>& o,
const Tuple& v) { const Tuple& v) {
o.pack(type::get<0>(v)); o.pack(type::get<0>(v));
} }
}; };
template <typename Stream, typename... Args> template <typename Stream, typename... Args>
const packer<Stream>& operator<< ( const packer<Stream>& operator<< (
packer<Stream>& o, packer<Stream>& o,
const type::tuple<Args...>& v) { const type::tuple<Args...>& v) {
o.pack_array(sizeof...(Args)); o.pack_array(sizeof...(Args));
MsgpackTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v); MsgpackTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v);
return o; return o;
} }
// --- Convert from tuple to object --- // --- Convert from tuple to object ---
template <typename Tuple, std::size_t N> template <typename Tuple, std::size_t N>
struct MsgpackTupleConverter { struct MsgpackTupleConverter {
static void convert( static void convert(
object const& o, object const& o,
Tuple& v) { Tuple& v) {
MsgpackTupleConverter<Tuple, N-1>::convert(o, v); MsgpackTupleConverter<Tuple, N-1>::convert(o, v);
o.via.array.ptr[N-1].convert<typename std::remove_reference<decltype(type::get<N-1>(v))>::type>(type::get<N-1>(v)); o.via.array.ptr[N-1].convert<typename std::remove_reference<decltype(type::get<N-1>(v))>::type>(type::get<N-1>(v));
} }
}; };
template <typename Tuple> template <typename Tuple>
struct MsgpackTupleConverter<Tuple, 1> { struct MsgpackTupleConverter<Tuple, 1> {
static void convert ( static void convert (
object const& o, object const& o,
Tuple& v) { Tuple& v) {
o.via.array.ptr[0].convert<typename std::remove_reference<decltype(type::get<0>(v))>::type>(type::get<0>(v)); o.via.array.ptr[0].convert<typename std::remove_reference<decltype(type::get<0>(v))>::type>(type::get<0>(v));
} }
}; };
template <typename... Args> template <typename... Args>
type::tuple<Args...>& operator>> ( type::tuple<Args...>& operator>> (
object const& o, object const& o,
type::tuple<Args...>& v) { type::tuple<Args...>& v) {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.array.size < sizeof...(Args)) { throw type_error(); } if(o.via.array.size < sizeof...(Args)) { throw type_error(); }
MsgpackTupleConverter<decltype(v), sizeof...(Args)>::convert(o, v); MsgpackTupleConverter<decltype(v), sizeof...(Args)>::convert(o, v);
return v; return v;
} }
// --- Convert from tuple to object with zone --- // --- Convert from tuple to object with zone ---
template <typename Tuple, std::size_t N> template <typename Tuple, std::size_t N>
struct MsgpackTupleToObjectWithZone { struct MsgpackTupleToObjectWithZone {
static void convert( static void convert(
object::with_zone& o, object::with_zone& o,
const Tuple& v) { const Tuple& v) {
MsgpackTupleToObjectWithZone<Tuple, N-1>::convert(o, v); MsgpackTupleToObjectWithZone<Tuple, N-1>::convert(o, v);
o.via.array.ptr[N-1] = object(type::get<N-1>(v), o.zone); o.via.array.ptr[N-1] = object(type::get<N-1>(v), o.zone);
} }
}; };
template <typename Tuple> template <typename Tuple>
struct MsgpackTupleToObjectWithZone<Tuple, 1> { struct MsgpackTupleToObjectWithZone<Tuple, 1> {
static void convert ( static void convert (
object::with_zone& o, object::with_zone& o,
const Tuple& v) { const Tuple& v) {
o.via.array.ptr[0] = object(type::get<0>(v), o.zone); o.via.array.ptr[0] = object(type::get<0>(v), o.zone);
} }
}; };
template <typename... Args> template <typename... Args>
inline void operator<< ( inline void operator<< (
object::with_zone& o, object::with_zone& o,
type::tuple<Args...>& v) { type::tuple<Args...>& v) {
o.type = type::ARRAY; o.type = type::ARRAY;
o.via.array.ptr = static_cast<object*>(o.zone->allocate_align(sizeof(object)*sizeof...(Args))); o.via.array.ptr = static_cast<object*>(o.zone->allocate_align(sizeof(object)*sizeof...(Args)));
o.via.array.size = sizeof...(Args); o.via.array.size = sizeof...(Args);
MsgpackTupleToObjectWithZone<decltype(v), sizeof...(Args)>::convert(o, v); MsgpackTupleToObjectWithZone<decltype(v), sizeof...(Args)>::convert(o, v);
} }
} // msgpack } // msgpack

View File

@@ -28,15 +28,15 @@ namespace type {
template <typename T> template <typename T>
struct fix_int { struct fix_int {
fix_int() : value(0) { } fix_int() : value(0) { }
fix_int(T value) : value(value) { } fix_int(T value) : value(value) { }
operator T() const { return value; } operator T() const { return value; }
T get() const { return value; } T get() const { return value; }
private: private:
T value; T value;
}; };
@@ -55,115 +55,115 @@ typedef fix_int<int64_t> fix_int64;
inline type::fix_int8& operator>> (object const& o, type::fix_int8& v) inline type::fix_int8& operator>> (object const& o, type::fix_int8& v)
{ v = type::detail::convert_integer<int8_t>(o); return v; } { v = type::detail::convert_integer<int8_t>(o); return v; }
inline type::fix_int16& operator>> (object const& o, type::fix_int16& v) inline type::fix_int16& operator>> (object const& o, type::fix_int16& v)
{ v = type::detail::convert_integer<int16_t>(o); return v; } { v = type::detail::convert_integer<int16_t>(o); return v; }
inline type::fix_int32& operator>> (object const& o, type::fix_int32& v) inline type::fix_int32& operator>> (object const& o, type::fix_int32& v)
{ v = type::detail::convert_integer<int32_t>(o); return v; } { v = type::detail::convert_integer<int32_t>(o); return v; }
inline type::fix_int64& operator>> (object const& o, type::fix_int64& v) inline type::fix_int64& operator>> (object const& o, type::fix_int64& v)
{ v = type::detail::convert_integer<int64_t>(o); return v; } { v = type::detail::convert_integer<int64_t>(o); return v; }
inline type::fix_uint8& operator>> (object const& o, type::fix_uint8& v) inline type::fix_uint8& operator>> (object const& o, type::fix_uint8& v)
{ v = type::detail::convert_integer<uint8_t>(o); return v; } { v = type::detail::convert_integer<uint8_t>(o); return v; }
inline type::fix_uint16& operator>> (object const& o, type::fix_uint16& v) inline type::fix_uint16& operator>> (object const& o, type::fix_uint16& v)
{ v = type::detail::convert_integer<uint16_t>(o); return v; } { v = type::detail::convert_integer<uint16_t>(o); return v; }
inline type::fix_uint32& operator>> (object const& o, type::fix_uint32& v) inline type::fix_uint32& operator>> (object const& o, type::fix_uint32& v)
{ v = type::detail::convert_integer<uint32_t>(o); return v; } { v = type::detail::convert_integer<uint32_t>(o); return v; }
inline type::fix_uint64& operator>> (object const& o, type::fix_uint64& v) inline type::fix_uint64& operator>> (object const& o, type::fix_uint64& v)
{ v = type::detail::convert_integer<uint64_t>(o); return v; } { v = type::detail::convert_integer<uint64_t>(o); return v; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v)
{ o.pack_fix_int8(v); return o; } { o.pack_fix_int8(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int16& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int16& v)
{ o.pack_fix_int16(v); return o; } { o.pack_fix_int16(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int32& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int32& v)
{ o.pack_fix_int32(v); return o; } { o.pack_fix_int32(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v)
{ o.pack_fix_int64(v); return o; } { o.pack_fix_int64(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v)
{ o.pack_fix_uint8(v); return o; } { o.pack_fix_uint8(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint16& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint16& v)
{ o.pack_fix_uint16(v); return o; } { o.pack_fix_uint16(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint32& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint32& v)
{ o.pack_fix_uint32(v); return o; } { o.pack_fix_uint32(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v)
{ o.pack_fix_uint64(v); return o; } { o.pack_fix_uint64(v); return o; }
inline void operator<< (object& o, type::fix_int8 v) inline void operator<< (object& o, type::fix_int8 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_int16 v) inline void operator<< (object& o, type::fix_int16 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_int32 v) inline void operator<< (object& o, type::fix_int32 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_int64 v) inline void operator<< (object& o, type::fix_int64 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint8 v) inline void operator<< (object& o, type::fix_uint8 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint16 v) inline void operator<< (object& o, type::fix_uint16 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint32 v) inline void operator<< (object& o, type::fix_uint32 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint64 v) inline void operator<< (object& o, type::fix_uint64 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object::with_zone& o, type::fix_int8 v) inline void operator<< (object::with_zone& o, type::fix_int8 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_int16 v) inline void operator<< (object::with_zone& o, type::fix_int16 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_int32 v) inline void operator<< (object::with_zone& o, type::fix_int32 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_int64 v) inline void operator<< (object::with_zone& o, type::fix_int64 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint8 v) inline void operator<< (object::with_zone& o, type::fix_uint8 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint16 v) inline void operator<< (object::with_zone& o, type::fix_uint16 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint32 v) inline void operator<< (object::with_zone& o, type::fix_uint32 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint64 v) inline void operator<< (object::with_zone& o, type::fix_uint64 v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
} // namespace msgpack } // namespace msgpack

View File

@@ -29,71 +29,71 @@ namespace msgpack {
inline float& operator>> (object const& o, float& v) inline float& operator>> (object const& o, float& v)
{ {
if(o.type == type::DOUBLE) { if(o.type == type::DOUBLE) {
v = static_cast<float>(o.via.dec); v = static_cast<float>(o.via.dec);
} }
else if (o.type == type::POSITIVE_INTEGER) { else if (o.type == type::POSITIVE_INTEGER) {
v = static_cast<float>(o.via.u64); v = static_cast<float>(o.via.u64);
} }
else if (o.type == type::NEGATIVE_INTEGER) { else if (o.type == type::NEGATIVE_INTEGER) {
v = static_cast<float>(o.via.i64); v = static_cast<float>(o.via.i64);
} }
else { else {
throw type_error(); throw type_error();
} }
return v; return v;
} }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const float& v) inline packer<Stream>& operator<< (packer<Stream>& o, const float& v)
{ {
o.pack_float(v); o.pack_float(v);
return o; return o;
} }
inline double& operator>> (object const& o, double& v) inline double& operator>> (object const& o, double& v)
{ {
if(o.type == type::DOUBLE) { if(o.type == type::DOUBLE) {
v = o.via.dec; v = o.via.dec;
} }
else if (o.type == type::POSITIVE_INTEGER) { else if (o.type == type::POSITIVE_INTEGER) {
v = static_cast<double>(o.via.u64); v = static_cast<double>(o.via.u64);
} }
else if (o.type == type::NEGATIVE_INTEGER) { else if (o.type == type::NEGATIVE_INTEGER) {
v = static_cast<double>(o.via.i64); v = static_cast<double>(o.via.i64);
} }
else { else {
throw type_error(); throw type_error();
} }
return v; return v;
} }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const double& v) inline packer<Stream>& operator<< (packer<Stream>& o, const double& v)
{ {
o.pack_double(v); o.pack_double(v);
return o; return o;
} }
inline void operator<< (object& o, float v) inline void operator<< (object& o, float v)
{ {
o.type = type::DOUBLE; o.type = type::DOUBLE;
o.via.dec = static_cast<double>(v); o.via.dec = static_cast<double>(v);
} }
inline void operator<< (object& o, double v) inline void operator<< (object& o, double v)
{ {
o.type = type::DOUBLE; o.type = type::DOUBLE;
o.via.dec = v; o.via.dec = v;
} }
inline void operator<< (object::with_zone& o, float v) inline void operator<< (object::with_zone& o, float v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, double v) inline void operator<< (object::with_zone& o, double v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
} // namespace msgpack } // namespace msgpack

View File

@@ -26,251 +26,251 @@ namespace msgpack {
namespace type { namespace type {
namespace detail { namespace detail {
template <typename T, bool Signed> template <typename T, bool Signed>
struct convert_integer_sign; struct convert_integer_sign;
template <typename T> template <typename T>
struct convert_integer_sign<T, true> { struct convert_integer_sign<T, true> {
static inline T convert(object const& o) { static inline T convert(object const& o) {
if(o.type == type::POSITIVE_INTEGER) { if(o.type == type::POSITIVE_INTEGER) {
if(o.via.u64 > static_cast<uint64_t>(std::numeric_limits<T>::max())) if(o.via.u64 > static_cast<uint64_t>(std::numeric_limits<T>::max()))
{ throw type_error(); } { throw type_error(); }
return static_cast<T>(o.via.u64); return static_cast<T>(o.via.u64);
} else if(o.type == type::NEGATIVE_INTEGER) { } else if(o.type == type::NEGATIVE_INTEGER) {
if(o.via.i64 < static_cast<int64_t>(std::numeric_limits<T>::min())) if(o.via.i64 < static_cast<int64_t>(std::numeric_limits<T>::min()))
{ throw type_error(); } { throw type_error(); }
return static_cast<T>(o.via.i64); return static_cast<T>(o.via.i64);
} }
throw type_error(); throw type_error();
} }
}; };
template <typename T> template <typename T>
struct convert_integer_sign<T, false> { struct convert_integer_sign<T, false> {
static inline T convert(object const& o) { static inline T convert(object const& o) {
if(o.type == type::POSITIVE_INTEGER) { if(o.type == type::POSITIVE_INTEGER) {
if(o.via.u64 > static_cast<uint64_t>(std::numeric_limits<T>::max())) if(o.via.u64 > static_cast<uint64_t>(std::numeric_limits<T>::max()))
{ throw type_error(); } { throw type_error(); }
return static_cast<T>(o.via.u64); return static_cast<T>(o.via.u64);
} }
throw type_error(); throw type_error();
} }
}; };
template <typename T> template <typename T>
struct is_signed { struct is_signed {
static const bool value = std::numeric_limits<T>::is_signed; static const bool value = std::numeric_limits<T>::is_signed;
}; };
template <typename T> template <typename T>
static inline T convert_integer(object const& o) static inline T convert_integer(object const& o)
{ {
return detail::convert_integer_sign<T, is_signed<T>::value>::convert(o); return detail::convert_integer_sign<T, is_signed<T>::value>::convert(o);
} }
template <bool Signed> template <bool Signed>
struct pack_char_sign; struct pack_char_sign;
template <> template <>
struct pack_char_sign<true> { struct pack_char_sign<true> {
template <typename Stream> template <typename Stream>
static inline packer<Stream>& pack(packer<Stream>& o, char v) { static inline packer<Stream>& pack(packer<Stream>& o, char v) {
o.pack_int8(v); return o; o.pack_int8(v); return o;
} }
}; };
template <> template <>
struct pack_char_sign<false> { struct pack_char_sign<false> {
template <typename Stream> template <typename Stream>
static inline packer<Stream>& pack(packer<Stream>& o, char v) { static inline packer<Stream>& pack(packer<Stream>& o, char v) {
o.pack_uint8(v); return o; o.pack_uint8(v); return o;
} }
}; };
template <typename Stream> template <typename Stream>
static inline packer<Stream>& pack_char(packer<Stream>& o, char v) { static inline packer<Stream>& pack_char(packer<Stream>& o, char v) {
return pack_char_sign<is_signed<char>::value>::pack(o, v); return pack_char_sign<is_signed<char>::value>::pack(o, v);
} }
template <bool Signed> template <bool Signed>
struct object_char_sign; struct object_char_sign;
template <> template <>
struct object_char_sign<true> { struct object_char_sign<true> {
static inline void make(object& o, char v) { static inline void make(object& o, char v) {
v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v
: o.type = type::POSITIVE_INTEGER, o.via.u64 = v; : o.type = type::POSITIVE_INTEGER, o.via.u64 = v;
} }
}; };
template <> template <>
struct object_char_sign<false> { struct object_char_sign<false> {
static inline void make(object& o, char v) { static inline void make(object& o, char v) {
o.type = type::POSITIVE_INTEGER, o.via.u64 = v; o.type = type::POSITIVE_INTEGER, o.via.u64 = v;
} }
}; };
static inline void object_char(object& o, char v) { static inline void object_char(object& o, char v) {
return object_char_sign<is_signed<char>::value>::make(o, v); return object_char_sign<is_signed<char>::value>::make(o, v);
} }
} // namespace detail } // namespace detail
} // namespace type } // namespace type
inline char& operator>> (object const& o, char& v) inline char& operator>> (object const& o, char& v)
{ v = type::detail::convert_integer<char>(o); return v; } { v = type::detail::convert_integer<char>(o); return v; }
inline signed char& operator>> (object const& o, signed char& v) inline signed char& operator>> (object const& o, signed char& v)
{ v = type::detail::convert_integer<signed char>(o); return v; } { v = type::detail::convert_integer<signed char>(o); return v; }
inline signed short& operator>> (object const& o, signed short& v) inline signed short& operator>> (object const& o, signed short& v)
{ v = type::detail::convert_integer<signed short>(o); return v; } { v = type::detail::convert_integer<signed short>(o); return v; }
inline signed int& operator>> (object const& o, signed int& v) inline signed int& operator>> (object const& o, signed int& v)
{ v = type::detail::convert_integer<signed int>(o); return v; } { v = type::detail::convert_integer<signed int>(o); return v; }
inline signed long& operator>> (object const& o, signed long& v) inline signed long& operator>> (object const& o, signed long& v)
{ v = type::detail::convert_integer<signed long>(o); return v; } { v = type::detail::convert_integer<signed long>(o); return v; }
inline signed long long& operator>> (object const& o, signed long long& v) inline signed long long& operator>> (object const& o, signed long long& v)
{ v = type::detail::convert_integer<signed long long>(o); return v; } { v = type::detail::convert_integer<signed long long>(o); return v; }
inline unsigned char& operator>> (object const& o, unsigned char& v) inline unsigned char& operator>> (object const& o, unsigned char& v)
{ v = type::detail::convert_integer<unsigned char>(o); return v; } { v = type::detail::convert_integer<unsigned char>(o); return v; }
inline unsigned short& operator>> (object const& o, unsigned short& v) inline unsigned short& operator>> (object const& o, unsigned short& v)
{ v = type::detail::convert_integer<unsigned short>(o); return v; } { v = type::detail::convert_integer<unsigned short>(o); return v; }
inline unsigned int& operator>> (object const& o, unsigned int& v) inline unsigned int& operator>> (object const& o, unsigned int& v)
{ v = type::detail::convert_integer<unsigned int>(o); return v; } { v = type::detail::convert_integer<unsigned int>(o); return v; }
inline unsigned long& operator>> (object const& o, unsigned long& v) inline unsigned long& operator>> (object const& o, unsigned long& v)
{ v = type::detail::convert_integer<unsigned long>(o); return v; } { v = type::detail::convert_integer<unsigned long>(o); return v; }
inline unsigned long long& operator>> (object const& o, unsigned long long& v) inline unsigned long long& operator>> (object const& o, unsigned long long& v)
{ v = type::detail::convert_integer<unsigned long long>(o); return v; } { v = type::detail::convert_integer<unsigned long long>(o); return v; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, char v) inline packer<Stream>& operator<< (packer<Stream>& o, char v)
{ return type::detail::pack_char(o, v); } { return type::detail::pack_char(o, v); }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, signed char v) inline packer<Stream>& operator<< (packer<Stream>& o, signed char v)
{ o.pack_int8(v); return o; } { o.pack_int8(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, signed short v) inline packer<Stream>& operator<< (packer<Stream>& o, signed short v)
{ o.pack_short(v); return o; } { o.pack_short(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, signed int v) inline packer<Stream>& operator<< (packer<Stream>& o, signed int v)
{ o.pack_int(v); return o; } { o.pack_int(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, signed long v) inline packer<Stream>& operator<< (packer<Stream>& o, signed long v)
{ o.pack_long(v); return o; } { o.pack_long(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, signed long long v) inline packer<Stream>& operator<< (packer<Stream>& o, signed long long v)
{ o.pack_long_long(v); return o; } { o.pack_long_long(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, unsigned char v) inline packer<Stream>& operator<< (packer<Stream>& o, unsigned char v)
{ o.pack_uint8(v); return o; } { o.pack_uint8(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, unsigned short v) inline packer<Stream>& operator<< (packer<Stream>& o, unsigned short v)
{ o.pack_unsigned_short(v); return o; } { o.pack_unsigned_short(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, unsigned int v) inline packer<Stream>& operator<< (packer<Stream>& o, unsigned int v)
{ o.pack_unsigned_int(v); return o; } { o.pack_unsigned_int(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, unsigned long v) inline packer<Stream>& operator<< (packer<Stream>& o, unsigned long v)
{ o.pack_unsigned_long(v); return o; } { o.pack_unsigned_long(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, unsigned long long v) inline packer<Stream>& operator<< (packer<Stream>& o, unsigned long long v)
{ o.pack_unsigned_long_long(v); return o; } { o.pack_unsigned_long_long(v); return o; }
inline void operator<< (object& o, char v) inline void operator<< (object& o, char v)
{ type::detail::object_char(o, v); } { type::detail::object_char(o, v); }
inline void operator<< (object& o, signed char v) inline void operator<< (object& o, signed char v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed short v) inline void operator<< (object& o, signed short v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed int v) inline void operator<< (object& o, signed int v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed long v) inline void operator<< (object& o, signed long v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed long long v) inline void operator<< (object& o, signed long long v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned char v) inline void operator<< (object& o, unsigned char v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned short v) inline void operator<< (object& o, unsigned short v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned int v) inline void operator<< (object& o, unsigned int v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned long v) inline void operator<< (object& o, unsigned long v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned long long v) inline void operator<< (object& o, unsigned long long v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object::with_zone& o, char v) inline void operator<< (object::with_zone& o, char v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed char v) inline void operator<< (object::with_zone& o, signed char v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed short v) inline void operator<< (object::with_zone& o, signed short v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed int v) inline void operator<< (object::with_zone& o, signed int v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed long v) inline void operator<< (object::with_zone& o, signed long v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, const signed long long& v) inline void operator<< (object::with_zone& o, const signed long long& v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned char v) inline void operator<< (object::with_zone& o, unsigned char v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned short v) inline void operator<< (object::with_zone& o, unsigned short v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned int v) inline void operator<< (object::with_zone& o, unsigned int v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned long v) inline void operator<< (object::with_zone& o, unsigned long v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, const unsigned long long& v) inline void operator<< (object::with_zone& o, const unsigned long long& v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
} // namespace msgpack } // namespace msgpack

View File

@@ -27,47 +27,47 @@ namespace msgpack {
template <typename T> template <typename T>
inline std::list<T>& operator>> (object const& o, std::list<T>& v) inline std::list<T>& operator>> (object const& o, std::list<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.array.size); v.resize(o.via.array.size);
object* p = o.via.array.ptr; object* p = o.via.array.ptr;
object* const pend = o.via.array.ptr + o.via.array.size; object* const pend = o.via.array.ptr + o.via.array.size;
typename std::list<T>::iterator it = v.begin(); typename std::list<T>::iterator it = v.begin();
for(; p < pend; ++p, ++it) { for(; p < pend; ++p, ++it) {
p->convert(*it); p->convert(*it);
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::list<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::list<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename std::list<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::list<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const std::list<T>& v) inline void operator<< (object::with_zone& o, const std::list<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename std::list<T>::const_iterator it(v.begin()); typename std::list<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

View File

@@ -32,11 +32,11 @@ template <typename K, typename V>
class assoc_vector : public std::vector< std::pair<K, V> > {}; class assoc_vector : public std::vector< std::pair<K, V> > {};
namespace detail { namespace detail {
template <typename K, typename V> template <typename K, typename V>
struct pair_first_less { struct pair_first_less {
bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const
{ return x.first < y.first; } { return x.first < y.first; }
}; };
} }
} //namespace type } //namespace type
@@ -45,157 +45,157 @@ namespace detail {
template <typename K, typename V> template <typename K, typename V>
inline type::assoc_vector<K,V>& operator>> (object const& o, type::assoc_vector<K,V>& v) inline type::assoc_vector<K,V>& operator>> (object const& o, type::assoc_vector<K,V>& v)
{ {
if(o.type != type::MAP) { throw type_error(); } if(o.type != type::MAP) { throw type_error(); }
v.resize(o.via.map.size); v.resize(o.via.map.size);
object_kv* p = o.via.map.ptr; object_kv* p = o.via.map.ptr;
object_kv* const pend = o.via.map.ptr + o.via.map.size; object_kv* const pend = o.via.map.ptr + o.via.map.size;
std::pair<K, V>* it(&v.front()); std::pair<K, V>* it(&v.front());
for(; p < pend; ++p, ++it) { for(; p < pend; ++p, ++it) {
p->key.convert(it->first); p->key.convert(it->first);
p->val.convert(it->second); p->val.convert(it->second);
} }
std::sort(v.begin(), v.end(), type::detail::pair_first_less<K,V>()); std::sort(v.begin(), v.end(), type::detail::pair_first_less<K,V>());
return v; return v;
} }
template <typename Stream, typename K, typename V> template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K,V>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K,V>& v)
{ {
o.pack_map(v.size()); o.pack_map(v.size());
for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end()); for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(it->first); o.pack(it->first);
o.pack(it->second); o.pack(it->second);
} }
return o; return o;
} }
template <typename K, typename V> template <typename K, typename V>
inline void operator<< (object::with_zone& o, const type::assoc_vector<K,V>& v) inline void operator<< (object::with_zone& o, const type::assoc_vector<K,V>& v)
{ {
o.type = type::MAP; o.type = type::MAP;
if(v.empty()) { if(v.empty()) {
o.via.map.ptr = nullptr; o.via.map.ptr = nullptr;
o.via.map.size = 0; o.via.map.size = 0;
} else { } else {
object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size())); object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size()));
object_kv* const pend = p + v.size(); object_kv* const pend = p + v.size();
o.via.map.ptr = p; o.via.map.ptr = p;
o.via.map.size = v.size(); o.via.map.size = v.size();
typename type::assoc_vector<K,V>::const_iterator it(v.begin()); typename type::assoc_vector<K,V>::const_iterator it(v.begin());
do { do {
p->key = object(it->first, o.zone); p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone); p->val = object(it->second, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }
template <typename K, typename V> template <typename K, typename V>
inline std::map<K, V> operator>> (object const& o, std::map<K, V>& v) inline std::map<K, V> operator>> (object const& o, std::map<K, V>& v)
{ {
if(o.type != type::MAP) { throw type_error(); } if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr); object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size); object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) { for(; p != pend; ++p) {
K key; K key;
p->key.convert(key); p->key.convert(key);
typename std::map<K,V>::iterator it(v.lower_bound(key)); typename std::map<K,V>::iterator it(v.lower_bound(key));
if(it != v.end() && !(key < it->first)) { if(it != v.end() && !(key < it->first)) {
p->val.convert(it->second); p->val.convert(it->second);
} else { } else {
V val; V val;
p->val.convert(val); p->val.convert(val);
v.insert(it, std::pair<K,V>(key, val)); v.insert(it, std::pair<K,V>(key, val));
} }
} }
return v; return v;
} }
template <typename Stream, typename K, typename V> template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v)
{ {
o.pack_map(v.size()); o.pack_map(v.size());
for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(it->first); o.pack(it->first);
o.pack(it->second); o.pack(it->second);
} }
return o; return o;
} }
template <typename K, typename V> template <typename K, typename V>
inline void operator<< (object::with_zone& o, const std::map<K,V>& v) inline void operator<< (object::with_zone& o, const std::map<K,V>& v)
{ {
o.type = type::MAP; o.type = type::MAP;
if(v.empty()) { if(v.empty()) {
o.via.map.ptr = nullptr; o.via.map.ptr = nullptr;
o.via.map.size = 0; o.via.map.size = 0;
} else { } else {
object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size())); object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size()));
object_kv* const pend = p + v.size(); object_kv* const pend = p + v.size();
o.via.map.ptr = p; o.via.map.ptr = p;
o.via.map.size = v.size(); o.via.map.size = v.size();
typename std::map<K,V>::const_iterator it(v.begin()); typename std::map<K,V>::const_iterator it(v.begin());
do { do {
p->key = object(it->first, o.zone); p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone); p->val = object(it->second, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }
template <typename K, typename V> template <typename K, typename V>
inline std::multimap<K, V> operator>> (object const& o, std::multimap<K, V>& v) inline std::multimap<K, V> operator>> (object const& o, std::multimap<K, V>& v)
{ {
if(o.type != type::MAP) { throw type_error(); } if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr); object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size); object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) { for(; p != pend; ++p) {
std::pair<K, V> value; std::pair<K, V> value;
p->key.convert(value.first); p->key.convert(value.first);
p->val.convert(value.second); p->val.convert(value.second);
v.insert(value); v.insert(value);
} }
return v; return v;
} }
template <typename Stream, typename K, typename V> template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& v)
{ {
o.pack_map(v.size()); o.pack_map(v.size());
for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(it->first); o.pack(it->first);
o.pack(it->second); o.pack(it->second);
} }
return o; return o;
} }
template <typename K, typename V> template <typename K, typename V>
inline void operator<< (object::with_zone& o, const std::multimap<K,V>& v) inline void operator<< (object::with_zone& o, const std::multimap<K,V>& v)
{ {
o.type = type::MAP; o.type = type::MAP;
if(v.empty()) { if(v.empty()) {
o.via.map.ptr = nullptr; o.via.map.ptr = nullptr;
o.via.map.size = 0; o.via.map.size = 0;
} else { } else {
object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size())); object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size()));
object_kv* const pend = p + v.size(); object_kv* const pend = p + v.size();
o.via.map.ptr = p; o.via.map.ptr = p;
o.via.map.size = v.size(); o.via.map.size = v.size();
typename std::multimap<K,V>::const_iterator it(v.begin()); typename std::multimap<K,V>::const_iterator it(v.begin());
do { do {
p->key = object(it->first, o.zone); p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone); p->val = object(it->second, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

View File

@@ -31,31 +31,31 @@ struct nil { };
inline type::nil& operator>> (object const& o, type::nil& v) inline type::nil& operator>> (object const& o, type::nil& v)
{ {
if(o.type != type::NIL) { throw type_error(); } if(o.type != type::NIL) { throw type_error(); }
return v; return v;
} }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::nil& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::nil& v)
{ {
o.pack_nil(); o.pack_nil();
return o; return o;
} }
inline void operator<< (object& o, type::nil v) inline void operator<< (object& o, type::nil v)
{ {
o.type = type::NIL; o.type = type::NIL;
} }
inline void operator<< (object::with_zone& o, type::nil v) inline void operator<< (object::with_zone& o, type::nil v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
template <> template <>
inline void object::as<void>() const inline void object::as<void>() const
{ {
msgpack::type::nil v; msgpack::type::nil v;
convert(v); convert(v);
} }

View File

@@ -27,31 +27,31 @@ namespace msgpack {
template <typename T1, typename T2> template <typename T1, typename T2>
inline std::pair<T1, T2>& operator>> (object const& o, std::pair<T1, T2>& v) inline std::pair<T1, T2>& operator>> (object const& o, std::pair<T1, T2>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.array.size != 2) { throw type_error(); } if(o.via.array.size != 2) { throw type_error(); }
o.via.array.ptr[0].convert(v.first); o.via.array.ptr[0].convert(v.first);
o.via.array.ptr[1].convert(v.second); o.via.array.ptr[1].convert(v.second);
return v; return v;
} }
template <typename Stream, typename T1, typename T2> template <typename Stream, typename T1, typename T2>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::pair<T1, T2>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::pair<T1, T2>& v)
{ {
o.pack_array(2); o.pack_array(2);
o.pack(v.first); o.pack(v.first);
o.pack(v.second); o.pack(v.second);
return o; return o;
} }
template <typename T1, typename T2> template <typename T1, typename T2>
inline void operator<< (object::with_zone& o, const std::pair<T1, T2>& v) inline void operator<< (object::with_zone& o, const std::pair<T1, T2>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*2)); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*2));
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = 2; o.via.array.size = 2;
p[0] = object(v.first, o.zone); p[0] = object(v.first, o.zone);
p[1] = object(v.second, o.zone); p[1] = object(v.second, o.zone);
} }

View File

@@ -27,35 +27,35 @@ namespace msgpack {
namespace type { namespace type {
struct raw_ref { struct raw_ref {
raw_ref() : size(0), ptr(nullptr) {} raw_ref() : size(0), ptr(nullptr) {}
raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {} raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {}
uint32_t size; uint32_t size;
const char* ptr; const char* ptr;
std::string str() const { return std::string(ptr, size); } std::string str() const { return std::string(ptr, size); }
bool operator== (const raw_ref& x) const bool operator== (const raw_ref& x) const
{ {
return size == x.size && memcmp(ptr, x.ptr, size) == 0; return size == x.size && memcmp(ptr, x.ptr, size) == 0;
} }
bool operator!= (const raw_ref& x) const bool operator!= (const raw_ref& x) const
{ {
return !(*this != x); return !(*this != x);
} }
bool operator< (const raw_ref& x) const bool operator< (const raw_ref& x) const
{ {
if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; } if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; }
else { return size < x.size; } else { return size < x.size; }
} }
bool operator> (const raw_ref& x) const bool operator> (const raw_ref& x) const
{ {
if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; } if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; }
else { return size > x.size; } else { return size > x.size; }
} }
}; };
} // namespace type } // namespace type
@@ -63,29 +63,29 @@ struct raw_ref {
inline type::raw_ref& operator>> (object const& o, type::raw_ref& v) inline type::raw_ref& operator>> (object const& o, type::raw_ref& v)
{ {
if(o.type != type::BIN) { throw type_error(); } if(o.type != type::BIN) { throw type_error(); }
v.ptr = o.via.bin.ptr; v.ptr = o.via.bin.ptr;
v.size = o.via.bin.size; v.size = o.via.bin.size;
return v; return v;
} }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v)
{ {
o.pack_bin(v.size); o.pack_bin(v.size);
o.pack_bin_body(v.ptr, v.size); o.pack_bin_body(v.ptr, v.size);
return o; return o;
} }
inline void operator<< (object& o, const type::raw_ref& v) inline void operator<< (object& o, const type::raw_ref& v)
{ {
o.type = type::BIN; o.type = type::BIN;
o.via.bin.ptr = v.ptr; o.via.bin.ptr = v.ptr;
o.via.bin.size = v.size; o.via.bin.size = v.size;
} }
inline void operator<< (object::with_zone& o, const type::raw_ref& v) inline void operator<< (object::with_zone& o, const type::raw_ref& v)
{ static_cast<object&>(o) << v; } { static_cast<object&>(o) << v; }
} // namespace msgpack } // namespace msgpack

View File

@@ -27,92 +27,92 @@ namespace msgpack {
template <typename T> template <typename T>
inline std::set<T>& operator>> (object const& o, std::set<T>& v) inline std::set<T>& operator>> (object const& o, std::set<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size; object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr; object* const pbegin = o.via.array.ptr;
while(p > pbegin) { while(p > pbegin) {
--p; --p;
v.insert(p->as<T>()); v.insert(p->as<T>());
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::set<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::set<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename std::set<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::set<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const std::set<T>& v) inline void operator<< (object::with_zone& o, const std::set<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename std::set<T>::const_iterator it(v.begin()); typename std::set<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }
template <typename T> template <typename T>
inline std::multiset<T>& operator>> (object const& o, std::multiset<T>& v) inline std::multiset<T>& operator>> (object const& o, std::multiset<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size; object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr; object* const pbegin = o.via.array.ptr;
while(p > pbegin) { while(p > pbegin) {
--p; --p;
v.insert(p->as<T>()); v.insert(p->as<T>());
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multiset<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::multiset<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const std::multiset<T>& v) inline void operator<< (object::with_zone& o, const std::multiset<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename std::multiset<T>::const_iterator it(v.begin()); typename std::multiset<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

View File

@@ -26,42 +26,42 @@ namespace msgpack {
inline std::string& operator>> (object const& o, std::string& v) inline std::string& operator>> (object const& o, std::string& v)
{ {
switch (o.type) { switch (o.type) {
case type::BIN: case type::BIN:
v.assign(o.via.bin.ptr, o.via.bin.size); v.assign(o.via.bin.ptr, o.via.bin.size);
break; break;
case type::STR: case type::STR:
v.assign(o.via.str.ptr, o.via.str.size); v.assign(o.via.str.ptr, o.via.str.size);
break; break;
default: default:
throw type_error(); throw type_error();
break; break;
} }
return v; return v;
} }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::string& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::string& v)
{ {
o.pack_str(v.size()); o.pack_str(v.size());
o.pack_str_body(v.data(), v.size()); o.pack_str_body(v.data(), v.size());
return o; return o;
} }
inline void operator<< (object::with_zone& o, const std::string& v) inline void operator<< (object::with_zone& o, const std::string& v)
{ {
o.type = type::STR; o.type = type::STR;
char* ptr = static_cast<char*>(o.zone->allocate_align(v.size())); char* ptr = static_cast<char*>(o.zone->allocate_align(v.size()));
o.via.str.ptr = ptr; o.via.str.ptr = ptr;
o.via.str.size = static_cast<uint32_t>(v.size()); o.via.str.size = static_cast<uint32_t>(v.size());
memcpy(ptr, v.data(), v.size()); memcpy(ptr, v.data(), v.size());
} }
inline void operator<< (object& o, const std::string& v) inline void operator<< (object& o, const std::string& v)
{ {
o.type = type::STR; o.type = type::STR;
o.via.str.ptr = v.data(); o.via.str.ptr = v.data();
o.via.str.size = static_cast<uint32_t>(v.size()); o.via.str.size = static_cast<uint32_t>(v.size());
} }

View File

@@ -46,99 +46,99 @@ namespace msgpack {
template <typename K, typename V> template <typename K, typename V>
inline MSGPACK_STD_TR1::unordered_map<K, V> operator>> (object o, MSGPACK_STD_TR1::unordered_map<K, V>& v) inline MSGPACK_STD_TR1::unordered_map<K, V> operator>> (object o, MSGPACK_STD_TR1::unordered_map<K, V>& v)
{ {
if(o.type != type::MAP) { throw type_error(); } if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr); object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size); object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) { for(; p != pend; ++p) {
K key; K key;
p->key.convert(key); p->key.convert(key);
p->val.convert(v[key]); p->val.convert(v[key]);
} }
return v; return v;
} }
template <typename Stream, typename K, typename V> template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_map<K,V>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_map<K,V>& v)
{ {
o.pack_map(v.size()); o.pack_map(v.size());
for(typename MSGPACK_STD_TR1::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end()); for(typename MSGPACK_STD_TR1::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(it->first); o.pack(it->first);
o.pack(it->second); o.pack(it->second);
} }
return o; return o;
} }
template <typename K, typename V> template <typename K, typename V>
inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_map<K,V>& v) inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_map<K,V>& v)
{ {
o.type = type::MAP; o.type = type::MAP;
if(v.empty()) { if(v.empty()) {
o.via.map.ptr = nullptr; o.via.map.ptr = nullptr;
o.via.map.size = 0; o.via.map.size = 0;
} else { } else {
object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size())); object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size()));
object_kv* const pend = p + v.size(); object_kv* const pend = p + v.size();
o.via.map.ptr = p; o.via.map.ptr = p;
o.via.map.size = v.size(); o.via.map.size = v.size();
typename MSGPACK_STD_TR1::unordered_map<K,V>::const_iterator it(v.begin()); typename MSGPACK_STD_TR1::unordered_map<K,V>::const_iterator it(v.begin());
do { do {
p->key = object(it->first, o.zone); p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone); p->val = object(it->second, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }
template <typename K, typename V> template <typename K, typename V>
inline MSGPACK_STD_TR1::unordered_multimap<K, V> operator>> (object o, MSGPACK_STD_TR1::unordered_multimap<K, V>& v) inline MSGPACK_STD_TR1::unordered_multimap<K, V> operator>> (object o, MSGPACK_STD_TR1::unordered_multimap<K, V>& v)
{ {
if(o.type != type::MAP) { throw type_error(); } if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr); object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size); object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) { for(; p != pend; ++p) {
std::pair<K, V> value; std::pair<K, V> value;
p->key.convert(value.first); p->key.convert(value.first);
p->val.convert(value.second); p->val.convert(value.second);
v.insert(value); v.insert(value);
} }
return v; return v;
} }
template <typename Stream, typename K, typename V> template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_multimap<K,V>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_multimap<K,V>& v)
{ {
o.pack_map(v.size()); o.pack_map(v.size());
for(typename MSGPACK_STD_TR1::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end()); for(typename MSGPACK_STD_TR1::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(it->first); o.pack(it->first);
o.pack(it->second); o.pack(it->second);
} }
return o; return o;
} }
template <typename K, typename V> template <typename K, typename V>
inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_multimap<K,V>& v) inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_multimap<K,V>& v)
{ {
o.type = type::MAP; o.type = type::MAP;
if(v.empty()) { if(v.empty()) {
o.via.map.ptr = nullptr; o.via.map.ptr = nullptr;
o.via.map.size = 0; o.via.map.size = 0;
} else { } else {
object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size())); object_kv* p = static_cast<object_kv*>(o.zone->allocate_align(sizeof(object_kv)*v.size()));
object_kv* const pend = p + v.size(); object_kv* const pend = p + v.size();
o.via.map.ptr = p; o.via.map.ptr = p;
o.via.map.size = v.size(); o.via.map.size = v.size();
typename MSGPACK_STD_TR1::unordered_multimap<K,V>::const_iterator it(v.begin()); typename MSGPACK_STD_TR1::unordered_multimap<K,V>::const_iterator it(v.begin());
do { do {
p->key = object(it->first, o.zone); p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone); p->val = object(it->second, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

View File

@@ -45,92 +45,92 @@ namespace msgpack {
template <typename T> template <typename T>
inline MSGPACK_STD_TR1::unordered_set<T>& operator>> (object o, MSGPACK_STD_TR1::unordered_set<T>& v) inline MSGPACK_STD_TR1::unordered_set<T>& operator>> (object o, MSGPACK_STD_TR1::unordered_set<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size; object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr; object* const pbegin = o.via.array.ptr;
while(p > pbegin) { while(p > pbegin) {
--p; --p;
v.insert(p->as<T>()); v.insert(p->as<T>());
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_set<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_set<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename MSGPACK_STD_TR1::unordered_set<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename MSGPACK_STD_TR1::unordered_set<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_set<T>& v) inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_set<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename MSGPACK_STD_TR1::unordered_set<T>::const_iterator it(v.begin()); typename MSGPACK_STD_TR1::unordered_set<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }
template <typename T> template <typename T>
inline MSGPACK_STD_TR1::unordered_multiset<T>& operator>> (object o, MSGPACK_STD_TR1::unordered_multiset<T>& v) inline MSGPACK_STD_TR1::unordered_multiset<T>& operator>> (object o, MSGPACK_STD_TR1::unordered_multiset<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size; object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr; object* const pbegin = o.via.array.ptr;
while(p > pbegin) { while(p > pbegin) {
--p; --p;
v.insert(p->as<T>()); v.insert(p->as<T>());
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_multiset<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const MSGPACK_STD_TR1::unordered_multiset<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename MSGPACK_STD_TR1::unordered_multiset<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename MSGPACK_STD_TR1::unordered_multiset<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_multiset<T>& v) inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_multiset<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename MSGPACK_STD_TR1::unordered_multiset<T>::const_iterator it(v.begin()); typename MSGPACK_STD_TR1::unordered_multiset<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

View File

@@ -27,51 +27,51 @@ namespace msgpack {
template <typename T> template <typename T>
inline std::vector<T>& operator>> (object const& o, std::vector<T>& v) inline std::vector<T>& operator>> (object const& o, std::vector<T>& v)
{ {
if(o.type != type::ARRAY) { throw type_error(); } if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.array.size); v.resize(o.via.array.size);
if(o.via.array.size > 0) { if(o.via.array.size > 0) {
object* p = o.via.array.ptr; object* p = o.via.array.ptr;
object* const pend = o.via.array.ptr + o.via.array.size; object* const pend = o.via.array.ptr + o.via.array.size;
T* it = &v[0]; T* it = &v[0];
do { do {
p->convert(*it); p->convert(*it);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
return v; return v;
} }
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v) inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v)
{ {
o.pack_array(v.size()); o.pack_array(v.size());
for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end()); for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) { it != it_end; ++it) {
o.pack(*it); o.pack(*it);
} }
return o; return o;
} }
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const std::vector<T>& v) inline void operator<< (object::with_zone& o, const std::vector<T>& v)
{ {
o.type = type::ARRAY; o.type = type::ARRAY;
if(v.empty()) { if(v.empty()) {
o.via.array.ptr = nullptr; o.via.array.ptr = nullptr;
o.via.array.size = 0; o.via.array.size = 0;
} else { } else {
object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size())); object* p = static_cast<object*>(o.zone->allocate_align(sizeof(object)*v.size()));
object* const pend = p + v.size(); object* const pend = p + v.size();
o.via.array.ptr = p; o.via.array.ptr = p;
o.via.array.size = v.size(); o.via.array.size = v.size();
typename std::vector<T>::const_iterator it(v.begin()); typename std::vector<T>::const_iterator it(v.begin());
do { do {
*p = object(*it, o.zone); *p = object(*it, o.zone);
++p; ++p;
++it; ++it;
} while(p < pend); } while(p < pend);
} }
} }

View File

@@ -42,27 +42,27 @@ namespace msgpack {
template <typename T> template <typename T>
struct unique_ptr : std::auto_ptr<T> { struct unique_ptr : std::auto_ptr<T> {
explicit unique_ptr(T* p = 0) throw() : std::auto_ptr<T>(p) {} explicit unique_ptr(T* p = 0) throw() : std::auto_ptr<T>(p) {}
unique_ptr(unique_ptr& a) throw() : std::auto_ptr<T>(a) {} unique_ptr(unique_ptr& a) throw() : std::auto_ptr<T>(a) {}
template<class Y> template<class Y>
unique_ptr (unique_ptr<Y>& a) throw() : std::auto_ptr<T>(a) {} unique_ptr (unique_ptr<Y>& a) throw() : std::auto_ptr<T>(a) {}
}; };
template <typename T> template <typename T>
T& move(T& t) T& move(T& t)
{ {
return t; return t;
} }
template <typename T> template <typename T>
T const& move(T const& t) T const& move(T const& t)
{ {
return t; return t;
} }
template <bool P, typename T = void> template <bool P, typename T = void>
struct enable_if { struct enable_if {
typedef T type; typedef T type;
}; };
template <typename T> template <typename T>
@@ -78,15 +78,15 @@ struct enable_if<false, T> {
#include <tuple> #include <tuple>
namespace msgpack { namespace msgpack {
// unique_ptr // unique_ptr
using std::unique_ptr; using std::unique_ptr;
// using std::make_unique; // since C++14 // using std::make_unique; // since C++14
using std::hash; using std::hash;
// utility // utility
using std::move; using std::move;
using std::swap; using std::swap;
using std::enable_if; using std::enable_if;
} // msgpack } // msgpack

File diff suppressed because it is too large Load Diff

View File

@@ -36,182 +36,182 @@ namespace msgpack {
class zone { class zone {
private: private:
struct finalizer { struct finalizer {
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {} finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
void operator()() { m_func(m_data); } void operator()() { m_func(m_data); }
void (*m_func)(void*); void (*m_func)(void*);
void* m_data; void* m_data;
}; };
struct finalizer_array { struct finalizer_array {
finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {} finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {}
void call() { void call() {
finalizer* fin = m_tail; finalizer* fin = m_tail;
for(; fin != m_array; --fin) (*(fin-1))(); for(; fin != m_array; --fin) (*(fin-1))();
} }
~finalizer_array() { ~finalizer_array() {
call(); call();
::free(m_array); ::free(m_array);
} }
void clear() { void clear() {
call(); call();
m_tail = m_array; m_tail = m_array;
} }
void push(void (*func)(void* data), void* data) void push(void (*func)(void* data), void* data)
{ {
finalizer* fin = m_tail; finalizer* fin = m_tail;
if(fin == m_end) { if(fin == m_end) {
push_expand(func, data); push_expand(func, data);
return; return;
} }
fin->m_func = func; fin->m_func = func;
fin->m_data = data; fin->m_data = data;
++m_tail; ++m_tail;
} }
void push_expand(void (*func)(void*), void* data) { void push_expand(void (*func)(void*), void* data) {
const size_t nused = m_end - m_array; const size_t nused = m_end - m_array;
size_t nnext; size_t nnext;
if(nused == 0) { if(nused == 0) {
nnext = (sizeof(finalizer) < 72/2) ? nnext = (sizeof(finalizer) < 72/2) ?
72 / sizeof(finalizer) : 8; 72 / sizeof(finalizer) : 8;
} else { } else {
nnext = nused * 2; nnext = nused * 2;
} }
finalizer* tmp = finalizer* tmp =
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext)); static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
if(!tmp) { if(!tmp) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_array = tmp; m_array = tmp;
m_end = tmp + nnext; m_end = tmp + nnext;
m_tail = tmp + nused; m_tail = tmp + nused;
new (m_tail) finalizer(func, data); new (m_tail) finalizer(func, data);
++m_tail; ++m_tail;
} }
finalizer* m_tail; finalizer* m_tail;
finalizer* m_end; finalizer* m_end;
finalizer* m_array; finalizer* m_array;
}; };
struct chunk { struct chunk {
chunk* m_next; chunk* m_next;
}; };
struct chunk_list { struct chunk_list {
chunk_list(size_t chunk_size) chunk_list(size_t chunk_size)
{ {
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size)); chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
if(!c) { if(!c) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_head = c; m_head = c;
m_free = chunk_size; m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk); m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = nullptr; c->m_next = nullptr;
} }
~chunk_list() ~chunk_list()
{ {
chunk* c = m_head; chunk* c = m_head;
while(true) { while(true) {
chunk* n = c->m_next; chunk* n = c->m_next;
::free(c); ::free(c);
if(n) { if(n) {
c = n; c = n;
} else { } else {
break; break;
} }
} }
} }
void clear(size_t chunk_size) void clear(size_t chunk_size)
{ {
chunk* c = m_head; chunk* c = m_head;
while(true) { while(true) {
chunk* n = c->m_next; chunk* n = c->m_next;
if(n) { if(n) {
::free(c); ::free(c);
c = n; c = n;
} else { } else {
m_head = c; m_head = c;
break; break;
} }
} }
m_head->m_next = nullptr; m_head->m_next = nullptr;
m_free = chunk_size; m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk); m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
} }
size_t m_free; size_t m_free;
char* m_ptr; char* m_ptr;
chunk* m_head; chunk* m_head;
}; };
size_t m_chunk_size; size_t m_chunk_size;
chunk_list m_chunk_list; chunk_list m_chunk_list;
finalizer_array m_finalizer_array; finalizer_array m_finalizer_array;
public: public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept; zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept;
public: public:
static zone* create(size_t chunk_size); static zone* create(size_t chunk_size);
static void destroy(zone* zone); static void destroy(zone* zone);
void* allocate_align(size_t size); void* allocate_align(size_t size);
void* allocate_no_align(size_t size); void* allocate_no_align(size_t size);
void push_finalizer(void (*func)(void*), void* data); void push_finalizer(void (*func)(void*), void* data);
template <typename T> template <typename T>
void push_finalizer(msgpack::unique_ptr<T> obj); void push_finalizer(msgpack::unique_ptr<T> obj);
void clear(); void clear();
void swap(zone& o); void swap(zone& o);
static void* operator new(std::size_t size) throw(std::bad_alloc) static void* operator new(std::size_t size) throw(std::bad_alloc)
{ {
void* p = ::malloc(size); void* p = ::malloc(size);
if (!p) throw std::bad_alloc(); if (!p) throw std::bad_alloc();
return p; return p;
} }
static void operator delete(void *p) throw() static void operator delete(void *p) throw()
{ {
::free(p); ::free(p);
} }
static void* operator new(std::size_t size, void* mem) throw() static void* operator new(std::size_t size, void* mem) throw()
{ {
return mem; return mem;
} }
static void operator delete(void *p, void* mem) throw() static void operator delete(void *p, void* mem) throw()
{ {
} }
template <typename T, typename... Args> template <typename T, typename... Args>
T* allocate(Args... args); T* allocate(Args... args);
private: private:
void undo_allocate(size_t size); void undo_allocate(size_t size);
template <typename T> template <typename T>
static void object_destructor(void* obj); static void object_destructor(void* obj);
void* allocate_expand(size_t size); void* allocate_expand(size_t size);
}; };
inline zone* zone::create(size_t chunk_size) inline zone* zone::create(size_t chunk_size)
{ {
zone* z = static_cast<zone*>(::malloc(sizeof(zone) + chunk_size)); zone* z = static_cast<zone*>(::malloc(sizeof(zone) + chunk_size));
if (!z) { if (!z) {
return nullptr; return nullptr;
} }
new (z) zone(chunk_size); new (z) zone(chunk_size);
return z; return z;
} }
inline void zone::destroy(zone* z) inline void zone::destroy(zone* z)
{ {
z->~zone(); z->~zone();
::free(z); ::free(z);
} }
inline zone::zone(size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size) inline zone::zone(size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
@@ -220,99 +220,99 @@ inline zone::zone(size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_
inline void* zone::allocate_align(size_t size) inline void* zone::allocate_align(size_t size)
{ {
return allocate_no_align( return allocate_no_align(
((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
} }
inline void* zone::allocate_no_align(size_t size) inline void* zone::allocate_no_align(size_t size)
{ {
if(m_chunk_list.m_free < size) { if(m_chunk_list.m_free < size) {
return allocate_expand(size); return allocate_expand(size);
} }
char* ptr = m_chunk_list.m_ptr; char* ptr = m_chunk_list.m_ptr;
m_chunk_list.m_free -= size; m_chunk_list.m_free -= size;
m_chunk_list.m_ptr += size; m_chunk_list.m_ptr += size;
return ptr; return ptr;
} }
inline void* zone::allocate_expand(size_t size) inline void* zone::allocate_expand(size_t size)
{ {
chunk_list* const cl = &m_chunk_list; chunk_list* const cl = &m_chunk_list;
size_t sz = m_chunk_size; size_t sz = m_chunk_size;
while(sz < size) { while(sz < size) {
sz *= 2; sz *= 2;
} }
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz)); chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
if (!c) return nullptr; if (!c) return nullptr;
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk); char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = cl->m_head; c->m_next = cl->m_head;
cl->m_head = c; cl->m_head = c;
cl->m_free = sz - size; cl->m_free = sz - size;
cl->m_ptr = ptr + size; cl->m_ptr = ptr + size;
return ptr; return ptr;
} }
inline void zone::push_finalizer(void (*func)(void*), void* data) inline void zone::push_finalizer(void (*func)(void*), void* data)
{ {
m_finalizer_array.push(func, data); m_finalizer_array.push(func, data);
} }
template <typename T> template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{ {
m_finalizer_array.push(&zone::object_destructor<T>, obj.get()); m_finalizer_array.push(&zone::object_destructor<T>, obj.get());
obj.release(); obj.release();
} }
inline void zone::clear() inline void zone::clear()
{ {
m_finalizer_array.clear(); m_finalizer_array.clear();
m_chunk_list.clear(m_chunk_size); m_chunk_list.clear(m_chunk_size);
} }
inline void zone::swap(zone& o) inline void zone::swap(zone& o)
{ {
std::swap(*this, o); std::swap(*this, o);
} }
template <typename T> template <typename T>
void zone::object_destructor(void* obj) void zone::object_destructor(void* obj)
{ {
reinterpret_cast<T*>(obj)->~T(); reinterpret_cast<T*>(obj)->~T();
} }
inline void zone::undo_allocate(size_t size) inline void zone::undo_allocate(size_t size)
{ {
m_chunk_list.m_ptr -= size; m_chunk_list.m_ptr -= size;
m_chunk_list.m_free += size; m_chunk_list.m_free += size;
} }
template <typename T, typename... Args> template <typename T, typename... Args>
T* zone::allocate(Args... args) T* zone::allocate(Args... args)
{ {
void* x = allocate_align(sizeof(T)); void* x = allocate_align(sizeof(T));
try { try {
m_finalizer_array.push(&zone::object_destructor<T>, x); m_finalizer_array.push(&zone::object_destructor<T>, x);
} catch (...) { } catch (...) {
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
try { try {
return new (x) T(args...); return new (x) T(args...);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; --m_finalizer_array.m_tail;
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
} }
} // namespace msgpack } // namespace msgpack

View File

@@ -33,7 +33,7 @@ extern "C" {
static inline int msgpack_fbuffer_write(void* data, const char* buf, unsigned int len) static inline int msgpack_fbuffer_write(void* data, const char* buf, unsigned int len)
{ {
return (1 == fwrite(buf, len, 1, (FILE *)data)) ? 0 : -1; return (1 == fwrite(buf, len, 1, (FILE *)data)) ? 0 : -1;
} }
/** @} */ /** @} */

View File

@@ -26,27 +26,27 @@ namespace msgpack {
class fbuffer { class fbuffer {
public: public:
explicit fbuffer(FILE* file) : m_file(file) { } explicit fbuffer(FILE* file) : m_file(file) { }
public: public:
void write(const char* buf, unsigned int len) void write(const char* buf, unsigned int len)
{ {
if (1 != fwrite(buf, len, 1, m_file)) { if (1 != fwrite(buf, len, 1, m_file)) {
throw std::runtime_error("fwrite() failed"); throw std::runtime_error("fwrite() failed");
} }
} }
FILE* file() const FILE* file() const
{ {
return m_file; return m_file;
} }
private: private:
fbuffer(const fbuffer&); fbuffer(const fbuffer&);
fbuffer& operator= (const fbuffer&); fbuffer& operator= (const fbuffer&);
private: private:
FILE* m_file; FILE* m_file;
}; };

View File

@@ -33,15 +33,15 @@ extern "C" {
*/ */
typedef enum { typedef enum {
MSGPACK_OBJECT_NIL = 0x00, MSGPACK_OBJECT_NIL = 0x00,
MSGPACK_OBJECT_BOOLEAN = 0x01, MSGPACK_OBJECT_BOOLEAN = 0x01,
MSGPACK_OBJECT_POSITIVE_INTEGER = 0x02, MSGPACK_OBJECT_POSITIVE_INTEGER = 0x02,
MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x03, MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x03,
MSGPACK_OBJECT_DOUBLE = 0x04, MSGPACK_OBJECT_DOUBLE = 0x04,
MSGPACK_OBJECT_STR = 0x05, MSGPACK_OBJECT_STR = 0x05,
MSGPACK_OBJECT_ARRAY = 0x06, MSGPACK_OBJECT_ARRAY = 0x06,
MSGPACK_OBJECT_MAP = 0x07, MSGPACK_OBJECT_MAP = 0x07,
MSGPACK_OBJECT_BIN = 0x08 MSGPACK_OBJECT_BIN = 0x08
} msgpack_object_type; } msgpack_object_type;
@@ -49,44 +49,44 @@ struct msgpack_object;
struct msgpack_object_kv; struct msgpack_object_kv;
typedef struct { typedef struct {
uint32_t size; uint32_t size;
struct msgpack_object* ptr; struct msgpack_object* ptr;
} msgpack_object_array; } msgpack_object_array;
typedef struct { typedef struct {
uint32_t size; uint32_t size;
struct msgpack_object_kv* ptr; struct msgpack_object_kv* ptr;
} msgpack_object_map; } msgpack_object_map;
typedef struct { typedef struct {
uint32_t size; uint32_t size;
const char* ptr; const char* ptr;
} msgpack_object_str; } msgpack_object_str;
typedef struct { typedef struct {
uint32_t size; uint32_t size;
const char* ptr; const char* ptr;
} msgpack_object_bin; } msgpack_object_bin;
typedef union { typedef union {
bool boolean; bool boolean;
uint64_t u64; uint64_t u64;
int64_t i64; int64_t i64;
double dec; double dec;
msgpack_object_array array; msgpack_object_array array;
msgpack_object_map map; msgpack_object_map map;
msgpack_object_str str; msgpack_object_str str;
msgpack_object_bin bin; msgpack_object_bin bin;
} msgpack_object_union; } msgpack_object_union;
typedef struct msgpack_object { typedef struct msgpack_object {
msgpack_object_type type; msgpack_object_type type;
msgpack_object_union via; msgpack_object_union via;
} msgpack_object; } msgpack_object;
typedef struct msgpack_object_kv { typedef struct msgpack_object_kv {
msgpack_object key; msgpack_object key;
msgpack_object val; msgpack_object val;
} msgpack_object_kv; } msgpack_object_kv;

View File

@@ -34,17 +34,17 @@ class type_error : public std::bad_cast { };
namespace type { namespace type {
enum object_type { enum object_type {
NIL = MSGPACK_OBJECT_NIL, NIL = MSGPACK_OBJECT_NIL,
BOOLEAN = MSGPACK_OBJECT_BOOLEAN, BOOLEAN = MSGPACK_OBJECT_BOOLEAN,
POSITIVE_INTEGER = MSGPACK_OBJECT_POSITIVE_INTEGER, POSITIVE_INTEGER = MSGPACK_OBJECT_POSITIVE_INTEGER,
NEGATIVE_INTEGER = MSGPACK_OBJECT_NEGATIVE_INTEGER, NEGATIVE_INTEGER = MSGPACK_OBJECT_NEGATIVE_INTEGER,
DOUBLE = MSGPACK_OBJECT_DOUBLE, DOUBLE = MSGPACK_OBJECT_DOUBLE,
STR = MSGPACK_OBJECT_STR, STR = MSGPACK_OBJECT_STR,
BIN = MSGPACK_OBJECT_BIN, BIN = MSGPACK_OBJECT_BIN,
ARRAY = MSGPACK_OBJECT_ARRAY, ARRAY = MSGPACK_OBJECT_ARRAY,
MAP = MSGPACK_OBJECT_MAP MAP = MSGPACK_OBJECT_MAP
}; };
} }
@@ -52,95 +52,95 @@ struct object;
struct object_kv; struct object_kv;
struct object_array { struct object_array {
uint32_t size; uint32_t size;
object* ptr; object* ptr;
}; };
struct object_map { struct object_map {
uint32_t size; uint32_t size;
object_kv* ptr; object_kv* ptr;
}; };
struct object_str { struct object_str {
uint32_t size; uint32_t size;
const char* ptr; const char* ptr;
}; };
struct object_bin { struct object_bin {
uint32_t size; uint32_t size;
const char* ptr; const char* ptr;
}; };
struct object { struct object {
union union_type { union union_type {
bool boolean; bool boolean;
uint64_t u64; uint64_t u64;
int64_t i64; int64_t i64;
double dec; double dec;
object_array array; object_array array;
object_map map; object_map map;
object_str str; object_str str;
object_bin bin; object_bin bin;
}; };
type::object_type type; type::object_type type;
union_type via; union_type via;
bool is_nil() const { return type == type::NIL; } bool is_nil() const { return type == type::NIL; }
template <typename T> template <typename T>
T as() const; T as() const;
template <typename T> template <typename T>
void convert(T& v) const; void convert(T& v) const;
template <typename T> template <typename T>
void convert(T* v) const; void convert(T* v) const;
object(); object();
object(msgpack_object o); object(msgpack_object o);
template <typename T> template <typename T>
explicit object(const T& v); explicit object(const T& v);
template <typename T> template <typename T>
object(const T& v, zone* z); object(const T& v, zone* z);
template <typename T> template <typename T>
object& operator=(const T& v); object& operator=(const T& v);
operator msgpack_object() const; operator msgpack_object() const;
struct with_zone; struct with_zone;
private: private:
struct implicit_type; struct implicit_type;
public: public:
implicit_type convert() const; implicit_type convert() const;
}; };
struct object_kv { struct object_kv {
object key; object key;
object val; object val;
}; };
struct object::with_zone : object { struct object::with_zone : object {
with_zone(msgpack::zone* zone) : zone(zone) { } with_zone(msgpack::zone* zone) : zone(zone) { }
msgpack::zone* zone; msgpack::zone* zone;
private: private:
with_zone(); with_zone();
}; };
struct object::implicit_type { struct object::implicit_type {
implicit_type(object const& o) : obj(o) { } implicit_type(object const& o) : obj(o) { }
~implicit_type() { } ~implicit_type() { }
template <typename T> template <typename T>
operator T() { return obj.as<T>(); } operator T() { return obj.as<T>(); }
private: private:
object const& obj; object const& obj;
}; };
@@ -148,22 +148,22 @@ private:
template <typename Type> template <typename Type>
class define : public Type { class define : public Type {
public: public:
typedef Type msgpack_type; typedef Type msgpack_type;
typedef define<Type> define_type; typedef define<Type> define_type;
define() {} define() {}
define(const msgpack_type& v) : msgpack_type(v) {} define(const msgpack_type& v) : msgpack_type(v) {}
template <typename Packer> template <typename Packer>
void msgpack_pack(Packer& o) const void msgpack_pack(Packer& o) const
{ {
o << static_cast<const msgpack_type&>(*this); o << static_cast<const msgpack_type&>(*this);
} }
void msgpack_unpack(object const& o) void msgpack_unpack(object const& o)
{ {
o >> static_cast<msgpack_type&>(*this); o >> static_cast<msgpack_type&>(*this);
} }
}; };
@@ -171,31 +171,31 @@ template <typename Stream>
template <typename T> template <typename T>
inline packer<Stream>& packer<Stream>::pack(const T& v) inline packer<Stream>& packer<Stream>::pack(const T& v)
{ {
*this << v; *this << v;
return *this; return *this;
} }
inline object& operator>> (object const& o, object& v) inline object& operator>> (object const& o, object& v)
{ {
v = o; v = o;
return v; return v;
} }
// convert operator // convert operator
template <typename T> template <typename T>
inline T& operator>> (object const& o, T& v) inline T& operator>> (object const& o, T& v)
{ {
v.msgpack_unpack(o.convert()); v.msgpack_unpack(o.convert());
return v; return v;
} }
namespace detail { namespace detail {
template <typename Stream, typename T> template <typename Stream, typename T>
struct packer_serializer { struct packer_serializer {
static packer<Stream>& pack(packer<Stream>& o, const T& v) { static packer<Stream>& pack(packer<Stream>& o, const T& v) {
v.msgpack_pack(o); v.msgpack_pack(o);
return o; return o;
} }
}; };
} }
@@ -203,94 +203,94 @@ struct packer_serializer {
template <typename Stream, typename T> template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const T& v) inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
{ {
return detail::packer_serializer<Stream, T>::pack(o, v); return detail::packer_serializer<Stream, T>::pack(o, v);
} }
// deconvert operator // deconvert operator
template <typename T> template <typename T>
inline void operator<< (object::with_zone& o, const T& v) inline void operator<< (object::with_zone& o, const T& v)
{ {
v.msgpack_object(static_cast<object*>(&o), o.zone); v.msgpack_object(static_cast<object*>(&o), o.zone);
} }
inline bool operator==(const object& x, const object& y) inline bool operator==(const object& x, const object& y)
{ {
if(x.type != y.type) { return false; } if(x.type != y.type) { return false; }
switch(x.type) { switch(x.type) {
case type::NIL: case type::NIL:
return true; return true;
case type::BOOLEAN: case type::BOOLEAN:
return x.via.boolean == y.via.boolean; return x.via.boolean == y.via.boolean;
case type::POSITIVE_INTEGER: case type::POSITIVE_INTEGER:
return x.via.u64 == y.via.u64; return x.via.u64 == y.via.u64;
case type::NEGATIVE_INTEGER: case type::NEGATIVE_INTEGER:
return x.via.i64 == y.via.i64; return x.via.i64 == y.via.i64;
case type::DOUBLE: case type::DOUBLE:
return x.via.dec == y.via.dec; return x.via.dec == y.via.dec;
case type::STR: case type::STR:
return x.via.str.size == y.via.str.size && return x.via.str.size == y.via.str.size &&
memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0; memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0;
case type::BIN: case type::BIN:
return x.via.bin.size == y.via.bin.size && return x.via.bin.size == y.via.bin.size &&
memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0; memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
case type::ARRAY: case type::ARRAY:
if(x.via.array.size != y.via.array.size) { if(x.via.array.size != y.via.array.size) {
return false; return false;
} else if(x.via.array.size == 0) { } else if(x.via.array.size == 0) {
return true; return true;
} else { } else {
object* px = x.via.array.ptr; object* px = x.via.array.ptr;
object* const pxend = x.via.array.ptr + x.via.array.size; object* const pxend = x.via.array.ptr + x.via.array.size;
object* py = y.via.array.ptr; object* py = y.via.array.ptr;
do { do {
if(!(*px == *py)) { if(!(*px == *py)) {
return false; return false;
} }
++px; ++px;
++py; ++py;
} while(px < pxend); } while(px < pxend);
return true; return true;
} }
case type::MAP: case type::MAP:
if(x.via.map.size != y.via.map.size) { if(x.via.map.size != y.via.map.size) {
return false; return false;
} else if(x.via.map.size == 0) { } else if(x.via.map.size == 0) {
return true; return true;
} else { } else {
object_kv* px = x.via.map.ptr; object_kv* px = x.via.map.ptr;
object_kv* const pxend = x.via.map.ptr + x.via.map.size; object_kv* const pxend = x.via.map.ptr + x.via.map.size;
object_kv* py = y.via.map.ptr; object_kv* py = y.via.map.ptr;
do { do {
if(!(px->key == py->key) || !(px->val == py->val)) { if(!(px->key == py->key) || !(px->val == py->val)) {
return false; return false;
} }
++px; ++px;
++py; ++py;
} while(px < pxend); } while(px < pxend);
return true; return true;
} }
default: default:
return false; return false;
} }
} }
template <typename T> template <typename T>
inline bool operator==(const object& x, const T& y) inline bool operator==(const object& x, const T& y)
try { try {
return x == object(y); return x == object(y);
} catch (msgpack::type_error&) { } catch (msgpack::type_error&) {
return false; return false;
} }
inline bool operator!=(const object& x, const object& y) inline bool operator!=(const object& x, const object& y)
@@ -311,76 +311,76 @@ inline bool operator!=(const T& y, const object& x)
inline object::implicit_type object::convert() const inline object::implicit_type object::convert() const
{ {
return implicit_type(*this); return implicit_type(*this);
} }
template <typename T> template <typename T>
inline void object::convert(T& v) const inline void object::convert(T& v) const
{ {
*this >> v; *this >> v;
} }
template <typename T> template <typename T>
inline void object::convert(T* v) const inline void object::convert(T* v) const
{ {
convert(*v); convert(*v);
} }
template <typename T> template <typename T>
inline T object::as() const inline T object::as() const
{ {
T v; T v;
convert(v); convert(v);
return v; return v;
} }
inline object::object() inline object::object()
{ {
type = type::NIL; type = type::NIL;
} }
template <typename T> template <typename T>
inline object::object(const T& v) inline object::object(const T& v)
{ {
*this << v; *this << v;
} }
template <typename T> template <typename T>
inline object& object::operator=(const T& v) inline object& object::operator=(const T& v)
{ {
*this = object(v); *this = object(v);
return *this; return *this;
} }
template <typename T> template <typename T>
object::object(const T& v, zone* z) object::object(const T& v, zone* z)
{ {
with_zone oz(z); with_zone oz(z);
oz << v; oz << v;
type = oz.type; type = oz.type;
via = oz.via; via = oz.via;
} }
inline object::object(msgpack_object o) inline object::object(msgpack_object o)
{ {
// FIXME beter way? // FIXME beter way?
::memcpy(this, &o, sizeof(o)); ::memcpy(this, &o, sizeof(o));
} }
inline void operator<< (object& o, msgpack_object v) inline void operator<< (object& o, msgpack_object v)
{ {
// FIXME beter way? // FIXME beter way?
::memcpy(&o, &v, sizeof(v)); ::memcpy(&o, &v, sizeof(v));
} }
inline object::operator msgpack_object() const inline object::operator msgpack_object() const
{ {
// FIXME beter way? // FIXME beter way?
msgpack_object obj; msgpack_object obj;
::memcpy(&obj, this, sizeof(obj)); ::memcpy(&obj, this, sizeof(obj));
return obj; return obj;
} }
@@ -388,151 +388,151 @@ inline object::operator msgpack_object() const
template <typename T> template <typename T>
inline void convert(T& v, object const& o) inline void convert(T& v, object const& o)
{ {
o.convert(v); o.convert(v);
} }
// obsolete // obsolete
template <typename Stream, typename T> template <typename Stream, typename T>
inline void pack(packer<Stream>& o, const T& v) inline void pack(packer<Stream>& o, const T& v)
{ {
o.pack(v); o.pack(v);
} }
// obsolete // obsolete
template <typename Stream, typename T> template <typename Stream, typename T>
inline void pack_copy(packer<Stream>& o, T v) inline void pack_copy(packer<Stream>& o, T v)
{ {
pack(o, v); pack(o, v);
} }
template <typename Stream> template <typename Stream>
packer<Stream>& operator<< (packer<Stream>& o, const object& v) packer<Stream>& operator<< (packer<Stream>& o, const object& v)
{ {
switch(v.type) { switch(v.type) {
case type::NIL: case type::NIL:
o.pack_nil(); o.pack_nil();
return o; return o;
case type::BOOLEAN: case type::BOOLEAN:
if(v.via.boolean) { if(v.via.boolean) {
o.pack_true(); o.pack_true();
} else { } else {
o.pack_false(); o.pack_false();
} }
return o; return o;
case type::POSITIVE_INTEGER: case type::POSITIVE_INTEGER:
o.pack_uint64(v.via.u64); o.pack_uint64(v.via.u64);
return o; return o;
case type::NEGATIVE_INTEGER: case type::NEGATIVE_INTEGER:
o.pack_int64(v.via.i64); o.pack_int64(v.via.i64);
return o; return o;
case type::DOUBLE: case type::DOUBLE:
o.pack_double(v.via.dec); o.pack_double(v.via.dec);
return o; return o;
case type::STR: case type::STR:
o.pack_str(v.via.str.size); o.pack_str(v.via.str.size);
o.pack_str_body(v.via.str.ptr, v.via.str.size); o.pack_str_body(v.via.str.ptr, v.via.str.size);
return o; return o;
case type::BIN: case type::BIN:
o.pack_bin(v.via.bin.size); o.pack_bin(v.via.bin.size);
o.pack_bin_body(v.via.bin.ptr, v.via.bin.size); o.pack_bin_body(v.via.bin.ptr, v.via.bin.size);
return o; return o;
case type::ARRAY: case type::ARRAY:
o.pack_array(v.via.array.size); o.pack_array(v.via.array.size);
for(object* p(v.via.array.ptr), for(object* p(v.via.array.ptr),
* const pend(v.via.array.ptr + v.via.array.size); * const pend(v.via.array.ptr + v.via.array.size);
p < pend; ++p) { p < pend; ++p) {
o << *p; o << *p;
} }
return o; return o;
case type::MAP: case type::MAP:
o.pack_map(v.via.map.size); o.pack_map(v.via.map.size);
for(object_kv* p(v.via.map.ptr), for(object_kv* p(v.via.map.ptr),
* const pend(v.via.map.ptr + v.via.map.size); * const pend(v.via.map.ptr + v.via.map.size);
p < pend; ++p) { p < pend; ++p) {
o << p->key; o << p->key;
o << p->val; o << p->val;
} }
return o; return o;
default: default:
throw type_error(); throw type_error();
} }
} }
std::ostream& operator<< (std::ostream& s, const object& o) std::ostream& operator<< (std::ostream& s, const object& o)
{ {
switch(o.type) { switch(o.type) {
case type::NIL: case type::NIL:
s << "nil"; s << "nil";
break; break;
case type::BOOLEAN: case type::BOOLEAN:
s << (o.via.boolean ? "true" : "false"); s << (o.via.boolean ? "true" : "false");
break; break;
case type::POSITIVE_INTEGER: case type::POSITIVE_INTEGER:
s << o.via.u64; s << o.via.u64;
break; break;
case type::NEGATIVE_INTEGER: case type::NEGATIVE_INTEGER:
s << o.via.i64; s << o.via.i64;
break; break;
case type::DOUBLE: case type::DOUBLE:
s << o.via.dec; s << o.via.dec;
break; break;
case type::STR: case type::STR:
(s << '"').write(o.via.str.ptr, o.via.str.size) << '"'; (s << '"').write(o.via.str.ptr, o.via.str.size) << '"';
break; break;
case type::BIN: case type::BIN:
(s << '"').write(o.via.bin.ptr, o.via.bin.size) << '"'; (s << '"').write(o.via.bin.ptr, o.via.bin.size) << '"';
break; break;
case type::ARRAY: case type::ARRAY:
s << "["; s << "[";
if(o.via.array.size != 0) { if(o.via.array.size != 0) {
object* p(o.via.array.ptr); object* p(o.via.array.ptr);
s << *p; s << *p;
++p; ++p;
for(object* const pend(o.via.array.ptr + o.via.array.size); for(object* const pend(o.via.array.ptr + o.via.array.size);
p < pend; ++p) { p < pend; ++p) {
s << ", " << *p; s << ", " << *p;
} }
} }
s << "]"; s << "]";
break; break;
case type::MAP: case type::MAP:
s << "{"; s << "{";
if(o.via.map.size != 0) { if(o.via.map.size != 0) {
object_kv* p(o.via.map.ptr); object_kv* p(o.via.map.ptr);
s << p->key << "=>" << p->val; s << p->key << "=>" << p->val;
++p; ++p;
for(object_kv* const pend(o.via.map.ptr + o.via.map.size); for(object_kv* const pend(o.via.map.ptr + o.via.map.size);
p < pend; ++p) { p < pend; ++p) {
s << ", " << p->key << "=>" << p->val; s << ", " << p->key << "=>" << p->val;
} }
} }
s << "}"; s << "}";
break; break;
default: default:
// FIXME // FIXME
s << "#<UNKNOWN " << static_cast<uint16_t>(o.type) << ">"; s << "#<UNKNOWN " << static_cast<uint16_t>(o.type) << ">";
} }
return s; return s;
} }
} // namespace msgpack } // namespace msgpack

View File

@@ -43,8 +43,8 @@ extern "C" {
typedef int (*msgpack_packer_write)(void* data, const char* buf, size_t len); typedef int (*msgpack_packer_write)(void* data, const char* buf, size_t len);
typedef struct msgpack_packer { typedef struct msgpack_packer {
void* data; void* data;
msgpack_packer_write callback; msgpack_packer_write callback;
} msgpack_packer; } msgpack_packer;
static void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback); static void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback);
@@ -107,38 +107,38 @@ int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
#define msgpack_pack_inline_func(name) \ #define msgpack_pack_inline_func(name) \
inline int msgpack_pack ## name inline int msgpack_pack ## name
#define msgpack_pack_inline_func_cint(name) \ #define msgpack_pack_inline_func_cint(name) \
inline int msgpack_pack ## name inline int msgpack_pack ## name
#define msgpack_pack_inline_func_fixint(name) \ #define msgpack_pack_inline_func_fixint(name) \
inline int msgpack_pack_fix ## name inline int msgpack_pack_fix ## name
#define msgpack_pack_user msgpack_packer* #define msgpack_pack_user msgpack_packer*
#define msgpack_pack_append_buffer(user, buf, len) \ #define msgpack_pack_append_buffer(user, buf, len) \
return (*(user)->callback)((user)->data, (const char*)buf, len) return (*(user)->callback)((user)->data, (const char*)buf, len)
#include "pack_template.h" #include "pack_template.h"
inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback) inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback)
{ {
pk->data = data; pk->data = data;
pk->callback = callback; pk->callback = callback;
} }
inline msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback) inline msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback)
{ {
msgpack_packer* pk = (msgpack_packer*)calloc(1, sizeof(msgpack_packer)); msgpack_packer* pk = (msgpack_packer*)calloc(1, sizeof(msgpack_packer));
if(!pk) { return NULL; } if(!pk) { return NULL; }
msgpack_packer_init(pk, data, callback); msgpack_packer_init(pk, data, callback);
return pk; return pk;
} }
inline void msgpack_packer_free(msgpack_packer* pk) inline void msgpack_packer_free(msgpack_packer* pk)
{ {
free(pk); free(pk);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -33,31 +33,31 @@ extern "C" {
*/ */
typedef struct msgpack_sbuffer { typedef struct msgpack_sbuffer {
size_t size; size_t size;
char* data; char* data;
size_t alloc; size_t alloc;
} msgpack_sbuffer; } msgpack_sbuffer;
static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf) static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
{ {
memset(sbuf, 0, sizeof(msgpack_sbuffer)); memset(sbuf, 0, sizeof(msgpack_sbuffer));
} }
static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf) static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
{ {
free(sbuf->data); free(sbuf->data);
} }
static inline msgpack_sbuffer* msgpack_sbuffer_new(void) static inline msgpack_sbuffer* msgpack_sbuffer_new(void)
{ {
return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer)); return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer));
} }
static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf) static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf)
{ {
if(sbuf == NULL) { return; } if(sbuf == NULL) { return; }
msgpack_sbuffer_destroy(sbuf); msgpack_sbuffer_destroy(sbuf);
free(sbuf); free(sbuf);
} }
#ifndef MSGPACK_SBUFFER_INIT_SIZE #ifndef MSGPACK_SBUFFER_INIT_SIZE
@@ -66,39 +66,39 @@ static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf)
static inline int msgpack_sbuffer_write(void* data, const char* buf, size_t len) static inline int msgpack_sbuffer_write(void* data, const char* buf, size_t len)
{ {
msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data; msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
if(sbuf->alloc - sbuf->size < len) { if(sbuf->alloc - sbuf->size < len) {
void* tmp; void* tmp;
size_t nsize = (sbuf->alloc) ? size_t nsize = (sbuf->alloc) ?
sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
while(nsize < sbuf->size + len) { nsize *= 2; } while(nsize < sbuf->size + len) { nsize *= 2; }
tmp = realloc(sbuf->data, nsize); tmp = realloc(sbuf->data, nsize);
if(!tmp) { return -1; } if(!tmp) { return -1; }
sbuf->data = (char*)tmp; sbuf->data = (char*)tmp;
sbuf->alloc = nsize; sbuf->alloc = nsize;
} }
memcpy(sbuf->data + sbuf->size, buf, len); memcpy(sbuf->data + sbuf->size, buf, len);
sbuf->size += len; sbuf->size += len;
return 0; return 0;
} }
static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf) static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf)
{ {
char* tmp = sbuf->data; char* tmp = sbuf->data;
sbuf->size = 0; sbuf->size = 0;
sbuf->data = NULL; sbuf->data = NULL;
sbuf->alloc = 0; sbuf->alloc = 0;
return tmp; return tmp;
} }
static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf) static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf)
{ {
sbuf->size = 0; sbuf->size = 0;
} }
/** @} */ /** @} */

View File

@@ -29,85 +29,85 @@ namespace msgpack {
class sbuffer { class sbuffer {
public: public:
sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE):m_size(0), m_alloc(initsz) sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE):m_size(0), m_alloc(initsz)
{ {
if(initsz == 0) { if(initsz == 0) {
m_data = nullptr; m_data = nullptr;
} else { } else {
m_data = (char*)::malloc(initsz); m_data = (char*)::malloc(initsz);
if(!m_data) { if(!m_data) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
} }
} }
~sbuffer() ~sbuffer()
{ {
::free(m_data); ::free(m_data);
} }
public: public:
void write(const char* buf, size_t len) void write(const char* buf, size_t len)
{ {
if(m_alloc - m_size < len) { if(m_alloc - m_size < len) {
expand_buffer(len); expand_buffer(len);
} }
::memcpy(m_data + m_size, buf, len); ::memcpy(m_data + m_size, buf, len);
m_size += len; m_size += len;
} }
char* data() char* data()
{ {
return m_data; return m_data;
} }
const char* data() const const char* data() const
{ {
return m_data; return m_data;
} }
size_t size() const size_t size() const
{ {
return m_size; return m_size;
} }
char* release() char* release()
{ {
char* tmp = m_data; char* tmp = m_data;
m_size = 0; m_size = 0;
m_data = nullptr; m_data = nullptr;
m_alloc = 0; m_alloc = 0;
return tmp; return tmp;
} }
void clear() void clear()
{ {
m_size = 0; m_size = 0;
} }
private: private:
void expand_buffer(size_t len) void expand_buffer(size_t len)
{ {
size_t nsize = (m_alloc > 0) ? size_t nsize = (m_alloc > 0) ?
m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
while(nsize < m_size + len) { nsize *= 2; } while(nsize < m_size + len) { nsize *= 2; }
void* tmp = ::realloc(m_data, nsize); void* tmp = ::realloc(m_data, nsize);
if(!tmp) { if(!tmp) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_data = static_cast<char*>(tmp); m_data = static_cast<char*>(tmp);
m_alloc = nsize; m_alloc = nsize;
} }
private: private:
sbuffer(const sbuffer&); sbuffer(const sbuffer&);
private: private:
size_t m_size; size_t m_size;
char* m_data; char* m_data;
size_t m_alloc; size_t m_alloc;
}; };

View File

@@ -34,12 +34,12 @@ extern "C" {
*/ */
typedef struct msgpack_unpacked { typedef struct msgpack_unpacked {
msgpack_zone* zone; msgpack_zone* zone;
msgpack_object data; msgpack_object data;
} msgpack_unpacked; } msgpack_unpacked;
bool msgpack_unpack_next(msgpack_unpacked* result, bool msgpack_unpack_next(msgpack_unpacked* result,
const char* data, size_t len, size_t* off); const char* data, size_t len, size_t* off);
/** @} */ /** @} */
@@ -51,14 +51,14 @@ bool msgpack_unpack_next(msgpack_unpacked* result,
*/ */
typedef struct msgpack_unpacker { typedef struct msgpack_unpacker {
char* buffer; char* buffer;
size_t used; size_t used;
size_t free; size_t free;
size_t off; size_t off;
size_t parsed; size_t parsed;
msgpack_zone* z; msgpack_zone* z;
size_t initial_buffer_size; size_t initial_buffer_size;
void* ctx; void* ctx;
} msgpack_unpacker; } msgpack_unpacker;
@@ -176,16 +176,16 @@ static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac)
// obsolete // obsolete
typedef enum { typedef enum {
MSGPACK_UNPACK_SUCCESS = 2, MSGPACK_UNPACK_SUCCESS = 2,
MSGPACK_UNPACK_EXTRA_BYTES = 1, MSGPACK_UNPACK_EXTRA_BYTES = 1,
MSGPACK_UNPACK_CONTINUE = 0, MSGPACK_UNPACK_CONTINUE = 0,
MSGPACK_UNPACK_PARSE_ERROR = -1 MSGPACK_UNPACK_PARSE_ERROR = -1
} msgpack_unpack_return; } msgpack_unpack_return;
// obsolete // obsolete
msgpack_unpack_return msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off, msgpack_unpack(const char* data, size_t len, size_t* off,
msgpack_zone* result_zone, msgpack_object* result); msgpack_zone* result_zone, msgpack_object* result);
static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac); static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac);
@@ -196,59 +196,59 @@ bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size);
static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size) static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size)
{ {
if(mpac->free >= size) { return true; } if(mpac->free >= size) { return true; }
return msgpack_unpacker_expand_buffer(mpac, size); return msgpack_unpacker_expand_buffer(mpac, size);
} }
static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac) static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac)
{ {
return mpac->buffer + mpac->used; return mpac->buffer + mpac->used;
} }
static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac) static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac)
{ {
return mpac->free; return mpac->free;
} }
static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size) static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size)
{ {
mpac->used += size; mpac->used += size;
mpac->free -= size; mpac->free -= size;
} }
static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac) static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac)
{ {
return mpac->parsed - mpac->off + mpac->used; return mpac->parsed - mpac->off + mpac->used;
} }
static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac) static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac)
{ {
return mpac->parsed; return mpac->parsed;
} }
static inline void msgpack_unpacked_init(msgpack_unpacked* result) static inline void msgpack_unpacked_init(msgpack_unpacked* result)
{ {
memset(result, 0, sizeof(msgpack_unpacked)); memset(result, 0, sizeof(msgpack_unpacked));
} }
static inline void msgpack_unpacked_destroy(msgpack_unpacked* result) static inline void msgpack_unpacked_destroy(msgpack_unpacked* result)
{ {
if(result->zone != NULL) { if(result->zone != NULL) {
msgpack_zone_free(result->zone); msgpack_zone_free(result->zone);
result->zone = NULL; result->zone = NULL;
memset(&result->data, 0, sizeof(msgpack_object)); memset(&result->data, 0, sizeof(msgpack_object));
} }
} }
static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result) static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result)
{ {
if(result->zone != NULL) { if(result->zone != NULL) {
msgpack_zone* z = result->zone; msgpack_zone* z = result->zone;
result->zone = NULL; result->zone = NULL;
return z; return z;
} }
return NULL; return NULL;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -35,56 +35,56 @@ extern "C" {
typedef enum { typedef enum {
CS_HEADER = 0x00, // nil CS_HEADER = 0x00, // nil
//CS_ = 0x01, //CS_ = 0x01,
//CS_ = 0x02, // false //CS_ = 0x02, // false
//CS_ = 0x03, // true //CS_ = 0x03, // true
CS_BIN_8 = 0x04, CS_BIN_8 = 0x04,
CS_BIN_16 = 0x05, CS_BIN_16 = 0x05,
CS_BIN_32 = 0x06, CS_BIN_32 = 0x06,
//CS_EXT_8 = 0x07, //CS_EXT_8 = 0x07,
//CS_EXT_16 = 0x08, //CS_EXT_16 = 0x08,
//CS_EXT_32 = 0x09, //CS_EXT_32 = 0x09,
CS_FLOAT = 0x0a, CS_FLOAT = 0x0a,
CS_DOUBLE = 0x0b, CS_DOUBLE = 0x0b,
CS_UINT_8 = 0x0c, CS_UINT_8 = 0x0c,
CS_UINT_16 = 0x0d, CS_UINT_16 = 0x0d,
CS_UINT_32 = 0x0e, CS_UINT_32 = 0x0e,
CS_UINT_64 = 0x0f, CS_UINT_64 = 0x0f,
CS_INT_8 = 0x10, CS_INT_8 = 0x10,
CS_INT_16 = 0x11, CS_INT_16 = 0x11,
CS_INT_32 = 0x12, CS_INT_32 = 0x12,
CS_INT_64 = 0x13, CS_INT_64 = 0x13,
//CS_FIXEXT_1 = 0x14, //CS_FIXEXT_1 = 0x14,
//CS_FIXEXT_2 = 0x15, //CS_FIXEXT_2 = 0x15,
//CS_FIXEXT_4 = 0x16, //CS_FIXEXT_4 = 0x16,
//CS_FIXEXT_8 = 0x17, //CS_FIXEXT_8 = 0x17,
//CS_FIXEXT_16 = 0x18, //CS_FIXEXT_16 = 0x18,
CS_STR_8 = 0x19, // str8 CS_STR_8 = 0x19, // str8
CS_STR_16 = 0x1a, // str16 CS_STR_16 = 0x1a, // str16
CS_STR_32 = 0x1b, // str32 CS_STR_32 = 0x1b, // str32
CS_ARRAY_16 = 0x1c, CS_ARRAY_16 = 0x1c,
CS_ARRAY_32 = 0x1d, CS_ARRAY_32 = 0x1d,
CS_MAP_16 = 0x1e, CS_MAP_16 = 0x1e,
CS_MAP_32 = 0x1f, CS_MAP_32 = 0x1f,
//ACS_BIG_INT_VALUE, //ACS_BIG_INT_VALUE,
//ACS_BIG_FLOAT_VALUE, //ACS_BIG_FLOAT_VALUE,
ACS_STR_VALUE, ACS_STR_VALUE,
ACS_BIN_VALUE ACS_BIN_VALUE
} msgpack_unpack_state; } msgpack_unpack_state;
typedef enum { typedef enum {
CT_ARRAY_ITEM, CT_ARRAY_ITEM,
CT_MAP_KEY, CT_MAP_KEY,
CT_MAP_VALUE CT_MAP_VALUE
} msgpack_container_type; } msgpack_container_type;

View File

@@ -47,128 +47,128 @@
#endif #endif
msgpack_unpack_struct_decl(_stack) { msgpack_unpack_struct_decl(_stack) {
msgpack_unpack_object obj; msgpack_unpack_object obj;
size_t count; size_t count;
unsigned int ct; unsigned int ct;
msgpack_unpack_object map_key; msgpack_unpack_object map_key;
}; };
msgpack_unpack_struct_decl(_context) { msgpack_unpack_struct_decl(_context) {
msgpack_unpack_user user; msgpack_unpack_user user;
unsigned int cs; unsigned int cs;
unsigned int trail; unsigned int trail;
unsigned int top; unsigned int top;
/* /*
msgpack_unpack_struct(_stack)* stack; msgpack_unpack_struct(_stack)* stack;
unsigned int stack_size; unsigned int stack_size;
msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE]; msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE];
*/ */
msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE]; msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE];
}; };
msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx) msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx)
{ {
ctx->cs = CS_HEADER; ctx->cs = CS_HEADER;
ctx->trail = 0; ctx->trail = 0;
ctx->top = 0; ctx->top = 0;
/* /*
ctx->stack = ctx->embed_stack; ctx->stack = ctx->embed_stack;
ctx->stack_size = MSGPACK_EMBED_STACK_SIZE; ctx->stack_size = MSGPACK_EMBED_STACK_SIZE;
*/ */
ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user); ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user);
} }
/* /*
msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx) msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx)
{ {
if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) { if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) {
free(ctx->stack); free(ctx->stack);
} }
} }
*/ */
msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx) msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx)
{ {
return (ctx)->stack[0].obj; return (ctx)->stack[0].obj;
} }
msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off) msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
{ {
assert(len >= *off); assert(len >= *off);
const unsigned char* p = (unsigned char*)data + *off; const unsigned char* p = (unsigned char*)data + *off;
const unsigned char* const pe = (unsigned char*)data + len; const unsigned char* const pe = (unsigned char*)data + len;
const void* n = NULL; const void* n = NULL;
unsigned int trail = ctx->trail; unsigned int trail = ctx->trail;
unsigned int cs = ctx->cs; unsigned int cs = ctx->cs;
unsigned int top = ctx->top; unsigned int top = ctx->top;
msgpack_unpack_struct(_stack)* stack = ctx->stack; msgpack_unpack_struct(_stack)* stack = ctx->stack;
/* /*
unsigned int stack_size = ctx->stack_size; unsigned int stack_size = ctx->stack_size;
*/ */
msgpack_unpack_user* user = &ctx->user; msgpack_unpack_user* user = &ctx->user;
msgpack_unpack_object obj; msgpack_unpack_object obj;
msgpack_unpack_struct(_stack)* c = NULL; msgpack_unpack_struct(_stack)* c = NULL;
int ret; int ret;
#define push_simple_value(func) \ #define push_simple_value(func) \
if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \ if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \
goto _push goto _push
#define push_fixed_value(func, arg) \ #define push_fixed_value(func, arg) \
if(msgpack_unpack_callback(func)(user, arg, &obj) < 0) { goto _failed; } \ if(msgpack_unpack_callback(func)(user, arg, &obj) < 0) { goto _failed; } \
goto _push goto _push
#define push_variable_value(func, base, pos, len) \ #define push_variable_value(func, base, pos, len) \
if(msgpack_unpack_callback(func)(user, \ if(msgpack_unpack_callback(func)(user, \
(const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \ (const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \
goto _push goto _push
#define again_fixed_trail(_cs, trail_len) \ #define again_fixed_trail(_cs, trail_len) \
trail = trail_len; \ trail = trail_len; \
cs = _cs; \ cs = _cs; \
goto _fixed_trail_again goto _fixed_trail_again
#define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \ #define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \
trail = trail_len; \ trail = trail_len; \
if(trail == 0) { goto ifzero; } \ if(trail == 0) { goto ifzero; } \
cs = _cs; \ cs = _cs; \
goto _fixed_trail_again goto _fixed_trail_again
#define start_container(func, count_, ct_) \ #define start_container(func, count_, ct_) \
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \ if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \
if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \ if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \
if((count_) == 0) { obj = stack[top].obj; goto _push; } \ if((count_) == 0) { obj = stack[top].obj; goto _push; } \
stack[top].ct = ct_; \ stack[top].ct = ct_; \
stack[top].count = count_; \ stack[top].count = count_; \
++top; \ ++top; \
/*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \ /*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \
/*printf("stack push %d\n", top);*/ \ /*printf("stack push %d\n", top);*/ \
/* FIXME \ /* FIXME \
if(top >= stack_size) { \ if(top >= stack_size) { \
if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \ if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \
size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \ size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \
size_t nsize = csize * 2; \ size_t nsize = csize * 2; \
msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \ msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \
if(tmp == NULL) { goto _failed; } \ if(tmp == NULL) { goto _failed; } \
memcpy(tmp, ctx->stack, csize); \ memcpy(tmp, ctx->stack, csize); \
ctx->stack = stack = tmp; \ ctx->stack = stack = tmp; \
ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \ ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \
} else { \ } else { \
size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \ size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \
msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \ msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \
if(tmp == NULL) { goto _failed; } \ if(tmp == NULL) { goto _failed; } \
ctx->stack = stack = tmp; \ ctx->stack = stack = tmp; \
ctx->stack_size = stack_size = stack_size * 2; \ ctx->stack_size = stack_size = stack_size * 2; \
} \ } \
} \ } \
*/ \ */ \
goto _header_again goto _header_again
#define NEXT_CS(p) \ #define NEXT_CS(p) \
((unsigned int)*p & 0x1f) ((unsigned int)*p & 0x1f)
#ifdef USE_CASE_RANGE #ifdef USE_CASE_RANGE
#define SWITCH_RANGE_BEGIN switch(*p) { #define SWITCH_RANGE_BEGIN switch(*p) {
@@ -182,271 +182,271 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
#define SWITCH_RANGE_END } } #define SWITCH_RANGE_END } }
#endif #endif
if(p == pe) { goto _out; } if(p == pe) { goto _out; }
do { do {
switch(cs) { switch(cs) {
case CS_HEADER: case CS_HEADER:
SWITCH_RANGE_BEGIN SWITCH_RANGE_BEGIN
SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum
push_fixed_value(_uint8, *(uint8_t*)p); push_fixed_value(_uint8, *(uint8_t*)p);
SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum
push_fixed_value(_int8, *(int8_t*)p); push_fixed_value(_int8, *(int8_t*)p);
SWITCH_RANGE(0xc0, 0xdf) // Variable SWITCH_RANGE(0xc0, 0xdf) // Variable
switch(*p) { switch(*p) {
case 0xc0: // nil case 0xc0: // nil
push_simple_value(_nil); push_simple_value(_nil);
//case 0xc1: // string //case 0xc1: // string
// again_terminal_trail(NEXT_CS(p), p+1); // again_terminal_trail(NEXT_CS(p), p+1);
case 0xc2: // false case 0xc2: // false
push_simple_value(_false); push_simple_value(_false);
case 0xc3: // true case 0xc3: // true
push_simple_value(_true); push_simple_value(_true);
case 0xc4: // bin 8 case 0xc4: // bin 8
case 0xc5: // bin 16 case 0xc5: // bin 16
case 0xc6: // bin 32 case 0xc6: // bin 32
again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03));
//case 0xc7: //case 0xc7:
//case 0xc8: //case 0xc8:
//case 0xc9: //case 0xc9:
case 0xca: // float case 0xca: // float
case 0xcb: // double case 0xcb: // double
case 0xcc: // unsigned int 8 case 0xcc: // unsigned int 8
case 0xcd: // unsigned int 16 case 0xcd: // unsigned int 16
case 0xce: // unsigned int 32 case 0xce: // unsigned int 32
case 0xcf: // unsigned int 64 case 0xcf: // unsigned int 64
case 0xd0: // signed int 8 case 0xd0: // signed int 8
case 0xd1: // signed int 16 case 0xd1: // signed int 16
case 0xd2: // signed int 32 case 0xd2: // signed int 32
case 0xd3: // signed int 64 case 0xd3: // signed int 64
again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03));
//case 0xd4: //case 0xd4:
//case 0xd5: //case 0xd5:
//case 0xd6: // big integer 16 //case 0xd6: // big integer 16
//case 0xd7: // big integer 32 //case 0xd7: // big integer 32
//case 0xd8: // big float 16 //case 0xd8: // big float 16
case 0xd9: // str 8 case 0xd9: // str 8
case 0xda: // str 16 case 0xda: // str 16
case 0xdb: // str 32 case 0xdb: // str 32
again_fixed_trail(NEXT_CS(p), 1 << ((((unsigned int)*p) & 0x03) - 1)); again_fixed_trail(NEXT_CS(p), 1 << ((((unsigned int)*p) & 0x03) - 1));
case 0xdc: // array 16 case 0xdc: // array 16
case 0xdd: // array 32 case 0xdd: // array 32
case 0xde: // map 16 case 0xde: // map 16
case 0xdf: // map 32 case 0xdf: // map 32
again_fixed_trail(NEXT_CS(p), 2u << (((unsigned int)*p) & 0x01)); again_fixed_trail(NEXT_CS(p), 2u << (((unsigned int)*p) & 0x01));
default: default:
goto _failed; goto _failed;
} }
SWITCH_RANGE(0xa0, 0xbf) // FixStr SWITCH_RANGE(0xa0, 0xbf) // FixStr
again_fixed_trail_if_zero(ACS_STR_VALUE, ((unsigned int)*p & 0x1f), _str_zero); again_fixed_trail_if_zero(ACS_STR_VALUE, ((unsigned int)*p & 0x1f), _str_zero);
SWITCH_RANGE(0x90, 0x9f) // FixArray SWITCH_RANGE(0x90, 0x9f) // FixArray
start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM); start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM);
SWITCH_RANGE(0x80, 0x8f) // FixMap SWITCH_RANGE(0x80, 0x8f) // FixMap
start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY); start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY);
SWITCH_RANGE_DEFAULT SWITCH_RANGE_DEFAULT
goto _failed; goto _failed;
SWITCH_RANGE_END SWITCH_RANGE_END
// end CS_HEADER // end CS_HEADER
_fixed_trail_again: _fixed_trail_again:
++p; ++p;
default: default:
if((size_t)(pe - p) < trail) { goto _out; } if((size_t)(pe - p) < trail) { goto _out; }
n = p; p += trail - 1; n = p; p += trail - 1;
switch(cs) { switch(cs) {
//case CS_ //case CS_
//case CS_ //case CS_
case CS_FLOAT: { case CS_FLOAT: {
union { uint32_t i; float f; } mem; union { uint32_t i; float f; } mem;
_msgpack_load32(uint32_t, n, &mem.i); _msgpack_load32(uint32_t, n, &mem.i);
push_fixed_value(_float, mem.f); } push_fixed_value(_float, mem.f); }
case CS_DOUBLE: { case CS_DOUBLE: {
union { uint64_t i; double f; } mem; union { uint64_t i; double f; } mem;
_msgpack_load64(uint64_t, n, &mem.i); _msgpack_load64(uint64_t, n, &mem.i);
#if defined(__arm__) && !(__ARM_EABI__) // arm-oabi #if defined(__arm__) && !(__ARM_EABI__) // arm-oabi
// https://github.com/msgpack/msgpack-perl/pull/1 // https://github.com/msgpack/msgpack-perl/pull/1
mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
#endif #endif
push_fixed_value(_double, mem.f); } push_fixed_value(_double, mem.f); }
case CS_UINT_8: case CS_UINT_8:
push_fixed_value(_uint8, *(uint8_t*)n); push_fixed_value(_uint8, *(uint8_t*)n);
case CS_UINT_16:{ case CS_UINT_16:{
uint16_t tmp; uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp); _msgpack_load16(uint16_t,n,&tmp);
push_fixed_value(_uint16, tmp); push_fixed_value(_uint16, tmp);
} }
case CS_UINT_32:{ case CS_UINT_32:{
uint32_t tmp; uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp); _msgpack_load32(uint32_t,n,&tmp);
push_fixed_value(_uint32, tmp); push_fixed_value(_uint32, tmp);
} }
case CS_UINT_64:{ case CS_UINT_64:{
uint64_t tmp; uint64_t tmp;
_msgpack_load64(uint64_t,n,&tmp); _msgpack_load64(uint64_t,n,&tmp);
push_fixed_value(_uint64, tmp); push_fixed_value(_uint64, tmp);
} }
case CS_INT_8: case CS_INT_8:
push_fixed_value(_int8, *(int8_t*)n); push_fixed_value(_int8, *(int8_t*)n);
case CS_INT_16:{ case CS_INT_16:{
int16_t tmp; int16_t tmp;
_msgpack_load16(int16_t,n,&tmp); _msgpack_load16(int16_t,n,&tmp);
push_fixed_value(_int16, tmp); push_fixed_value(_int16, tmp);
} }
case CS_INT_32:{ case CS_INT_32:{
int32_t tmp; int32_t tmp;
_msgpack_load32(int32_t,n,&tmp); _msgpack_load32(int32_t,n,&tmp);
push_fixed_value(_int32, tmp); push_fixed_value(_int32, tmp);
} }
case CS_INT_64:{ case CS_INT_64:{
int64_t tmp; int64_t tmp;
_msgpack_load64(int64_t,n,&tmp); _msgpack_load64(int64_t,n,&tmp);
push_fixed_value(_int64, tmp); push_fixed_value(_int64, tmp);
} }
//case CS_ //case CS_
//case CS_ //case CS_
//case CS_BIG_INT_16: //case CS_BIG_INT_16:
// again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load16(uint16_t,n), _big_int_zero); // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load16(uint16_t,n), _big_int_zero);
//case CS_BIG_INT_32: //case CS_BIG_INT_32:
// again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load32(uint32_t,n), _big_int_zero); // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load32(uint32_t,n), _big_int_zero);
//case ACS_BIG_INT_VALUE: //case ACS_BIG_INT_VALUE:
//_big_int_zero: //_big_int_zero:
// // FIXME // // FIXME
// push_variable_value(_big_int, data, n, trail); // push_variable_value(_big_int, data, n, trail);
//case CS_BIG_FLOAT_16: //case CS_BIG_FLOAT_16:
// again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load16(uint16_t,n), _big_float_zero); // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load16(uint16_t,n), _big_float_zero);
//case CS_BIG_FLOAT_32: //case CS_BIG_FLOAT_32:
// again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load32(uint32_t,n), _big_float_zero); // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load32(uint32_t,n), _big_float_zero);
//case ACS_BIG_FLOAT_VALUE: //case ACS_BIG_FLOAT_VALUE:
//_big_float_zero: //_big_float_zero:
// // FIXME // // FIXME
// push_variable_value(_big_float, data, n, trail); // push_variable_value(_big_float, data, n, trail);
case CS_STR_8: case CS_STR_8:
again_fixed_trail_if_zero(ACS_STR_VALUE, *(uint8_t*)n, _str_zero); again_fixed_trail_if_zero(ACS_STR_VALUE, *(uint8_t*)n, _str_zero);
case CS_BIN_8: case CS_BIN_8:
again_fixed_trail_if_zero(ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero); again_fixed_trail_if_zero(ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero);
case CS_STR_16:{ case CS_STR_16:{
uint16_t tmp; uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp); _msgpack_load16(uint16_t,n,&tmp);
again_fixed_trail_if_zero(ACS_STR_VALUE, tmp, _str_zero); again_fixed_trail_if_zero(ACS_STR_VALUE, tmp, _str_zero);
} }
case CS_BIN_16:{ case CS_BIN_16:{
uint16_t tmp; uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp); _msgpack_load16(uint16_t,n,&tmp);
again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero); again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero);
} }
case CS_STR_32:{ case CS_STR_32:{
uint32_t tmp; uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp); _msgpack_load32(uint32_t,n,&tmp);
again_fixed_trail_if_zero(ACS_STR_VALUE, tmp, _str_zero); again_fixed_trail_if_zero(ACS_STR_VALUE, tmp, _str_zero);
} }
case CS_BIN_32:{ case CS_BIN_32:{
uint32_t tmp; uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp); _msgpack_load32(uint32_t,n,&tmp);
again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero); again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero);
} }
case ACS_STR_VALUE: case ACS_STR_VALUE:
_str_zero: _str_zero:
push_variable_value(_str, data, n, trail); push_variable_value(_str, data, n, trail);
case ACS_BIN_VALUE: case ACS_BIN_VALUE:
_bin_zero: _bin_zero:
push_variable_value(_bin, data, n, trail); push_variable_value(_bin, data, n, trail);
case CS_ARRAY_16:{ case CS_ARRAY_16:{
uint16_t tmp; uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp); _msgpack_load16(uint16_t,n,&tmp);
start_container(_array, tmp, CT_ARRAY_ITEM); start_container(_array, tmp, CT_ARRAY_ITEM);
} }
case CS_ARRAY_32:{ case CS_ARRAY_32:{
/* FIXME security guard */ /* FIXME security guard */
uint32_t tmp; uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp); _msgpack_load32(uint32_t,n,&tmp);
start_container(_array, tmp, CT_ARRAY_ITEM); start_container(_array, tmp, CT_ARRAY_ITEM);
} }
case CS_MAP_16:{ case CS_MAP_16:{
uint16_t tmp; uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp); _msgpack_load16(uint16_t,n,&tmp);
start_container(_map, tmp, CT_MAP_KEY); start_container(_map, tmp, CT_MAP_KEY);
} }
case CS_MAP_32:{ case CS_MAP_32:{
/* FIXME security guard */ /* FIXME security guard */
uint32_t tmp; uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp); _msgpack_load32(uint32_t,n,&tmp);
start_container(_map, tmp, CT_MAP_KEY); start_container(_map, tmp, CT_MAP_KEY);
} }
default: default:
goto _failed; goto _failed;
} }
} }
_push: _push:
if(top == 0) { goto _finish; } if(top == 0) { goto _finish; }
c = &stack[top-1]; c = &stack[top-1];
switch(c->ct) { switch(c->ct) {
case CT_ARRAY_ITEM: case CT_ARRAY_ITEM:
if(msgpack_unpack_callback(_array_item)(user, &c->obj, obj) < 0) { goto _failed; } if(msgpack_unpack_callback(_array_item)(user, &c->obj, obj) < 0) { goto _failed; }
if(--c->count == 0) { if(--c->count == 0) {
obj = c->obj; obj = c->obj;
--top; --top;
/*printf("stack pop %d\n", top);*/ /*printf("stack pop %d\n", top);*/
goto _push; goto _push;
} }
goto _header_again; goto _header_again;
case CT_MAP_KEY: case CT_MAP_KEY:
c->map_key = obj; c->map_key = obj;
c->ct = CT_MAP_VALUE; c->ct = CT_MAP_VALUE;
goto _header_again; goto _header_again;
case CT_MAP_VALUE: case CT_MAP_VALUE:
if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; } if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; }
if(--c->count == 0) { if(--c->count == 0) {
obj = c->obj; obj = c->obj;
--top; --top;
/*printf("stack pop %d\n", top);*/ /*printf("stack pop %d\n", top);*/
goto _push; goto _push;
} }
c->ct = CT_MAP_KEY; c->ct = CT_MAP_KEY;
goto _header_again; goto _header_again;
default: default:
goto _failed; goto _failed;
} }
_header_again: _header_again:
cs = CS_HEADER; cs = CS_HEADER;
++p; ++p;
} while(p != pe); } while(p != pe);
goto _out; goto _out;
_finish: _finish:
stack[0].obj = obj; stack[0].obj = obj;
++p; ++p;
ret = 1; ret = 1;
/*printf("-- finish --\n"); */ /*printf("-- finish --\n"); */
goto _end; goto _end;
_failed: _failed:
/*printf("** FAILED **\n"); */ /*printf("** FAILED **\n"); */
ret = -1; ret = -1;
goto _end; goto _end;
_out: _out:
ret = 0; ret = 0;
goto _end; goto _end;
_end: _end:
ctx->cs = cs; ctx->cs = cs;
ctx->trail = trail; ctx->trail = trail;
ctx->top = top; ctx->top = top;
*off = (size_t)(p - (const unsigned char*)data); *off = (size_t)(p - (const unsigned char*)data);
return ret; return ret;
} }

View File

@@ -26,15 +26,15 @@
#define MSGPACK_VERSION MSGPACK_VERSION_I(MSGPACK_VERSION_MAJOR, MSGPACK_VERSION_MINOR, MSGPACK_VERSION_RELEASE) #define MSGPACK_VERSION MSGPACK_VERSION_I(MSGPACK_VERSION_MAJOR, MSGPACK_VERSION_MINOR, MSGPACK_VERSION_RELEASE)
inline const char* msgpack_version(void) { inline const char* msgpack_version(void) {
return MSGPACK_VERSION; return MSGPACK_VERSION;
} }
inline int msgpack_version_major(void) { inline int msgpack_version_major(void) {
return MSGPACK_VERSION_MAJOR; return MSGPACK_VERSION_MAJOR;
} }
inline int msgpack_version_minor(void) { inline int msgpack_version_minor(void) {
return MSGPACK_VERSION_MINOR; return MSGPACK_VERSION_MINOR;
} }
#endif /* msgpack/version.hpp */ #endif /* msgpack/version.hpp */

View File

@@ -25,8 +25,8 @@
#include <sys/uio.h> #include <sys/uio.h>
#else #else
struct iovec { struct iovec {
void *iov_base; void *iov_base;
size_t iov_len; size_t iov_len;
}; };
#endif #endif
@@ -45,20 +45,20 @@ struct msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk; typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_inner_buffer { typedef struct msgpack_vrefbuffer_inner_buffer {
size_t free; size_t free;
char* ptr; char* ptr;
msgpack_vrefbuffer_chunk* head; msgpack_vrefbuffer_chunk* head;
} msgpack_vrefbuffer_inner_buffer; } msgpack_vrefbuffer_inner_buffer;
typedef struct msgpack_vrefbuffer { typedef struct msgpack_vrefbuffer {
struct iovec* tail; struct iovec* tail;
struct iovec* end; struct iovec* end;
struct iovec* array; struct iovec* array;
size_t chunk_size; size_t chunk_size;
size_t ref_size; size_t ref_size;
msgpack_vrefbuffer_inner_buffer inner_buffer; msgpack_vrefbuffer_inner_buffer inner_buffer;
} msgpack_vrefbuffer; } msgpack_vrefbuffer;
@@ -71,7 +71,7 @@ typedef struct msgpack_vrefbuffer {
#endif #endif
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size); size_t ref_size, size_t chunk_size);
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf); void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf);
static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size); static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size);
@@ -83,10 +83,10 @@ static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffe
static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref); static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref);
int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf, int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
const char* buf, size_t len); const char* buf, size_t len);
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
const char* buf, size_t len); const char* buf, size_t len);
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to); int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to);
@@ -97,41 +97,41 @@ void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vref);
static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size) static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size)
{ {
msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)malloc(sizeof(msgpack_vrefbuffer)); msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)malloc(sizeof(msgpack_vrefbuffer));
if (vbuf == NULL) return NULL; if (vbuf == NULL) return NULL;
if(!msgpack_vrefbuffer_init(vbuf, ref_size, chunk_size)) { if(!msgpack_vrefbuffer_init(vbuf, ref_size, chunk_size)) {
free(vbuf); free(vbuf);
return NULL; return NULL;
} }
return vbuf; return vbuf;
} }
static inline void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf) static inline void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf)
{ {
if(vbuf == NULL) { return; } if(vbuf == NULL) { return; }
msgpack_vrefbuffer_destroy(vbuf); msgpack_vrefbuffer_destroy(vbuf);
free(vbuf); free(vbuf);
} }
static inline int msgpack_vrefbuffer_write(void* data, const char* buf, size_t len) static inline int msgpack_vrefbuffer_write(void* data, const char* buf, size_t len)
{ {
msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data; msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data;
if(len < vbuf->ref_size) { if(len < vbuf->ref_size) {
return msgpack_vrefbuffer_append_copy(vbuf, buf, len); return msgpack_vrefbuffer_append_copy(vbuf, buf, len);
} else { } else {
return msgpack_vrefbuffer_append_ref(vbuf, buf, len); return msgpack_vrefbuffer_append_ref(vbuf, buf, len);
} }
} }
static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref) static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref)
{ {
return vref->array; return vref->array;
} }
static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref) static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref)
{ {
return (size_t)(vref->tail - vref->array); return (size_t)(vref->tail - vref->array);
} }

View File

@@ -32,8 +32,8 @@
#include <sys/uio.h> #include <sys/uio.h>
#else #else
struct iovec { struct iovec {
void *iov_base; void *iov_base;
size_t iov_len; size_t iov_len;
}; };
#endif #endif
@@ -46,230 +46,230 @@ namespace detail {
class vrefbuffer { class vrefbuffer {
private: private:
struct chunk { struct chunk {
chunk* next; chunk* next;
}; };
struct inner_buffer { struct inner_buffer {
size_t free; size_t free;
char* ptr; char* ptr;
chunk* head; chunk* head;
}; };
public: public:
vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE, vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE,
size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE) size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE)
:m_ref_size(ref_size), m_chunk_size(chunk_size) :m_ref_size(ref_size), m_chunk_size(chunk_size)
{ {
size_t nfirst = (sizeof(iovec) < 72/2) ? size_t nfirst = (sizeof(iovec) < 72/2) ?
72 / sizeof(iovec) : 8; 72 / sizeof(iovec) : 8;
iovec* array = static_cast<iovec*>(::malloc( iovec* array = static_cast<iovec*>(::malloc(
sizeof(iovec) * nfirst)); sizeof(iovec) * nfirst));
if(!array) { if(!array) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_tail = array; m_tail = array;
m_end = array + nfirst; m_end = array + nfirst;
m_array = array; m_array = array;
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size)); chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
if(!c) { if(!c) {
::free(array); ::free(array);
throw std::bad_alloc(); throw std::bad_alloc();
} }
inner_buffer* const ib = &m_inner_buffer; inner_buffer* const ib = &m_inner_buffer;
ib->free = chunk_size; ib->free = chunk_size;
ib->ptr = reinterpret_cast<char*>(c) + sizeof(chunk); ib->ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
ib->head = c; ib->head = c;
c->next = nullptr; c->next = nullptr;
} }
~vrefbuffer() ~vrefbuffer()
{ {
chunk* c = m_inner_buffer.head; chunk* c = m_inner_buffer.head;
while(true) { while(true) {
chunk* n = c->next; chunk* n = c->next;
::free(c); ::free(c);
if(n != NULL) { if(n != NULL) {
c = n; c = n;
} else { } else {
break; break;
} }
} }
::free(m_array); ::free(m_array);
} }
public: public:
void write(const char* buf, size_t len) void write(const char* buf, size_t len)
{ {
if(len < m_ref_size) { if(len < m_ref_size) {
append_copy(buf, len); append_copy(buf, len);
} else { } else {
append_ref(buf, len); append_ref(buf, len);
} }
} }
void append_ref(const char* buf, size_t len) void append_ref(const char* buf, size_t len)
{ {
if(m_tail == m_end) { if(m_tail == m_end) {
const size_t nused = m_tail - m_array; const size_t nused = m_tail - m_array;
const size_t nnext = nused * 2; const size_t nnext = nused * 2;
iovec* nvec = static_cast<iovec*>(::realloc( iovec* nvec = static_cast<iovec*>(::realloc(
m_array, sizeof(iovec)*nnext)); m_array, sizeof(iovec)*nnext));
if(!nvec) { if(!nvec) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
m_array = nvec; m_array = nvec;
m_end = nvec + nnext; m_end = nvec + nnext;
m_tail = nvec + nused; m_tail = nvec + nused;
} }
m_tail->iov_base = const_cast<char*>(buf); m_tail->iov_base = const_cast<char*>(buf);
m_tail->iov_len = len; m_tail->iov_len = len;
++m_tail; ++m_tail;
} }
void append_copy(const char* buf, size_t len) void append_copy(const char* buf, size_t len)
{ {
inner_buffer* const ib = &m_inner_buffer; inner_buffer* const ib = &m_inner_buffer;
if(ib->free < len) { if(ib->free < len) {
size_t sz = m_chunk_size; size_t sz = m_chunk_size;
if(sz < len) { if(sz < len) {
sz = len; sz = len;
} }
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz)); chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
if(!c) { if(!c) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
c->next = ib->head; c->next = ib->head;
ib->head = c; ib->head = c;
ib->free = sz; ib->free = sz;
ib->ptr = reinterpret_cast<char*>(c) + sizeof(chunk); ib->ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
} }
char* m = ib->ptr; char* m = ib->ptr;
::memcpy(m, buf, len); ::memcpy(m, buf, len);
ib->free -= len; ib->free -= len;
ib->ptr += len; ib->ptr += len;
if(m_tail != m_array && m == if(m_tail != m_array && m ==
static_cast<const char*>( static_cast<const char*>(
const_cast<const void *>((m_tail - 1)->iov_base) const_cast<const void *>((m_tail - 1)->iov_base)
) + (m_tail - 1)->iov_len) { ) + (m_tail - 1)->iov_len) {
(m_tail - 1)->iov_len += len; (m_tail - 1)->iov_len += len;
return; return;
} else { } else {
append_ref( m, len); append_ref( m, len);
} }
} }
const struct iovec* vector() const const struct iovec* vector() const
{ {
return m_array; return m_array;
} }
size_t vector_size() const size_t vector_size() const
{ {
return m_tail - m_array; return m_tail - m_array;
} }
void migrate(vrefbuffer* to) void migrate(vrefbuffer* to)
{ {
size_t sz = m_chunk_size; size_t sz = m_chunk_size;
chunk* empty = static_cast<chunk*>(::malloc(sizeof(chunk) + sz)); chunk* empty = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
if(!empty) { if(!empty) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
empty->next = nullptr; empty->next = nullptr;
const size_t nused = m_tail - m_array; const size_t nused = m_tail - m_array;
if(to->m_tail + nused < m_end) { if(to->m_tail + nused < m_end) {
const size_t tosize = to->m_tail - to->m_array; const size_t tosize = to->m_tail - to->m_array;
const size_t reqsize = nused + tosize; const size_t reqsize = nused + tosize;
size_t nnext = (to->m_end - to->m_array) * 2; size_t nnext = (to->m_end - to->m_array) * 2;
while(nnext < reqsize) { while(nnext < reqsize) {
nnext *= 2; nnext *= 2;
} }
iovec* nvec = static_cast<iovec*>(::realloc( iovec* nvec = static_cast<iovec*>(::realloc(
to->m_array, sizeof(iovec)*nnext)); to->m_array, sizeof(iovec)*nnext));
if(!nvec) { if(!nvec) {
::free(empty); ::free(empty);
throw std::bad_alloc(); throw std::bad_alloc();
} }
to->m_array = nvec; to->m_array = nvec;
to->m_end = nvec + nnext; to->m_end = nvec + nnext;
to->m_tail = nvec + tosize; to->m_tail = nvec + tosize;
} }
::memcpy(to->m_tail, m_array, sizeof(iovec)*nused); ::memcpy(to->m_tail, m_array, sizeof(iovec)*nused);
to->m_tail += nused; to->m_tail += nused;
m_tail = m_array; m_tail = m_array;
inner_buffer* const ib = &m_inner_buffer; inner_buffer* const ib = &m_inner_buffer;
inner_buffer* const toib = &to->m_inner_buffer; inner_buffer* const toib = &to->m_inner_buffer;
chunk* last = ib->head; chunk* last = ib->head;
while(last->next) { while(last->next) {
last = last->next; last = last->next;
} }
last->next = toib->head; last->next = toib->head;
toib->head = ib->head; toib->head = ib->head;
if(toib->free < ib->free) { if(toib->free < ib->free) {
toib->free = ib->free; toib->free = ib->free;
toib->ptr = ib->ptr; toib->ptr = ib->ptr;
} }
ib->head = empty; ib->head = empty;
ib->free = sz; ib->free = sz;
ib->ptr = reinterpret_cast<char*>(empty) + sizeof(chunk); ib->ptr = reinterpret_cast<char*>(empty) + sizeof(chunk);
} }
void clear() void clear()
{ {
chunk* c = m_inner_buffer.head->next; chunk* c = m_inner_buffer.head->next;
chunk* n; chunk* n;
while(c) { while(c) {
n = c->next; n = c->next;
::free(c); ::free(c);
c = n; c = n;
} }
inner_buffer* const ib = &m_inner_buffer; inner_buffer* const ib = &m_inner_buffer;
c = ib->head; c = ib->head;
c->next = nullptr; c->next = nullptr;
ib->free = m_chunk_size; ib->free = m_chunk_size;
ib->ptr = reinterpret_cast<char*>(c) + sizeof(chunk); ib->ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
m_tail = m_array; m_tail = m_array;
} }
private: private:
vrefbuffer(const vrefbuffer&); vrefbuffer(const vrefbuffer&);
private: private:
iovec* m_tail; iovec* m_tail;
iovec* m_end; iovec* m_end;
iovec* m_array; iovec* m_array;
size_t m_ref_size; size_t m_ref_size;
size_t m_chunk_size; size_t m_chunk_size;
inner_buffer m_inner_buffer; inner_buffer m_inner_buffer;
}; };

View File

@@ -35,17 +35,17 @@ extern "C" {
*/ */
typedef struct msgpack_zbuffer { typedef struct msgpack_zbuffer {
z_stream stream; z_stream stream;
char* data; char* data;
size_t init_size; size_t init_size;
} msgpack_zbuffer; } msgpack_zbuffer;
#ifndef MSGPACK_ZBUFFER_INIT_SIZE #ifndef MSGPACK_ZBUFFER_INIT_SIZE
#define MSGPACK_ZBUFFER_INIT_SIZE 8192 #define MSGPACK_ZBUFFER_INIT_SIZE 8192
#endif #endif
static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf, static inline bool msgpack_zbuffer_init(
int level, size_t init_size); msgpack_zbuffer* zbuf, int level, size_t init_size);
static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf); static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf);
static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size); static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size);
@@ -71,130 +71,130 @@ static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf);
bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf, bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
int level, size_t init_size) int level, size_t init_size)
{ {
memset(zbuf, 0, sizeof(msgpack_zbuffer)); memset(zbuf, 0, sizeof(msgpack_zbuffer));
zbuf->init_size = init_size; zbuf->init_size = init_size;
if(deflateInit(&zbuf->stream, level) != Z_OK) { if(deflateInit(&zbuf->stream, level) != Z_OK) {
free(zbuf->data); free(zbuf->data);
return false; return false;
} }
return true; return true;
} }
void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf) void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf)
{ {
deflateEnd(&zbuf->stream); deflateEnd(&zbuf->stream);
free(zbuf->data); free(zbuf->data);
} }
msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size) msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size)
{ {
msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer)); msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer));
if (zbuf == NULL) return NULL; if (zbuf == NULL) return NULL;
if(!msgpack_zbuffer_init(zbuf, level, init_size)) { if(!msgpack_zbuffer_init(zbuf, level, init_size)) {
free(zbuf); free(zbuf);
return NULL; return NULL;
} }
return zbuf; return zbuf;
} }
void msgpack_zbuffer_free(msgpack_zbuffer* zbuf) void msgpack_zbuffer_free(msgpack_zbuffer* zbuf)
{ {
if(zbuf == NULL) { return; } if(zbuf == NULL) { return; }
msgpack_zbuffer_destroy(zbuf); msgpack_zbuffer_destroy(zbuf);
free(zbuf); free(zbuf);
} }
bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf) bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf)
{ {
size_t used = (char*)zbuf->stream.next_out - zbuf->data; size_t used = (char*)zbuf->stream.next_out - zbuf->data;
size_t csize = used + zbuf->stream.avail_out; size_t csize = used + zbuf->stream.avail_out;
size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2; size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2;
char* tmp = (char*)realloc(zbuf->data, nsize); char* tmp = (char*)realloc(zbuf->data, nsize);
if(tmp == NULL) { if(tmp == NULL) {
return false; return false;
} }
zbuf->data = tmp; zbuf->data = tmp;
zbuf->stream.next_out = (Bytef*)(tmp + used); zbuf->stream.next_out = (Bytef*)(tmp + used);
zbuf->stream.avail_out = nsize - used; zbuf->stream.avail_out = nsize - used;
return true; return true;
} }
int msgpack_zbuffer_write(void* data, const char* buf, size_t len) int msgpack_zbuffer_write(void* data, const char* buf, size_t len)
{ {
msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data; msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data;
zbuf->stream.next_in = (Bytef*)buf; zbuf->stream.next_in = (Bytef*)buf;
zbuf->stream.avail_in = len; zbuf->stream.avail_in = len;
do { do {
if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) { if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
if(!msgpack_zbuffer_expand(zbuf)) { if(!msgpack_zbuffer_expand(zbuf)) {
return -1; return -1;
} }
} }
if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) { if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) {
return -1; return -1;
} }
} while(zbuf->stream.avail_in > 0); } while(zbuf->stream.avail_in > 0);
return 0; return 0;
} }
char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf) char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf)
{ {
while(true) { while(true) {
switch(deflate(&zbuf->stream, Z_FINISH)) { switch(deflate(&zbuf->stream, Z_FINISH)) {
case Z_STREAM_END: case Z_STREAM_END:
return zbuf->data; return zbuf->data;
case Z_OK: case Z_OK:
if(!msgpack_zbuffer_expand(zbuf)) { if(!msgpack_zbuffer_expand(zbuf)) {
return NULL; return NULL;
} }
break; break;
default: default:
return NULL; return NULL;
} }
} }
} }
const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf) const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf)
{ {
return zbuf->data; return zbuf->data;
} }
size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf) size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf)
{ {
return (char*)zbuf->stream.next_out - zbuf->data; return (char*)zbuf->stream.next_out - zbuf->data;
} }
void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf) void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf)
{ {
zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data; zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data;
zbuf->stream.next_out = (Bytef*)zbuf->data; zbuf->stream.next_out = (Bytef*)zbuf->data;
} }
bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf) bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf)
{ {
if(deflateReset(&zbuf->stream) != Z_OK) { if(deflateReset(&zbuf->stream) != Z_OK) {
return false; return false;
} }
msgpack_zbuffer_reset_buffer(zbuf); msgpack_zbuffer_reset_buffer(zbuf);
return true; return true;
} }
char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf) char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf)
{ {
char* tmp = zbuf->data; char* tmp = zbuf->data;
zbuf->data = NULL; zbuf->data = NULL;
zbuf->stream.next_out = NULL; zbuf->stream.next_out = NULL;
zbuf->stream.avail_out = 0; zbuf->stream.avail_out = 0;
return tmp; return tmp;
} }
/** @} */ /** @} */

View File

@@ -34,125 +34,125 @@ namespace msgpack {
class zbuffer { class zbuffer {
public: public:
zbuffer(int level = Z_DEFAULT_COMPRESSION, zbuffer(int level = Z_DEFAULT_COMPRESSION,
size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE) size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE)
: m_data(nullptr), m_init_size(init_size) : m_data(nullptr), m_init_size(init_size)
{ {
m_stream.zalloc = Z_NULL; m_stream.zalloc = Z_NULL;
m_stream.zfree = Z_NULL; m_stream.zfree = Z_NULL;
m_stream.opaque = Z_NULL; m_stream.opaque = Z_NULL;
m_stream.next_out = Z_NULL; m_stream.next_out = Z_NULL;
m_stream.avail_out = 0; m_stream.avail_out = 0;
if(deflateInit(&m_stream, level) != Z_OK) { if(deflateInit(&m_stream, level) != Z_OK) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
} }
~zbuffer() ~zbuffer()
{ {
deflateEnd(&m_stream); deflateEnd(&m_stream);
::free(m_data); ::free(m_data);
} }
public: public:
void write(const char* buf, size_t len) void write(const char* buf, size_t len)
{ {
m_stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(buf)); m_stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(buf));
m_stream.avail_in = len; m_stream.avail_in = len;
do { do {
if(m_stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) { if(m_stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
if(!expand()) { if(!expand()) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
} }
if(deflate(&m_stream, Z_NO_FLUSH) != Z_OK) { if(deflate(&m_stream, Z_NO_FLUSH) != Z_OK) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
} while(m_stream.avail_in > 0); } while(m_stream.avail_in > 0);
} }
char* flush() char* flush()
{ {
while(true) { while(true) {
switch(deflate(&m_stream, Z_FINISH)) { switch(deflate(&m_stream, Z_FINISH)) {
case Z_STREAM_END: case Z_STREAM_END:
return m_data; return m_data;
case Z_OK: case Z_OK:
if(!expand()) { if(!expand()) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
break; break;
default: default:
throw std::bad_alloc(); throw std::bad_alloc();
} }
} }
} }
char* data() char* data()
{ {
return m_data; return m_data;
} }
const char* data() const const char* data() const
{ {
return m_data; return m_data;
} }
size_t size() const size_t size() const
{ {
return reinterpret_cast<char*>(m_stream.next_out) - m_data; return reinterpret_cast<char*>(m_stream.next_out) - m_data;
} }
void reset() void reset()
{ {
if(deflateReset(&m_stream) != Z_OK) { if(deflateReset(&m_stream) != Z_OK) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
reset_buffer(); reset_buffer();
} }
void reset_buffer() void reset_buffer()
{ {
m_stream.avail_out += reinterpret_cast<char*>(m_stream.next_out) - m_data; m_stream.avail_out += reinterpret_cast<char*>(m_stream.next_out) - m_data;
m_stream.next_out = reinterpret_cast<Bytef*>(m_data); m_stream.next_out = reinterpret_cast<Bytef*>(m_data);
} }
char* release_buffer() char* release_buffer()
{ {
char* tmp = m_data; char* tmp = m_data;
m_data = nullptr; m_data = nullptr;
m_stream.next_out = nullptr; m_stream.next_out = nullptr;
m_stream.avail_out = 0; m_stream.avail_out = 0;
return tmp; return tmp;
} }
private: private:
bool expand() bool expand()
{ {
size_t used = reinterpret_cast<char*>(m_stream.next_out) - m_data; size_t used = reinterpret_cast<char*>(m_stream.next_out) - m_data;
size_t csize = used + m_stream.avail_out; size_t csize = used + m_stream.avail_out;
size_t nsize = (csize == 0) ? m_init_size : csize * 2; size_t nsize = (csize == 0) ? m_init_size : csize * 2;
char* tmp = static_cast<char*>(::realloc(m_data, nsize)); char* tmp = static_cast<char*>(::realloc(m_data, nsize));
if(tmp == nullptr) { if(tmp == nullptr) {
return false; return false;
} }
m_data = tmp; m_data = tmp;
m_stream.next_out = reinterpret_cast<Bytef*>(tmp + used); m_stream.next_out = reinterpret_cast<Bytef*>(tmp + used);
m_stream.avail_out = nsize - used; m_stream.avail_out = nsize - used;
return true; return true;
} }
private: private:
zbuffer(const zbuffer&); zbuffer(const zbuffer&);
private: private:
z_stream m_stream; z_stream m_stream;
char* m_data; char* m_data;
size_t m_init_size; size_t m_init_size;
}; };

View File

@@ -32,29 +32,29 @@ extern "C" {
*/ */
typedef struct msgpack_zone_finalizer { typedef struct msgpack_zone_finalizer {
void (*func)(void* data); void (*func)(void* data);
void* data; void* data;
} msgpack_zone_finalizer; } msgpack_zone_finalizer;
typedef struct msgpack_zone_finalizer_array { typedef struct msgpack_zone_finalizer_array {
msgpack_zone_finalizer* tail; msgpack_zone_finalizer* tail;
msgpack_zone_finalizer* end; msgpack_zone_finalizer* end;
msgpack_zone_finalizer* array; msgpack_zone_finalizer* array;
} msgpack_zone_finalizer_array; } msgpack_zone_finalizer_array;
struct msgpack_zone_chunk; struct msgpack_zone_chunk;
typedef struct msgpack_zone_chunk msgpack_zone_chunk; typedef struct msgpack_zone_chunk msgpack_zone_chunk;
typedef struct msgpack_zone_chunk_list { typedef struct msgpack_zone_chunk_list {
size_t free; size_t free;
char* ptr; char* ptr;
msgpack_zone_chunk* head; msgpack_zone_chunk* head;
} msgpack_zone_chunk_list; } msgpack_zone_chunk_list;
typedef struct msgpack_zone { typedef struct msgpack_zone {
msgpack_zone_chunk_list chunk_list; msgpack_zone_chunk_list chunk_list;
msgpack_zone_finalizer_array finalizer_array; msgpack_zone_finalizer_array finalizer_array;
size_t chunk_size; size_t chunk_size;
} msgpack_zone; } msgpack_zone;
#ifndef MSGPACK_ZONE_CHUNK_SIZE #ifndef MSGPACK_ZONE_CHUNK_SIZE
@@ -71,7 +71,7 @@ static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size);
static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size); static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size);
static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone, static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
void (*func)(void* data), void* data); void (*func)(void* data), void* data);
static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b); static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b);
@@ -90,53 +90,53 @@ void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size);
void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size) void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size)
{ {
char* ptr; char* ptr;
msgpack_zone_chunk_list* cl = &zone->chunk_list; msgpack_zone_chunk_list* cl = &zone->chunk_list;
if(zone->chunk_list.free < size) { if(zone->chunk_list.free < size) {
return msgpack_zone_malloc_expand(zone, size); return msgpack_zone_malloc_expand(zone, size);
} }
ptr = cl->ptr; ptr = cl->ptr;
cl->free -= size; cl->free -= size;
cl->ptr += size; cl->ptr += size;
return ptr; return ptr;
} }
static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size) static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
{ {
return msgpack_zone_malloc_no_align(zone, return msgpack_zone_malloc_no_align(zone,
((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
} }
bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone, bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
void (*func)(void* data), void* data); void (*func)(void* data), void* data);
static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone, static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
void (*func)(void* data), void* data) void (*func)(void* data), void* data)
{ {
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
msgpack_zone_finalizer* fin = fa->tail; msgpack_zone_finalizer* fin = fa->tail;
if(fin == fa->end) { if(fin == fa->end) {
return msgpack_zone_push_finalizer_expand(zone, func, data); return msgpack_zone_push_finalizer_expand(zone, func, data);
} }
fin->func = func; fin->func = func;
fin->data = data; fin->data = data;
++fa->tail; ++fa->tail;
return true; return true;
} }
static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b) static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b)
{ {
msgpack_zone tmp = *a; msgpack_zone tmp = *a;
*a = *b; *a = *b;
*b = tmp; *b = tmp;
} }

View File

@@ -3,17 +3,17 @@
// //
// Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi // Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
#ifndef MSGPACK_ZONE_HPP #ifndef MSGPACK_ZONE_HPP
#define MSGPACK_ZONE_HPP #define MSGPACK_ZONE_HPP

View File

@@ -27,12 +27,12 @@
int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr) int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr)
{ {
return __gnu_cxx::__exchange_and_add(ptr, -1) - 1; return __gnu_cxx::__exchange_and_add(ptr, -1) - 1;
} }
int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr) int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr)
{ {
return __gnu_cxx::__exchange_and_add(ptr, 1) + 1; return __gnu_cxx::__exchange_and_add(ptr, 1) + 1;
} }
#endif // old gcc workaround #endif // old gcc workaround

View File

@@ -34,221 +34,221 @@
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d) int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
{ {
switch(d.type) { switch(d.type) {
case MSGPACK_OBJECT_NIL: case MSGPACK_OBJECT_NIL:
return msgpack_pack_nil(pk); return msgpack_pack_nil(pk);
case MSGPACK_OBJECT_BOOLEAN: case MSGPACK_OBJECT_BOOLEAN:
if(d.via.boolean) { if(d.via.boolean) {
return msgpack_pack_true(pk); return msgpack_pack_true(pk);
} else { } else {
return msgpack_pack_false(pk); return msgpack_pack_false(pk);
} }
case MSGPACK_OBJECT_POSITIVE_INTEGER: case MSGPACK_OBJECT_POSITIVE_INTEGER:
return msgpack_pack_uint64(pk, d.via.u64); return msgpack_pack_uint64(pk, d.via.u64);
case MSGPACK_OBJECT_NEGATIVE_INTEGER: case MSGPACK_OBJECT_NEGATIVE_INTEGER:
return msgpack_pack_int64(pk, d.via.i64); return msgpack_pack_int64(pk, d.via.i64);
case MSGPACK_OBJECT_DOUBLE: case MSGPACK_OBJECT_DOUBLE:
return msgpack_pack_double(pk, d.via.dec); return msgpack_pack_double(pk, d.via.dec);
case MSGPACK_OBJECT_STR: case MSGPACK_OBJECT_STR:
{ {
int ret = msgpack_pack_str(pk, d.via.str.size); int ret = msgpack_pack_str(pk, d.via.str.size);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
return msgpack_pack_str_body(pk, d.via.str.ptr, d.via.str.size); return msgpack_pack_str_body(pk, d.via.str.ptr, d.via.str.size);
} }
case MSGPACK_OBJECT_BIN: case MSGPACK_OBJECT_BIN:
{ {
int ret = msgpack_pack_bin(pk, d.via.bin.size); int ret = msgpack_pack_bin(pk, d.via.bin.size);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size); return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size);
} }
case MSGPACK_OBJECT_ARRAY: case MSGPACK_OBJECT_ARRAY:
{ {
int ret = msgpack_pack_array(pk, d.via.array.size); int ret = msgpack_pack_array(pk, d.via.array.size);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
msgpack_object* o = d.via.array.ptr; msgpack_object* o = d.via.array.ptr;
msgpack_object* const oend = d.via.array.ptr + d.via.array.size; msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
for(; o != oend; ++o) { for(; o != oend; ++o) {
ret = msgpack_pack_object(pk, *o); ret = msgpack_pack_object(pk, *o);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
} }
return 0; return 0;
} }
case MSGPACK_OBJECT_MAP: case MSGPACK_OBJECT_MAP:
{ {
int ret = msgpack_pack_map(pk, d.via.map.size); int ret = msgpack_pack_map(pk, d.via.map.size);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
msgpack_object_kv* kv = d.via.map.ptr; msgpack_object_kv* kv = d.via.map.ptr;
msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size; msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
for(; kv != kvend; ++kv) { for(; kv != kvend; ++kv) {
ret = msgpack_pack_object(pk, kv->key); ret = msgpack_pack_object(pk, kv->key);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
ret = msgpack_pack_object(pk, kv->val); ret = msgpack_pack_object(pk, kv->val);
if(ret < 0) { return ret; } if(ret < 0) { return ret; }
} }
return 0; return 0;
} }
default: default:
return -1; return -1;
} }
} }
void msgpack_object_print(FILE* out, msgpack_object o) void msgpack_object_print(FILE* out, msgpack_object o)
{ {
switch(o.type) { switch(o.type) {
case MSGPACK_OBJECT_NIL: case MSGPACK_OBJECT_NIL:
fprintf(out, "nil"); fprintf(out, "nil");
break; break;
case MSGPACK_OBJECT_BOOLEAN: case MSGPACK_OBJECT_BOOLEAN:
fprintf(out, (o.via.boolean ? "true" : "false")); fprintf(out, (o.via.boolean ? "true" : "false"));
break; break;
case MSGPACK_OBJECT_POSITIVE_INTEGER: case MSGPACK_OBJECT_POSITIVE_INTEGER:
fprintf(out, "%" PRIu64, o.via.u64); fprintf(out, "%" PRIu64, o.via.u64);
break; break;
case MSGPACK_OBJECT_NEGATIVE_INTEGER: case MSGPACK_OBJECT_NEGATIVE_INTEGER:
fprintf(out, "%" PRIi64, o.via.i64); fprintf(out, "%" PRIi64, o.via.i64);
break; break;
case MSGPACK_OBJECT_DOUBLE: case MSGPACK_OBJECT_DOUBLE:
fprintf(out, "%f", o.via.dec); fprintf(out, "%f", o.via.dec);
break; break;
case MSGPACK_OBJECT_STR: case MSGPACK_OBJECT_STR:
fprintf(out, "\""); fprintf(out, "\"");
fwrite(o.via.str.ptr, o.via.str.size, 1, out); fwrite(o.via.str.ptr, o.via.str.size, 1, out);
fprintf(out, "\""); fprintf(out, "\"");
break; break;
case MSGPACK_OBJECT_BIN: case MSGPACK_OBJECT_BIN:
fprintf(out, "\""); fprintf(out, "\"");
fwrite(o.via.bin.ptr, o.via.bin.size, 1, out); fwrite(o.via.bin.ptr, o.via.bin.size, 1, out);
fprintf(out, "\""); fprintf(out, "\"");
break; break;
case MSGPACK_OBJECT_ARRAY: case MSGPACK_OBJECT_ARRAY:
fprintf(out, "["); fprintf(out, "[");
if(o.via.array.size != 0) { if(o.via.array.size != 0) {
msgpack_object* p = o.via.array.ptr; msgpack_object* p = o.via.array.ptr;
msgpack_object_print(out, *p); msgpack_object_print(out, *p);
++p; ++p;
msgpack_object* const pend = o.via.array.ptr + o.via.array.size; msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
for(; p < pend; ++p) { for(; p < pend; ++p) {
fprintf(out, ", "); fprintf(out, ", ");
msgpack_object_print(out, *p); msgpack_object_print(out, *p);
} }
} }
fprintf(out, "]"); fprintf(out, "]");
break; break;
case MSGPACK_OBJECT_MAP: case MSGPACK_OBJECT_MAP:
fprintf(out, "{"); fprintf(out, "{");
if(o.via.map.size != 0) { if(o.via.map.size != 0) {
msgpack_object_kv* p = o.via.map.ptr; msgpack_object_kv* p = o.via.map.ptr;
msgpack_object_print(out, p->key); msgpack_object_print(out, p->key);
fprintf(out, "=>"); fprintf(out, "=>");
msgpack_object_print(out, p->val); msgpack_object_print(out, p->val);
++p; ++p;
msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size; msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
for(; p < pend; ++p) { for(; p < pend; ++p) {
fprintf(out, ", "); fprintf(out, ", ");
msgpack_object_print(out, p->key); msgpack_object_print(out, p->key);
fprintf(out, "=>"); fprintf(out, "=>");
msgpack_object_print(out, p->val); msgpack_object_print(out, p->val);
} }
} }
fprintf(out, "}"); fprintf(out, "}");
break; break;
default: default:
// FIXME // FIXME
fprintf(out, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64); fprintf(out, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64);
} }
} }
bool msgpack_object_equal(const msgpack_object x, const msgpack_object y) bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
{ {
if(x.type != y.type) { return false; } if(x.type != y.type) { return false; }
switch(x.type) { switch(x.type) {
case MSGPACK_OBJECT_NIL: case MSGPACK_OBJECT_NIL:
return true; return true;
case MSGPACK_OBJECT_BOOLEAN: case MSGPACK_OBJECT_BOOLEAN:
return x.via.boolean == y.via.boolean; return x.via.boolean == y.via.boolean;
case MSGPACK_OBJECT_POSITIVE_INTEGER: case MSGPACK_OBJECT_POSITIVE_INTEGER:
return x.via.u64 == y.via.u64; return x.via.u64 == y.via.u64;
case MSGPACK_OBJECT_NEGATIVE_INTEGER: case MSGPACK_OBJECT_NEGATIVE_INTEGER:
return x.via.i64 == y.via.i64; return x.via.i64 == y.via.i64;
case MSGPACK_OBJECT_DOUBLE: case MSGPACK_OBJECT_DOUBLE:
return x.via.dec == y.via.dec; return x.via.dec == y.via.dec;
case MSGPACK_OBJECT_STR: case MSGPACK_OBJECT_STR:
return x.via.str.size == y.via.str.size && return x.via.str.size == y.via.str.size &&
memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0; memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0;
case MSGPACK_OBJECT_BIN: case MSGPACK_OBJECT_BIN:
return x.via.bin.size == y.via.bin.size && return x.via.bin.size == y.via.bin.size &&
memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0; memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
case MSGPACK_OBJECT_ARRAY: case MSGPACK_OBJECT_ARRAY:
if(x.via.array.size != y.via.array.size) { if(x.via.array.size != y.via.array.size) {
return false; return false;
} else if(x.via.array.size == 0) { } else if(x.via.array.size == 0) {
return true; return true;
} else { } else {
msgpack_object* px = x.via.array.ptr; msgpack_object* px = x.via.array.ptr;
msgpack_object* const pxend = x.via.array.ptr + x.via.array.size; msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
msgpack_object* py = y.via.array.ptr; msgpack_object* py = y.via.array.ptr;
do { do {
if(!msgpack_object_equal(*px, *py)) { if(!msgpack_object_equal(*px, *py)) {
return false; return false;
} }
++px; ++px;
++py; ++py;
} while(px < pxend); } while(px < pxend);
return true; return true;
} }
case MSGPACK_OBJECT_MAP: case MSGPACK_OBJECT_MAP:
if(x.via.map.size != y.via.map.size) { if(x.via.map.size != y.via.map.size) {
return false; return false;
} else if(x.via.map.size == 0) { } else if(x.via.map.size == 0) {
return true; return true;
} else { } else {
msgpack_object_kv* px = x.via.map.ptr; msgpack_object_kv* px = x.via.map.ptr;
msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size; msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
msgpack_object_kv* py = y.via.map.ptr; msgpack_object_kv* py = y.via.map.ptr;
do { do {
if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) { if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
return false; return false;
} }
++px; ++px;
++py; ++py;
} while(px < pxend); } while(px < pxend);
return true; return true;
} }
default: default:
return false; return false;
} }
} }

View File

@@ -25,19 +25,19 @@
typedef struct { typedef struct {
msgpack_zone* z; msgpack_zone* z;
bool referenced; bool referenced;
} unpack_user; } unpack_user;
#define msgpack_unpack_struct(name) \ #define msgpack_unpack_struct(name) \
struct template ## name struct template ## name
#define msgpack_unpack_func(ret, name) \ #define msgpack_unpack_func(ret, name) \
ret template ## name ret template ## name
#define msgpack_unpack_callback(name) \ #define msgpack_unpack_callback(name) \
template_callback ## name template_callback ## name
#define msgpack_unpack_object msgpack_object #define msgpack_unpack_object msgpack_object
@@ -51,8 +51,8 @@ static void template_init(template_context* ctx);
static msgpack_object template_data(template_context* ctx); static msgpack_object template_data(template_context* ctx);
static int template_execute(template_context* ctx, static int template_execute(
const char* data, size_t len, size_t* off); template_context* ctx, const char* data, size_t len, size_t* off);
static inline msgpack_object template_callback_root(unpack_user* u) static inline msgpack_object template_callback_root(unpack_user* u)
@@ -72,19 +72,19 @@ static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_o
static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o) static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; } { if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o) static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; } { if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o) static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; } { if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o) static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; } { if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = (uint64_t)d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o) static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; } { o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
@@ -103,62 +103,62 @@ static inline int template_callback_false(unpack_user* u, msgpack_object* o)
static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o) static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o)
{ {
o->type = MSGPACK_OBJECT_ARRAY; o->type = MSGPACK_OBJECT_ARRAY;
o->via.array.size = 0; o->via.array.size = 0;
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object)); o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
if(o->via.array.ptr == NULL) { return -1; } if(o->via.array.ptr == NULL) { return -1; }
return 0; return 0;
} }
static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o) static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
{ {
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
memcpy(&c->via.array.ptr[c->via.array.size], &o, sizeof(msgpack_object)); memcpy(&c->via.array.ptr[c->via.array.size], &o, sizeof(msgpack_object));
#else /* __GNUC__ && !__clang__ */ #else /* __GNUC__ && !__clang__ */
c->via.array.ptr[c->via.array.size] = o; c->via.array.ptr[c->via.array.size] = o;
#endif /* __GNUC__ && !__clang__ */ #endif /* __GNUC__ && !__clang__ */
++c->via.array.size; ++c->via.array.size;
return 0; return 0;
} }
static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o) static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o)
{ {
o->type = MSGPACK_OBJECT_MAP; o->type = MSGPACK_OBJECT_MAP;
o->via.map.size = 0; o->via.map.size = 0;
o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv)); o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv));
if(o->via.map.ptr == NULL) { return -1; } if(o->via.map.ptr == NULL) { return -1; }
return 0; return 0;
} }
static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v) static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
{ {
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
memcpy(&c->via.map.ptr[c->via.map.size].key, &k, sizeof(msgpack_object)); memcpy(&c->via.map.ptr[c->via.map.size].key, &k, sizeof(msgpack_object));
memcpy(&c->via.map.ptr[c->via.map.size].val, &v, sizeof(msgpack_object)); memcpy(&c->via.map.ptr[c->via.map.size].val, &v, sizeof(msgpack_object));
#else /* __GNUC__ && !__clang__ */ #else /* __GNUC__ && !__clang__ */
c->via.map.ptr[c->via.map.size].key = k; c->via.map.ptr[c->via.map.size].key = k;
c->via.map.ptr[c->via.map.size].val = v; c->via.map.ptr[c->via.map.size].val = v;
#endif /* __GNUC__ && !__clang__ */ #endif /* __GNUC__ && !__clang__ */
++c->via.map.size; ++c->via.map.size;
return 0; return 0;
} }
static inline int template_callback_str(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o) static inline int template_callback_str(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
{ {
o->type = MSGPACK_OBJECT_STR; o->type = MSGPACK_OBJECT_STR;
o->via.str.ptr = p; o->via.str.ptr = p;
o->via.str.size = l; o->via.str.size = l;
u->referenced = true; u->referenced = true;
return 0; return 0;
} }
static inline int template_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o) static inline int template_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
{ {
o->type = MSGPACK_OBJECT_BIN; o->type = MSGPACK_OBJECT_BIN;
o->via.bin.ptr = p; o->via.bin.ptr = p;
o->via.bin.size = l; o->via.bin.size = l;
u->referenced = true; u->referenced = true;
return 0; return 0;
} }
#include "msgpack/unpack_template.h" #include "msgpack/unpack_template.h"
@@ -172,316 +172,316 @@ static inline int template_callback_bin(unpack_user* u, const char* b, const cha
static inline void init_count(void* buffer) static inline void init_count(void* buffer)
{ {
*(volatile _msgpack_atomic_counter_t*)buffer = 1; *(volatile _msgpack_atomic_counter_t*)buffer = 1;
} }
static inline void decl_count(void* buffer) static inline void decl_count(void* buffer)
{ {
// atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); } // atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); }
if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) { if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) {
free(buffer); free(buffer);
} }
} }
static inline void incr_count(void* buffer) static inline void incr_count(void* buffer)
{ {
// atomic ++*(_msgpack_atomic_counter_t*)buffer; // atomic ++*(_msgpack_atomic_counter_t*)buffer;
_msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer); _msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer);
} }
static inline _msgpack_atomic_counter_t get_count(void* buffer) static inline _msgpack_atomic_counter_t get_count(void* buffer)
{ {
return *(volatile _msgpack_atomic_counter_t*)buffer; return *(volatile _msgpack_atomic_counter_t*)buffer;
} }
bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size) bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
{ {
if(initial_buffer_size < COUNTER_SIZE) { if(initial_buffer_size < COUNTER_SIZE) {
initial_buffer_size = COUNTER_SIZE; initial_buffer_size = COUNTER_SIZE;
} }
char* buffer = (char*)malloc(initial_buffer_size); char* buffer = (char*)malloc(initial_buffer_size);
if(buffer == NULL) { if(buffer == NULL) {
return false; return false;
} }
void* ctx = malloc(sizeof(template_context)); void* ctx = malloc(sizeof(template_context));
if(ctx == NULL) { if(ctx == NULL) {
free(buffer); free(buffer);
return false; return false;
} }
msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
if(z == NULL) { if(z == NULL) {
free(ctx); free(ctx);
free(buffer); free(buffer);
return false; return false;
} }
mpac->buffer = buffer; mpac->buffer = buffer;
mpac->used = COUNTER_SIZE; mpac->used = COUNTER_SIZE;
mpac->free = initial_buffer_size - mpac->used; mpac->free = initial_buffer_size - mpac->used;
mpac->off = COUNTER_SIZE; mpac->off = COUNTER_SIZE;
mpac->parsed = 0; mpac->parsed = 0;
mpac->initial_buffer_size = initial_buffer_size; mpac->initial_buffer_size = initial_buffer_size;
mpac->z = z; mpac->z = z;
mpac->ctx = ctx; mpac->ctx = ctx;
init_count(mpac->buffer); init_count(mpac->buffer);
template_init(CTX_CAST(mpac->ctx)); template_init(CTX_CAST(mpac->ctx));
CTX_CAST(mpac->ctx)->user.z = mpac->z; CTX_CAST(mpac->ctx)->user.z = mpac->z;
CTX_CAST(mpac->ctx)->user.referenced = false; CTX_CAST(mpac->ctx)->user.referenced = false;
return true; return true;
} }
void msgpack_unpacker_destroy(msgpack_unpacker* mpac) void msgpack_unpacker_destroy(msgpack_unpacker* mpac)
{ {
msgpack_zone_free(mpac->z); msgpack_zone_free(mpac->z);
free(mpac->ctx); free(mpac->ctx);
decl_count(mpac->buffer); decl_count(mpac->buffer);
} }
msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size) msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size)
{ {
msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker)); msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker));
if(mpac == NULL) { if(mpac == NULL) {
return NULL; return NULL;
} }
if(!msgpack_unpacker_init(mpac, initial_buffer_size)) { if(!msgpack_unpacker_init(mpac, initial_buffer_size)) {
free(mpac); free(mpac);
return NULL; return NULL;
} }
return mpac; return mpac;
} }
void msgpack_unpacker_free(msgpack_unpacker* mpac) void msgpack_unpacker_free(msgpack_unpacker* mpac)
{ {
msgpack_unpacker_destroy(mpac); msgpack_unpacker_destroy(mpac);
free(mpac); free(mpac);
} }
bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size) bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size)
{ {
if(mpac->used == mpac->off && get_count(mpac->buffer) == 1 if(mpac->used == mpac->off && get_count(mpac->buffer) == 1
&& !CTX_REFERENCED(mpac)) { && !CTX_REFERENCED(mpac)) {
// rewind buffer // rewind buffer
mpac->free += mpac->used - COUNTER_SIZE; mpac->free += mpac->used - COUNTER_SIZE;
mpac->used = COUNTER_SIZE; mpac->used = COUNTER_SIZE;
mpac->off = COUNTER_SIZE; mpac->off = COUNTER_SIZE;
if(mpac->free >= size) { if(mpac->free >= size) {
return true; return true;
} }
} }
if(mpac->off == COUNTER_SIZE) { if(mpac->off == COUNTER_SIZE) {
size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE
while(next_size < size + mpac->used) { while(next_size < size + mpac->used) {
next_size *= 2; next_size *= 2;
} }
char* tmp = (char*)realloc(mpac->buffer, next_size); char* tmp = (char*)realloc(mpac->buffer, next_size);
if(tmp == NULL) { if(tmp == NULL) {
return false; return false;
} }
mpac->buffer = tmp; mpac->buffer = tmp;
mpac->free = next_size - mpac->used; mpac->free = next_size - mpac->used;
} else { } else {
size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE
size_t not_parsed = mpac->used - mpac->off; size_t not_parsed = mpac->used - mpac->off;
while(next_size < size + not_parsed + COUNTER_SIZE) { while(next_size < size + not_parsed + COUNTER_SIZE) {
next_size *= 2; next_size *= 2;
} }
char* tmp = (char*)malloc(next_size); char* tmp = (char*)malloc(next_size);
if(tmp == NULL) { if(tmp == NULL) {
return false; return false;
} }
init_count(tmp); init_count(tmp);
memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed); memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed);
if(CTX_REFERENCED(mpac)) { if(CTX_REFERENCED(mpac)) {
if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) { if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
free(tmp); free(tmp);
return false; return false;
} }
CTX_REFERENCED(mpac) = false; CTX_REFERENCED(mpac) = false;
} else { } else {
decl_count(mpac->buffer); decl_count(mpac->buffer);
} }
mpac->buffer = tmp; mpac->buffer = tmp;
mpac->used = not_parsed + COUNTER_SIZE; mpac->used = not_parsed + COUNTER_SIZE;
mpac->free = next_size - mpac->used; mpac->free = next_size - mpac->used;
mpac->off = COUNTER_SIZE; mpac->off = COUNTER_SIZE;
} }
return true; return true;
} }
int msgpack_unpacker_execute(msgpack_unpacker* mpac) int msgpack_unpacker_execute(msgpack_unpacker* mpac)
{ {
size_t off = mpac->off; size_t off = mpac->off;
int ret = template_execute(CTX_CAST(mpac->ctx), int ret = template_execute(CTX_CAST(mpac->ctx),
mpac->buffer, mpac->used, &mpac->off); mpac->buffer, mpac->used, &mpac->off);
if(mpac->off > off) { if(mpac->off > off) {
mpac->parsed += mpac->off - off; mpac->parsed += mpac->off - off;
} }
return ret; return ret;
} }
msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac) msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac)
{ {
return template_data(CTX_CAST(mpac->ctx)); return template_data(CTX_CAST(mpac->ctx));
} }
msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac) msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
{ {
if(!msgpack_unpacker_flush_zone(mpac)) { if(!msgpack_unpacker_flush_zone(mpac)) {
return NULL; return NULL;
} }
msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
if(r == NULL) { if(r == NULL) {
return NULL; return NULL;
} }
msgpack_zone* old = mpac->z; msgpack_zone* old = mpac->z;
mpac->z = r; mpac->z = r;
CTX_CAST(mpac->ctx)->user.z = mpac->z; CTX_CAST(mpac->ctx)->user.z = mpac->z;
return old; return old;
} }
void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac) void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac)
{ {
msgpack_zone_clear(mpac->z); msgpack_zone_clear(mpac->z);
} }
bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac) bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac)
{ {
if(CTX_REFERENCED(mpac)) { if(CTX_REFERENCED(mpac)) {
if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) { if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
return false; return false;
} }
CTX_REFERENCED(mpac) = false; CTX_REFERENCED(mpac) = false;
incr_count(mpac->buffer); incr_count(mpac->buffer);
} }
return true; return true;
} }
void msgpack_unpacker_reset(msgpack_unpacker* mpac) void msgpack_unpacker_reset(msgpack_unpacker* mpac)
{ {
template_init(CTX_CAST(mpac->ctx)); template_init(CTX_CAST(mpac->ctx));
// don't reset referenced flag // don't reset referenced flag
mpac->parsed = 0; mpac->parsed = 0;
} }
bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result) bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result)
{ {
if(result->zone != NULL) { if(result->zone != NULL) {
msgpack_zone_free(result->zone); msgpack_zone_free(result->zone);
} }
int ret = msgpack_unpacker_execute(mpac); int ret = msgpack_unpacker_execute(mpac);
if(ret <= 0) { if(ret <= 0) {
result->zone = NULL; result->zone = NULL;
memset(&result->data, 0, sizeof(msgpack_object)); memset(&result->data, 0, sizeof(msgpack_object));
return false; return false;
} }
result->zone = msgpack_unpacker_release_zone(mpac); result->zone = msgpack_unpacker_release_zone(mpac);
result->data = msgpack_unpacker_data(mpac); result->data = msgpack_unpacker_data(mpac);
msgpack_unpacker_reset(mpac); msgpack_unpacker_reset(mpac);
return true; return true;
} }
msgpack_unpack_return msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off, msgpack_unpack(const char* data, size_t len, size_t* off,
msgpack_zone* result_zone, msgpack_object* result) msgpack_zone* result_zone, msgpack_object* result)
{ {
size_t noff = 0; size_t noff = 0;
if(off != NULL) { noff = *off; } if(off != NULL) { noff = *off; }
if(len <= noff) { if(len <= noff) {
// FIXME // FIXME
return MSGPACK_UNPACK_CONTINUE; return MSGPACK_UNPACK_CONTINUE;
} }
template_context ctx; template_context ctx;
template_init(&ctx); template_init(&ctx);
ctx.user.z = result_zone; ctx.user.z = result_zone;
ctx.user.referenced = false; ctx.user.referenced = false;
int e = template_execute(&ctx, data, len, &noff); int e = template_execute(&ctx, data, len, &noff);
if(e < 0) { if(e < 0) {
return MSGPACK_UNPACK_PARSE_ERROR; return MSGPACK_UNPACK_PARSE_ERROR;
} }
if(off != NULL) { *off = noff; } if(off != NULL) { *off = noff; }
if(e == 0) { if(e == 0) {
return MSGPACK_UNPACK_CONTINUE; return MSGPACK_UNPACK_CONTINUE;
} }
*result = template_data(&ctx); *result = template_data(&ctx);
if(noff < len) { if(noff < len) {
return MSGPACK_UNPACK_EXTRA_BYTES; return MSGPACK_UNPACK_EXTRA_BYTES;
} }
return MSGPACK_UNPACK_SUCCESS; return MSGPACK_UNPACK_SUCCESS;
} }
bool msgpack_unpack_next(msgpack_unpacked* result, bool msgpack_unpack_next(msgpack_unpacked* result,
const char* data, size_t len, size_t* off) const char* data, size_t len, size_t* off)
{ {
msgpack_unpacked_destroy(result); msgpack_unpacked_destroy(result);
size_t noff = 0; size_t noff = 0;
if(off != NULL) { noff = *off; } if(off != NULL) { noff = *off; }
if(len <= noff) { if(len <= noff) {
return false; return false;
} }
msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
template_context ctx; template_context ctx;
template_init(&ctx); template_init(&ctx);
ctx.user.z = z; ctx.user.z = z;
ctx.user.referenced = false; ctx.user.referenced = false;
int e = template_execute(&ctx, data, len, &noff); int e = template_execute(&ctx, data, len, &noff);
if(e <= 0) { if(e <= 0) {
msgpack_zone_free(z); msgpack_zone_free(z);
return false; return false;
} }
if(off != NULL) { *off = noff; } if(off != NULL) { *off = noff; }
result->zone = z; result->zone = z;
result->data = template_data(&ctx); result->data = template_data(&ctx);
return true; return true;
} }
#if defined(MSGPACK_OLD_COMPILER_BUS_ERROR_WORKAROUND) #if defined(MSGPACK_OLD_COMPILER_BUS_ERROR_WORKAROUND)

View File

@@ -2,16 +2,16 @@
const char* msgpack_version(void) const char* msgpack_version(void)
{ {
return MSGPACK_VERSION; return MSGPACK_VERSION;
} }
int msgpack_version_major(void) int msgpack_version_major(void)
{ {
return MSGPACK_VERSION_MAJOR; return MSGPACK_VERSION_MAJOR;
} }
int msgpack_version_minor(void) int msgpack_version_minor(void)
{ {
return MSGPACK_VERSION_MINOR; return MSGPACK_VERSION_MINOR;
} }

View File

@@ -20,201 +20,201 @@
#include <string.h> #include <string.h>
struct msgpack_vrefbuffer_chunk { struct msgpack_vrefbuffer_chunk {
struct msgpack_vrefbuffer_chunk* next; struct msgpack_vrefbuffer_chunk* next;
/* data ... */ /* data ... */
}; };
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size) size_t ref_size, size_t chunk_size)
{ {
vbuf->chunk_size = chunk_size; vbuf->chunk_size = chunk_size;
vbuf->ref_size = ref_size; vbuf->ref_size = ref_size;
size_t nfirst = (sizeof(struct iovec) < 72/2) ? size_t nfirst = (sizeof(struct iovec) < 72/2) ?
72 / sizeof(struct iovec) : 8; 72 / sizeof(struct iovec) : 8;
struct iovec* array = (struct iovec*)malloc( struct iovec* array = (struct iovec*)malloc(
sizeof(struct iovec) * nfirst); sizeof(struct iovec) * nfirst);
if(array == NULL) { if(array == NULL) {
return false; return false;
} }
vbuf->tail = array; vbuf->tail = array;
vbuf->end = array + nfirst; vbuf->end = array + nfirst;
vbuf->array = array; vbuf->array = array;
msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc( msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + chunk_size); sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
if(chunk == NULL) { if(chunk == NULL) {
free(array); free(array);
return false; return false;
} }
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
ib->free = chunk_size; ib->free = chunk_size;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
ib->head = chunk; ib->head = chunk;
chunk->next = NULL; chunk->next = NULL;
return true; return true;
} }
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf) void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
{ {
msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head; msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
while(true) { while(true) {
msgpack_vrefbuffer_chunk* n = c->next; msgpack_vrefbuffer_chunk* n = c->next;
free(c); free(c);
if(n != NULL) { if(n != NULL) {
c = n; c = n;
} else { } else {
break; break;
} }
} }
free(vbuf->array); free(vbuf->array);
} }
void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf) void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf)
{ {
msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next; msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next;
msgpack_vrefbuffer_chunk* n; msgpack_vrefbuffer_chunk* n;
while(c != NULL) { while(c != NULL) {
n = c->next; n = c->next;
free(c); free(c);
c = n; c = n;
} }
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
msgpack_vrefbuffer_chunk* chunk = ib->head; msgpack_vrefbuffer_chunk* chunk = ib->head;
chunk->next = NULL; chunk->next = NULL;
ib->free = vbuf->chunk_size; ib->free = vbuf->chunk_size;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
vbuf->tail = vbuf->array; vbuf->tail = vbuf->array;
} }
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
const char* buf, size_t len) const char* buf, size_t len)
{ {
if(vbuf->tail == vbuf->end) { if(vbuf->tail == vbuf->end) {
const size_t nused = (size_t)(vbuf->tail - vbuf->array); const size_t nused = (size_t)(vbuf->tail - vbuf->array);
const size_t nnext = nused * 2; const size_t nnext = nused * 2;
struct iovec* nvec = (struct iovec*)realloc( struct iovec* nvec = (struct iovec*)realloc(
vbuf->array, sizeof(struct iovec)*nnext); vbuf->array, sizeof(struct iovec)*nnext);
if(nvec == NULL) { if(nvec == NULL) {
return -1; return -1;
} }
vbuf->array = nvec; vbuf->array = nvec;
vbuf->end = nvec + nnext; vbuf->end = nvec + nnext;
vbuf->tail = nvec + nused; vbuf->tail = nvec + nused;
} }
vbuf->tail->iov_base = (char*)buf; vbuf->tail->iov_base = (char*)buf;
vbuf->tail->iov_len = len; vbuf->tail->iov_len = len;
++vbuf->tail; ++vbuf->tail;
return 0; return 0;
} }
int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf, int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
const char* buf, size_t len) const char* buf, size_t len)
{ {
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
if(ib->free < len) { if(ib->free < len) {
size_t sz = vbuf->chunk_size; size_t sz = vbuf->chunk_size;
if(sz < len) { if(sz < len) {
sz = len; sz = len;
} }
msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc( msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + sz); sizeof(msgpack_vrefbuffer_chunk) + sz);
if(chunk == NULL) { if(chunk == NULL) {
return -1; return -1;
} }
chunk->next = ib->head; chunk->next = ib->head;
ib->head = chunk; ib->head = chunk;
ib->free = sz; ib->free = sz;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
} }
char* m = ib->ptr; char* m = ib->ptr;
memcpy(m, buf, len); memcpy(m, buf, len);
ib->free -= len; ib->free -= len;
ib->ptr += len; ib->ptr += len;
if(vbuf->tail != vbuf->array && m == if(vbuf->tail != vbuf->array && m ==
(const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) { (const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
(vbuf->tail-1)->iov_len += len; (vbuf->tail-1)->iov_len += len;
return 0; return 0;
} else { } else {
return msgpack_vrefbuffer_append_ref(vbuf, m, len); return msgpack_vrefbuffer_append_ref(vbuf, m, len);
} }
} }
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to) int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
{ {
size_t sz = vbuf->chunk_size; size_t sz = vbuf->chunk_size;
msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc( msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + sz); sizeof(msgpack_vrefbuffer_chunk) + sz);
if(empty == NULL) { if(empty == NULL) {
return -1; return -1;
} }
empty->next = NULL; empty->next = NULL;
const size_t nused = (size_t)(vbuf->tail - vbuf->array); const size_t nused = (size_t)(vbuf->tail - vbuf->array);
if(to->tail + nused < vbuf->end) { if(to->tail + nused < vbuf->end) {
const size_t tosize = (size_t)(to->tail - to->array); const size_t tosize = (size_t)(to->tail - to->array);
const size_t reqsize = nused + tosize; const size_t reqsize = nused + tosize;
size_t nnext = (size_t)(to->end - to->array) * 2; size_t nnext = (size_t)(to->end - to->array) * 2;
while(nnext < reqsize) { while(nnext < reqsize) {
nnext *= 2; nnext *= 2;
} }
struct iovec* nvec = (struct iovec*)realloc( struct iovec* nvec = (struct iovec*)realloc(
to->array, sizeof(struct iovec)*nnext); to->array, sizeof(struct iovec)*nnext);
if(nvec == NULL) { if(nvec == NULL) {
free(empty); free(empty);
return -1; return -1;
} }
to->array = nvec; to->array = nvec;
to->end = nvec + nnext; to->end = nvec + nnext;
to->tail = nvec + tosize; to->tail = nvec + tosize;
} }
memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused); memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
to->tail += nused; to->tail += nused;
vbuf->tail = vbuf->array; vbuf->tail = vbuf->array;
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer; msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
msgpack_vrefbuffer_chunk* last = ib->head; msgpack_vrefbuffer_chunk* last = ib->head;
while(last->next != NULL) { while(last->next != NULL) {
last = last->next; last = last->next;
} }
last->next = toib->head; last->next = toib->head;
toib->head = ib->head; toib->head = ib->head;
if(toib->free < ib->free) { if(toib->free < ib->free) {
toib->free = ib->free; toib->free = ib->free;
toib->ptr = ib->ptr; toib->ptr = ib->ptr;
} }
ib->head = empty; ib->head = empty;
ib->free = sz; ib->free = sz;
ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk); ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
return 0; return 0;
} }

View File

@@ -20,202 +20,202 @@
#include <string.h> #include <string.h>
struct msgpack_zone_chunk { struct msgpack_zone_chunk {
struct msgpack_zone_chunk* next; struct msgpack_zone_chunk* next;
/* data ... */ /* data ... */
}; };
static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size) static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
{ {
msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc( msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
sizeof(msgpack_zone_chunk) + chunk_size); sizeof(msgpack_zone_chunk) + chunk_size);
if(chunk == NULL) { if(chunk == NULL) {
return false; return false;
} }
cl->head = chunk; cl->head = chunk;
cl->free = chunk_size; cl->free = chunk_size;
cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk); cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
chunk->next = NULL; chunk->next = NULL;
return true; return true;
} }
static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl) static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
{ {
msgpack_zone_chunk* c = cl->head; msgpack_zone_chunk* c = cl->head;
while(true) { while(true) {
msgpack_zone_chunk* n = c->next; msgpack_zone_chunk* n = c->next;
free(c); free(c);
if(n != NULL) { if(n != NULL) {
c = n; c = n;
} else { } else {
break; break;
} }
} }
} }
static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size) static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
{ {
msgpack_zone_chunk* c = cl->head; msgpack_zone_chunk* c = cl->head;
while(true) { while(true) {
msgpack_zone_chunk* n = c->next; msgpack_zone_chunk* n = c->next;
if(n != NULL) { if(n != NULL) {
free(c); free(c);
c = n; c = n;
} else { } else {
cl->head = c; cl->head = c;
break; break;
} }
} }
cl->head->next = NULL; cl->head->next = NULL;
cl->free = chunk_size; cl->free = chunk_size;
cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk); cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
} }
void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size) void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
{ {
msgpack_zone_chunk_list* const cl = &zone->chunk_list; msgpack_zone_chunk_list* const cl = &zone->chunk_list;
size_t sz = zone->chunk_size; size_t sz = zone->chunk_size;
while(sz < size) { while(sz < size) {
sz *= 2; sz *= 2;
} }
msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc( msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
sizeof(msgpack_zone_chunk) + sz); sizeof(msgpack_zone_chunk) + sz);
if (chunk == NULL) return NULL; if (chunk == NULL) return NULL;
char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk); char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
chunk->next = cl->head; chunk->next = cl->head;
cl->head = chunk; cl->head = chunk;
cl->free = sz - size; cl->free = sz - size;
cl->ptr = ptr + size; cl->ptr = ptr + size;
return ptr; return ptr;
} }
static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa) static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
{ {
fa->tail = NULL; fa->tail = NULL;
fa->end = NULL; fa->end = NULL;
fa->array = NULL; fa->array = NULL;
} }
static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa) static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
{ {
msgpack_zone_finalizer* fin = fa->tail; msgpack_zone_finalizer* fin = fa->tail;
for(; fin != fa->array; --fin) { for(; fin != fa->array; --fin) {
(*(fin-1)->func)((fin-1)->data); (*(fin-1)->func)((fin-1)->data);
} }
} }
static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa) static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
{ {
call_finalizer_array(fa); call_finalizer_array(fa);
free(fa->array); free(fa->array);
} }
static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa) static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
{ {
call_finalizer_array(fa); call_finalizer_array(fa);
fa->tail = fa->array; fa->tail = fa->array;
} }
bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone, bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
void (*func)(void* data), void* data) void (*func)(void* data), void* data)
{ {
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
const size_t nused = (size_t)(fa->end - fa->array); const size_t nused = (size_t)(fa->end - fa->array);
size_t nnext; size_t nnext;
if(nused == 0) { if(nused == 0) {
nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ? nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
72 / sizeof(msgpack_zone_finalizer) : 8; 72 / sizeof(msgpack_zone_finalizer) : 8;
} else { } else {
nnext = nused * 2; nnext = nused * 2;
} }
msgpack_zone_finalizer* tmp = msgpack_zone_finalizer* tmp =
(msgpack_zone_finalizer*)realloc(fa->array, (msgpack_zone_finalizer*)realloc(fa->array,
sizeof(msgpack_zone_finalizer) * nnext); sizeof(msgpack_zone_finalizer) * nnext);
if(tmp == NULL) { if(tmp == NULL) {
return false; return false;
} }
fa->array = tmp; fa->array = tmp;
fa->end = tmp + nnext; fa->end = tmp + nnext;
fa->tail = tmp + nused; fa->tail = tmp + nused;
fa->tail->func = func; fa->tail->func = func;
fa->tail->data = data; fa->tail->data = data;
++fa->tail; ++fa->tail;
return true; return true;
} }
bool msgpack_zone_is_empty(msgpack_zone* zone) bool msgpack_zone_is_empty(msgpack_zone* zone)
{ {
msgpack_zone_chunk_list* const cl = &zone->chunk_list; msgpack_zone_chunk_list* const cl = &zone->chunk_list;
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
return cl->free == zone->chunk_size && cl->head->next == NULL && return cl->free == zone->chunk_size && cl->head->next == NULL &&
fa->tail == fa->array; fa->tail == fa->array;
} }
void msgpack_zone_destroy(msgpack_zone* zone) void msgpack_zone_destroy(msgpack_zone* zone)
{ {
destroy_finalizer_array(&zone->finalizer_array); destroy_finalizer_array(&zone->finalizer_array);
destroy_chunk_list(&zone->chunk_list); destroy_chunk_list(&zone->chunk_list);
} }
void msgpack_zone_clear(msgpack_zone* zone) void msgpack_zone_clear(msgpack_zone* zone)
{ {
clear_finalizer_array(&zone->finalizer_array); clear_finalizer_array(&zone->finalizer_array);
clear_chunk_list(&zone->chunk_list, zone->chunk_size); clear_chunk_list(&zone->chunk_list, zone->chunk_size);
} }
bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size) bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
{ {
zone->chunk_size = chunk_size; zone->chunk_size = chunk_size;
if(!init_chunk_list(&zone->chunk_list, chunk_size)) { if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
return false; return false;
} }
init_finalizer_array(&zone->finalizer_array); init_finalizer_array(&zone->finalizer_array);
return true; return true;
} }
msgpack_zone* msgpack_zone_new(size_t chunk_size) msgpack_zone* msgpack_zone_new(size_t chunk_size)
{ {
msgpack_zone* zone = (msgpack_zone*)malloc( msgpack_zone* zone = (msgpack_zone*)malloc(
sizeof(msgpack_zone) + chunk_size); sizeof(msgpack_zone) + chunk_size);
if(zone == NULL) { if(zone == NULL) {
return NULL; return NULL;
} }
zone->chunk_size = chunk_size; zone->chunk_size = chunk_size;
if(!init_chunk_list(&zone->chunk_list, chunk_size)) { if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
free(zone); free(zone);
return NULL; return NULL;
} }
init_finalizer_array(&zone->finalizer_array); init_finalizer_array(&zone->finalizer_array);
return zone; return zone;
} }
void msgpack_zone_free(msgpack_zone* zone) void msgpack_zone_free(msgpack_zone* zone)
{ {
if(zone == NULL) { return; } if(zone == NULL) { return; }
msgpack_zone_destroy(zone); msgpack_zone_destroy(zone);
free(zone); free(zone);
} }

View File

@@ -7,114 +7,114 @@
TEST(buffer, sbuffer) TEST(buffer, sbuffer)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
sbuf.write("a", 1); sbuf.write("a", 1);
sbuf.write("a", 1); sbuf.write("a", 1);
sbuf.write("a", 1); sbuf.write("a", 1);
EXPECT_EQ(3, sbuf.size()); EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
sbuf.clear(); sbuf.clear();
sbuf.write("a", 1); sbuf.write("a", 1);
sbuf.write("a", 1); sbuf.write("a", 1);
sbuf.write("a", 1); sbuf.write("a", 1);
EXPECT_EQ(3, sbuf.size()); EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
} }
TEST(buffer, vrefbuffer) TEST(buffer, vrefbuffer)
{ {
msgpack::vrefbuffer vbuf; msgpack::vrefbuffer vbuf;
vbuf.write("a", 1); vbuf.write("a", 1);
vbuf.write("a", 1); vbuf.write("a", 1);
vbuf.write("a", 1); vbuf.write("a", 1);
const struct iovec* vec = vbuf.vector(); const struct iovec* vec = vbuf.vector();
size_t veclen = vbuf.vector_size(); size_t veclen = vbuf.vector_size();
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
for(size_t i=0; i < veclen; ++i) { for(size_t i=0; i < veclen; ++i) {
sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len);
} }
EXPECT_EQ(3, sbuf.size()); EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
vbuf.clear(); vbuf.clear();
vbuf.write("a", 1); vbuf.write("a", 1);
vbuf.write("a", 1); vbuf.write("a", 1);
vbuf.write("a", 1); vbuf.write("a", 1);
vec = vbuf.vector(); vec = vbuf.vector();
veclen = vbuf.vector_size(); veclen = vbuf.vector_size();
sbuf.clear(); sbuf.clear();
for(size_t i=0; i < veclen; ++i) { for(size_t i=0; i < veclen; ++i) {
sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len);
} }
EXPECT_EQ(3, sbuf.size()); EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
} }
TEST(buffer, zbuffer) TEST(buffer, zbuffer)
{ {
msgpack::zbuffer zbuf; msgpack::zbuffer zbuf;
zbuf.write("a", 1); zbuf.write("a", 1);
zbuf.write("a", 1); zbuf.write("a", 1);
zbuf.write("a", 1); zbuf.write("a", 1);
zbuf.flush(); zbuf.flush();
} }
TEST(buffer, fbuffer) TEST(buffer, fbuffer)
{ {
FILE* file = tmpfile(); FILE* file = tmpfile();
EXPECT_TRUE( file != NULL ); EXPECT_TRUE( file != NULL );
msgpack::fbuffer fbuf(file); msgpack::fbuffer fbuf(file);
EXPECT_EQ(file, fbuf.file()); EXPECT_EQ(file, fbuf.file());
fbuf.write("a", 1); fbuf.write("a", 1);
fbuf.write("a", 1); fbuf.write("a", 1);
fbuf.write("a", 1); fbuf.write("a", 1);
fflush(file); fflush(file);
rewind(file); rewind(file);
for (size_t i=0; i < 3; ++i) { for (size_t i=0; i < 3; ++i) {
int ch = fgetc(file); int ch = fgetc(file);
EXPECT_TRUE(ch != EOF); EXPECT_TRUE(ch != EOF);
EXPECT_EQ('a', static_cast<char>(ch)); EXPECT_EQ('a', static_cast<char>(ch));
} }
EXPECT_EQ(EOF, fgetc(file)); EXPECT_EQ(EOF, fgetc(file));
fclose(file); fclose(file);
} }
TEST(buffer, fbuffer_c) TEST(buffer, fbuffer_c)
{ {
FILE* file = tmpfile(); FILE* file = tmpfile();
void* fbuf = (void*)file; void* fbuf = (void*)file;
EXPECT_TRUE( file != NULL ); EXPECT_TRUE( file != NULL );
EXPECT_EQ(0, msgpack_fbuffer_write(fbuf, "a", 1)); EXPECT_EQ(0, msgpack_fbuffer_write(fbuf, "a", 1));
EXPECT_EQ(0, msgpack_fbuffer_write(fbuf, "a", 1)); EXPECT_EQ(0, msgpack_fbuffer_write(fbuf, "a", 1));
EXPECT_EQ(0, msgpack_fbuffer_write(fbuf, "a", 1)); EXPECT_EQ(0, msgpack_fbuffer_write(fbuf, "a", 1));
fflush(file); fflush(file);
rewind(file); rewind(file);
for (size_t i=0; i < 3; ++i) { for (size_t i=0; i < 3; ++i) {
int ch = fgetc(file); int ch = fgetc(file);
EXPECT_TRUE(ch != EOF); EXPECT_TRUE(ch != EOF);
EXPECT_EQ('a', (char) ch); EXPECT_EQ('a', (char) ch);
} }
EXPECT_EQ(EOF, fgetc(file)); EXPECT_EQ(EOF, fgetc(file));
fclose(file); fclose(file);
} }

View File

@@ -4,35 +4,35 @@
static void feed_file(msgpack::unpacker& pac, const char* path) static void feed_file(msgpack::unpacker& pac, const char* path)
{ {
std::ifstream fin(path); std::ifstream fin(path);
while(true) { while(true) {
pac.reserve_buffer(32*1024); pac.reserve_buffer(32*1024);
fin.read(pac.buffer(), pac.buffer_capacity()); fin.read(pac.buffer(), pac.buffer_capacity());
if(fin.bad()) { if(fin.bad()) {
throw std::runtime_error("read failed"); throw std::runtime_error("read failed");
} }
pac.buffer_consumed(fin.gcount()); pac.buffer_consumed(fin.gcount());
if(fin.fail()) { if(fin.fail()) {
break; break;
} }
} }
} }
TEST(cases, format) TEST(cases, format)
{ {
msgpack::unpacker pac; msgpack::unpacker pac;
msgpack::unpacker pac_compact; msgpack::unpacker pac_compact;
feed_file(pac, "cases.mpac"); feed_file(pac, "cases.mpac");
feed_file(pac_compact, "cases_compact.mpac"); feed_file(pac_compact, "cases_compact.mpac");
msgpack::unpacked result; msgpack::unpacked result;
while(pac.next(&result)) { while(pac.next(&result)) {
msgpack::unpacked result_compact; msgpack::unpacked result_compact;
EXPECT_TRUE( pac_compact.next(&result_compact) ); EXPECT_TRUE( pac_compact.next(&result_compact) );
EXPECT_EQ(result_compact.get(), result.get()); EXPECT_EQ(result_compact.get(), result.get());
} }
EXPECT_FALSE( pac_compact.next(&result) ); EXPECT_FALSE( pac_compact.next(&result) );
} }

View File

@@ -3,74 +3,74 @@
class compatibility { class compatibility {
public: public:
compatibility() : str1("default"), str2("default") { } compatibility() : str1("default"), str2("default") { }
std::string str1; std::string str1;
std::string str2; std::string str2;
MSGPACK_DEFINE(str1, str2); MSGPACK_DEFINE(str1, str2);
}; };
TEST(convert, compatibility_less) TEST(convert, compatibility_less)
{ {
std::vector<std::string> src(1); std::vector<std::string> src(1);
src[0] = "kumofs"; src[0] = "kumofs";
msgpack::zone z; msgpack::zone z;
msgpack::object obj(src, &z); msgpack::object obj(src, &z);
compatibility c; compatibility c;
EXPECT_NO_THROW( obj.convert(&c) ); EXPECT_NO_THROW( obj.convert(&c) );
EXPECT_EQ("kumofs", c.str1); EXPECT_EQ("kumofs", c.str1);
EXPECT_EQ("default", c.str2); EXPECT_EQ("default", c.str2);
} }
TEST(convert, compatibility_more) TEST(convert, compatibility_more)
{ {
std::vector<std::string> src(3); std::vector<std::string> src(3);
src[0] = "kumofs"; src[0] = "kumofs";
src[1] = "mpio"; src[1] = "mpio";
src[2] = "cloudy"; src[2] = "cloudy";
msgpack::zone z; msgpack::zone z;
msgpack::object obj(src, &z); msgpack::object obj(src, &z);
compatibility to; compatibility to;
EXPECT_NO_THROW( obj.convert(&to) ); EXPECT_NO_THROW( obj.convert(&to) );
EXPECT_EQ("kumofs", to.str1); EXPECT_EQ("kumofs", to.str1);
EXPECT_EQ("mpio", to.str2); EXPECT_EQ("mpio", to.str2);
} }
class enum_member { class enum_member {
public: public:
enum_member() : flag(A) { } enum_member() : flag(A) { }
enum flags_t { enum flags_t {
A = 0, A = 0,
B = 1 B = 1
}; };
flags_t flag; flags_t flag;
MSGPACK_DEFINE(flag); MSGPACK_DEFINE(flag);
}; };
MSGPACK_ADD_ENUM(enum_member::flags_t); MSGPACK_ADD_ENUM(enum_member::flags_t);
TEST(convert, enum_member) TEST(convert, enum_member)
{ {
enum_member src; enum_member src;
src.flag = enum_member::B; src.flag = enum_member::B;
msgpack::zone z; msgpack::zone z;
msgpack::object obj(src, &z); msgpack::object obj(src, &z);
enum_member to; enum_member to;
EXPECT_NO_THROW( obj.convert(&to) ); EXPECT_NO_THROW( obj.convert(&to) );
EXPECT_EQ(enum_member::B, to.flag); EXPECT_EQ(enum_member::B, to.flag);
} }

View File

@@ -3,53 +3,53 @@
template <typename T> template <typename T>
void check_size(size_t size) { void check_size(size_t size) {
T v(0); T v(0);
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, v); msgpack::pack(sbuf, v);
EXPECT_EQ(size, sbuf.size()); EXPECT_EQ(size, sbuf.size());
} }
TEST(fixint, size) TEST(fixint, size)
{ {
check_size<msgpack::type::fix_int8>(2); check_size<msgpack::type::fix_int8>(2);
check_size<msgpack::type::fix_int16>(3); check_size<msgpack::type::fix_int16>(3);
check_size<msgpack::type::fix_int32>(5); check_size<msgpack::type::fix_int32>(5);
check_size<msgpack::type::fix_int64>(9); check_size<msgpack::type::fix_int64>(9);
check_size<msgpack::type::fix_uint8>(2); check_size<msgpack::type::fix_uint8>(2);
check_size<msgpack::type::fix_uint16>(3); check_size<msgpack::type::fix_uint16>(3);
check_size<msgpack::type::fix_uint32>(5); check_size<msgpack::type::fix_uint32>(5);
check_size<msgpack::type::fix_uint64>(9); check_size<msgpack::type::fix_uint64>(9);
} }
template <typename T> template <typename T>
void check_convert() { void check_convert() {
T v1(-11); T v1(-11);
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, v1); msgpack::pack(sbuf, v1);
msgpack::unpacked msg; msgpack::unpacked msg;
msgpack::unpack(&msg, sbuf.data(), sbuf.size()); msgpack::unpack(&msg, sbuf.data(), sbuf.size());
T v2; T v2;
msg.get().convert(&v2); msg.get().convert(&v2);
EXPECT_EQ(v1.get(), v2.get()); EXPECT_EQ(v1.get(), v2.get());
EXPECT_EQ(msg.get(), msgpack::object(T(v1.get()))); EXPECT_EQ(msg.get(), msgpack::object(T(v1.get())));
} }
TEST(fixint, convert) TEST(fixint, convert)
{ {
check_convert<msgpack::type::fix_int8>(); check_convert<msgpack::type::fix_int8>();
check_convert<msgpack::type::fix_int16>(); check_convert<msgpack::type::fix_int16>();
check_convert<msgpack::type::fix_int32>(); check_convert<msgpack::type::fix_int32>();
check_convert<msgpack::type::fix_int64>(); check_convert<msgpack::type::fix_int64>();
check_convert<msgpack::type::fix_uint8>(); check_convert<msgpack::type::fix_uint8>();
check_convert<msgpack::type::fix_uint16>(); check_convert<msgpack::type::fix_uint16>();
check_convert<msgpack::type::fix_uint32>(); check_convert<msgpack::type::fix_uint32>();
check_convert<msgpack::type::fix_uint64>(); check_convert<msgpack::type::fix_uint64>();
} }

View File

@@ -3,30 +3,30 @@
TEST(fixint, size) TEST(fixint, size)
{ {
msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
size_t sum = 0; size_t sum = 0;
EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0));
EXPECT_EQ(sum+=2, sbuf->size); EXPECT_EQ(sum+=2, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0));
EXPECT_EQ(sum+=3, sbuf->size); EXPECT_EQ(sum+=3, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0));
EXPECT_EQ(sum+=5, sbuf->size); EXPECT_EQ(sum+=5, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0));
EXPECT_EQ(sum+=9, sbuf->size); EXPECT_EQ(sum+=9, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0));
EXPECT_EQ(sum+=2, sbuf->size); EXPECT_EQ(sum+=2, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0));
EXPECT_EQ(sum+=3, sbuf->size); EXPECT_EQ(sum+=3, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0));
EXPECT_EQ(sum+=5, sbuf->size); EXPECT_EQ(sum+=5, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0)); EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0));
EXPECT_EQ(sum+=9, sbuf->size); EXPECT_EQ(sum+=9, sbuf->size);
msgpack_sbuffer_free(sbuf); msgpack_sbuffer_free(sbuf);
msgpack_packer_free(pk); msgpack_packer_free(pk);
} }

View File

@@ -4,100 +4,100 @@
TEST(msgpack_tuple, member_get) TEST(msgpack_tuple, member_get)
{ {
msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC"); msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
EXPECT_EQ(42, t1.get<0>()); EXPECT_EQ(42, t1.get<0>());
EXPECT_EQ(true, t1.get<1>()); EXPECT_EQ(true, t1.get<1>());
EXPECT_EQ("ABC", t1.get<2>()); EXPECT_EQ("ABC", t1.get<2>());
t1.get<0>() = 40; t1.get<0>() = 40;
t1.get<1>() = false; t1.get<1>() = false;
t1.get<2>() = "DEFG"; t1.get<2>() = "DEFG";
EXPECT_EQ(40, t1.get<0>()); EXPECT_EQ(40, t1.get<0>());
EXPECT_EQ(false, t1.get<1>()); EXPECT_EQ(false, t1.get<1>());
EXPECT_EQ("DEFG", t1.get<2>()); EXPECT_EQ("DEFG", t1.get<2>());
} }
TEST(msgpack_tuple, non_member_get) TEST(msgpack_tuple, non_member_get)
{ {
msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC"); msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
EXPECT_EQ(42, msgpack::type::get<0>(t1)); EXPECT_EQ(42, msgpack::type::get<0>(t1));
EXPECT_EQ(true, msgpack::type::get<1>(t1)); EXPECT_EQ(true, msgpack::type::get<1>(t1));
EXPECT_EQ("ABC", msgpack::type::get<2>(t1)); EXPECT_EQ("ABC", msgpack::type::get<2>(t1));
msgpack::type::get<0>(t1) = 40; msgpack::type::get<0>(t1) = 40;
msgpack::type::get<1>(t1) = false; msgpack::type::get<1>(t1) = false;
msgpack::type::get<2>(t1) = "DEFG"; msgpack::type::get<2>(t1) = "DEFG";
EXPECT_EQ(40, msgpack::type::get<0>(t1)); EXPECT_EQ(40, msgpack::type::get<0>(t1));
EXPECT_EQ(false, msgpack::type::get<1>(t1)); EXPECT_EQ(false, msgpack::type::get<1>(t1));
EXPECT_EQ("DEFG", msgpack::type::get<2>(t1)); EXPECT_EQ("DEFG", msgpack::type::get<2>(t1));
} }
#if __cplusplus >= 201103 #if __cplusplus >= 201103
TEST(msgpack_tuple, std_non_member_get) TEST(msgpack_tuple, std_non_member_get)
{ {
msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC"); msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
EXPECT_EQ(42, std::get<0>(t1)); EXPECT_EQ(42, std::get<0>(t1));
EXPECT_EQ(true, std::get<1>(t1)); EXPECT_EQ(true, std::get<1>(t1));
EXPECT_EQ("ABC", std::get<2>(t1)); EXPECT_EQ("ABC", std::get<2>(t1));
std::get<0>(t1) = 40; std::get<0>(t1) = 40;
std::get<1>(t1) = false; std::get<1>(t1) = false;
std::get<2>(t1) = "DEFG"; std::get<2>(t1) = "DEFG";
EXPECT_EQ(40, std::get<0>(t1)); EXPECT_EQ(40, std::get<0>(t1));
EXPECT_EQ(false, std::get<1>(t1)); EXPECT_EQ(false, std::get<1>(t1));
EXPECT_EQ("DEFG", std::get<2>(t1)); EXPECT_EQ("DEFG", std::get<2>(t1));
} }
TEST(msgpack_tuple, make_tuple) TEST(msgpack_tuple, make_tuple)
{ {
msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::make_tuple(42, true, "ABC"); msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::make_tuple(42, true, "ABC");
EXPECT_EQ(42, t1.get<0>()); EXPECT_EQ(42, t1.get<0>());
EXPECT_EQ(true, t1.get<1>()); EXPECT_EQ(true, t1.get<1>());
EXPECT_EQ("ABC", t1.get<2>()); EXPECT_EQ("ABC", t1.get<2>());
t1.get<0>() = 40; t1.get<0>() = 40;
t1.get<1>() = false; t1.get<1>() = false;
t1.get<2>() = "DEFG"; t1.get<2>() = "DEFG";
EXPECT_EQ(40, t1.get<0>()); EXPECT_EQ(40, t1.get<0>());
EXPECT_EQ(false, t1.get<1>()); EXPECT_EQ(false, t1.get<1>());
EXPECT_EQ("DEFG", t1.get<2>()); EXPECT_EQ("DEFG", t1.get<2>());
} }
TEST(msgpack_tuple, std_make_tuple) TEST(msgpack_tuple, std_make_tuple)
{ {
msgpack::type::tuple<int, bool, std::string> t1 = std::make_tuple(42, true, "ABC"); msgpack::type::tuple<int, bool, std::string> t1 = std::make_tuple(42, true, "ABC");
EXPECT_EQ(42, t1.get<0>()); EXPECT_EQ(42, t1.get<0>());
EXPECT_EQ(true, t1.get<1>()); EXPECT_EQ(true, t1.get<1>());
EXPECT_EQ("ABC", t1.get<2>()); EXPECT_EQ("ABC", t1.get<2>());
} }
TEST(msgpack_tuple, tie) TEST(msgpack_tuple, tie)
{ {
int i(43); int i(43);
bool b(false); bool b(false);
std::string s("DEFG"); std::string s("DEFG");
msgpack::type::tie(i, b, s) = msgpack::type::make_tuple(42, true, "ABC"); msgpack::type::tie(i, b, s) = msgpack::type::make_tuple(42, true, "ABC");
EXPECT_EQ(42, i); EXPECT_EQ(42, i);
EXPECT_EQ(true, b); EXPECT_EQ(true, b);
EXPECT_EQ("ABC", s); EXPECT_EQ("ABC", s);
} }
TEST(msgpack_tuple, tuple_cat) TEST(msgpack_tuple, tuple_cat)
{ {
msgpack::type::tuple<int> t1 = msgpack::type::make_tuple(42); msgpack::type::tuple<int> t1 = msgpack::type::make_tuple(42);
msgpack::type::tuple<bool, std::string> t2 = msgpack::type::make_tuple(true, "ABC"); msgpack::type::tuple<bool, std::string> t2 = msgpack::type::make_tuple(true, "ABC");
msgpack::type::tuple<int, bool, std::string> t3 = msgpack::type::tuple_cat(t1, std::move(t2)); msgpack::type::tuple<int, bool, std::string> t3 = msgpack::type::tuple_cat(t1, std::move(t2));
EXPECT_EQ(42, t3.get<0>()); EXPECT_EQ(42, t3.get<0>());
EXPECT_EQ(true, t3.get<1>()); EXPECT_EQ(true, t3.get<1>());
EXPECT_EQ("ABC", t3.get<2>()); EXPECT_EQ("ABC", t3.get<2>());
} }
TEST(msgpack_tuple, swap) TEST(msgpack_tuple, swap)
{ {
msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::make_tuple(42, true, "ABC"); msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::make_tuple(42, true, "ABC");
msgpack::type::tuple<int, bool, std::string> t2 = msgpack::type::make_tuple(40, false, "DEFG"); msgpack::type::tuple<int, bool, std::string> t2 = msgpack::type::make_tuple(40, false, "DEFG");
msgpack::type::swap(t1, t2); msgpack::type::swap(t1, t2);
EXPECT_EQ(42, t2.get<0>()); EXPECT_EQ(42, t2.get<0>());
EXPECT_EQ(true, t2.get<1>()); EXPECT_EQ(true, t2.get<1>());
EXPECT_EQ("ABC", t2.get<2>()); EXPECT_EQ("ABC", t2.get<2>());
EXPECT_EQ(40, t1.get<0>()); EXPECT_EQ(40, t1.get<0>());
EXPECT_EQ(false, t1.get<1>()); EXPECT_EQ(false, t1.get<1>());
EXPECT_EQ("DEFG", t1.get<2>()); EXPECT_EQ("DEFG", t1.get<2>());
} }
#endif #endif

View File

@@ -80,9 +80,9 @@ TEST(MSGPACKC, simple_buffer_char)
{ {
#if defined(CHAR_MIN) #if defined(CHAR_MIN)
#if CHAR_MIN < 0 #if CHAR_MIN < 0
GEN_TEST_SIGNED(char, char); GEN_TEST_SIGNED(char, char);
#else #else
GEN_TEST_UNSIGNED(char, char); GEN_TEST_UNSIGNED(char, char);
#endif #endif
#else #else
#error CHAR_MIN is not defined #error CHAR_MIN is not defined
@@ -490,7 +490,7 @@ TEST(MSGPACKC, unpack_str16)
{ {
size_t str_size = 7; size_t str_size = 7;
const char buf[] = { const char buf[] = {
(char)0xda, 0, 7, 'f', 'r', 's', 'y', 'u', 'k', 'i' (char)0xda, 0, 7, 'f', 'r', 's', 'y', 'u', 'k', 'i'
}; };
msgpack_zone z; msgpack_zone z;
@@ -510,7 +510,7 @@ TEST(MSGPACKC, unpack_str32)
{ {
size_t str_size = 7; size_t str_size = 7;
const char buf[] = { const char buf[] = {
(char)0xdb, 0, 0, 0, 7, 'f', 'r', 's', 'y', 'u', 'k', 'i' (char)0xdb, 0, 0, 0, 7, 'f', 'r', 's', 'y', 'u', 'k', 'i'
}; };
msgpack_zone z; msgpack_zone z;

View File

@@ -2,133 +2,133 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
struct myclass { struct myclass {
myclass() : num(0), str("default") { } myclass() : num(0), str("default") { }
myclass(int num, const std::string& str) : myclass(int num, const std::string& str) :
num(0), str("default") { } num(0), str("default") { }
~myclass() { } ~myclass() { }
int num; int num;
std::string str; std::string str;
MSGPACK_DEFINE(num, str); MSGPACK_DEFINE(num, str);
bool operator==(const myclass& o) const bool operator==(const myclass& o) const
{ {
return num == o.num && str == o.str; return num == o.num && str == o.str;
} }
}; };
std::ostream& operator<<(std::ostream& o, const myclass& m) std::ostream& operator<<(std::ostream& o, const myclass& m)
{ {
return o << "myclass("<<m.num<<",\""<<m.str<<"\")"; return o << "myclass("<<m.num<<",\""<<m.str<<"\")";
} }
TEST(object, convert) TEST(object, convert)
{ {
myclass m1; myclass m1;
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, m1); msgpack::pack(sbuf, m1);
msgpack::zone z; msgpack::zone z;
msgpack::object obj; msgpack::object obj;
msgpack::unpack_return ret = msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj); msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2; myclass m2;
obj.convert(&m2); obj.convert(&m2);
EXPECT_EQ(m1, m2); EXPECT_EQ(m1, m2);
} }
TEST(object, as) TEST(object, as)
{ {
myclass m1; myclass m1;
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, m1); msgpack::pack(sbuf, m1);
msgpack::zone z; msgpack::zone z;
msgpack::object obj; msgpack::object obj;
msgpack::unpack_return ret = msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj); msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(m1, obj.as<myclass>()); EXPECT_EQ(m1, obj.as<myclass>());
} }
TEST(object, print) TEST(object, print)
{ {
msgpack::object obj; msgpack::object obj;
std::cout << obj << std::endl; std::cout << obj << std::endl;
} }
TEST(object, is_nil) TEST(object, is_nil)
{ {
msgpack::object obj; msgpack::object obj;
EXPECT_TRUE(obj.is_nil()); EXPECT_TRUE(obj.is_nil());
} }
TEST(object, type_error) TEST(object, type_error)
{ {
msgpack::object obj(1); msgpack::object obj(1);
EXPECT_THROW(obj.as<std::string>(), msgpack::type_error); EXPECT_THROW(obj.as<std::string>(), msgpack::type_error);
EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error); EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error);
EXPECT_EQ(1, obj.as<int>()); EXPECT_EQ(1, obj.as<int>());
EXPECT_EQ(1, obj.as<short>()); EXPECT_EQ(1, obj.as<short>());
EXPECT_EQ(1u, obj.as<unsigned int>()); EXPECT_EQ(1u, obj.as<unsigned int>());
EXPECT_EQ(1u, obj.as<unsigned long>()); EXPECT_EQ(1u, obj.as<unsigned long>());
} }
TEST(object, equal_primitive) TEST(object, equal_primitive)
{ {
msgpack::object obj_nil; msgpack::object obj_nil;
EXPECT_EQ(obj_nil, msgpack::object()); EXPECT_EQ(obj_nil, msgpack::object());
msgpack::object obj_int(1); msgpack::object obj_int(1);
EXPECT_EQ(obj_int, msgpack::object(1)); EXPECT_EQ(obj_int, msgpack::object(1));
EXPECT_EQ(obj_int, 1); EXPECT_EQ(obj_int, 1);
msgpack::object obj_double(1.2); msgpack::object obj_double(1.2);
EXPECT_EQ(obj_double, msgpack::object(1.2)); EXPECT_EQ(obj_double, msgpack::object(1.2));
EXPECT_EQ(obj_double, 1.2); EXPECT_EQ(obj_double, 1.2);
msgpack::object obj_bool(true); msgpack::object obj_bool(true);
EXPECT_EQ(obj_bool, msgpack::object(true)); EXPECT_EQ(obj_bool, msgpack::object(true));
EXPECT_EQ(obj_bool, true); EXPECT_EQ(obj_bool, true);
} }
TEST(object, construct_primitive) TEST(object, construct_primitive)
{ {
msgpack::object obj_nil; msgpack::object obj_nil;
EXPECT_EQ(msgpack::type::NIL, obj_nil.type); EXPECT_EQ(msgpack::type::NIL, obj_nil.type);
msgpack::object obj_uint(1); msgpack::object obj_uint(1);
EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type); EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type);
EXPECT_EQ(1u, obj_uint.via.u64); EXPECT_EQ(1u, obj_uint.via.u64);
msgpack::object obj_int(-1); msgpack::object obj_int(-1);
EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type); EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type);
EXPECT_EQ(-1, obj_int.via.i64); EXPECT_EQ(-1, obj_int.via.i64);
msgpack::object obj_double(1.2); msgpack::object obj_double(1.2);
EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type); EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type);
EXPECT_EQ(1.2, obj_double.via.dec); EXPECT_EQ(1.2, obj_double.via.dec);
msgpack::object obj_bool(true); msgpack::object obj_bool(true);
EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type); EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type);
EXPECT_EQ(true, obj_bool.via.boolean); EXPECT_EQ(true, obj_bool.via.boolean);
} }

View File

@@ -4,120 +4,120 @@
TEST(pack, num) TEST(pack, num)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1); msgpack::pack(sbuf, 1);
} }
TEST(pack, vector) TEST(pack, vector)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
std::vector<int> vec; std::vector<int> vec;
vec.push_back(1); vec.push_back(1);
vec.push_back(2); vec.push_back(2);
vec.push_back(3); vec.push_back(3);
msgpack::pack(sbuf, vec); msgpack::pack(sbuf, vec);
} }
TEST(pack, to_ostream) TEST(pack, to_ostream)
{ {
std::ostringstream stream; std::ostringstream stream;
msgpack::pack(stream, 1); msgpack::pack(stream, 1);
} }
struct myclass { struct myclass {
myclass() : num(0), str("default") { } myclass() : num(0), str("default") { }
myclass(int num, const std::string& str) : myclass(int num, const std::string& str) :
num(num), str(str) { } num(num), str(str) { }
~myclass() { } ~myclass() { }
int num; int num;
std::string str; std::string str;
MSGPACK_DEFINE(num, str); MSGPACK_DEFINE(num, str);
}; };
TEST(pack, myclass) TEST(pack, myclass)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
myclass m(1, "msgpack"); myclass m(1, "msgpack");
msgpack::pack(sbuf, m); msgpack::pack(sbuf, m);
} }
TEST(unpack, myclass) TEST(unpack, myclass)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
myclass m1(1, "phraser"); myclass m1(1, "phraser");
msgpack::pack(sbuf, m1); msgpack::pack(sbuf, m1);
msgpack::zone z; msgpack::zone z;
msgpack::object obj; msgpack::object obj;
msgpack::unpack_return ret = msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj); msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2 = obj.as<myclass>(); myclass m2 = obj.as<myclass>();
EXPECT_EQ(m1.num, m2.num); EXPECT_EQ(m1.num, m2.num);
EXPECT_EQ(m1.str, m2.str); EXPECT_EQ(m1.str, m2.str);
} }
TEST(unpack, sequence) TEST(unpack, sequence)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1); msgpack::pack(sbuf, 1);
msgpack::pack(sbuf, 2); msgpack::pack(sbuf, 2);
msgpack::pack(sbuf, 3); msgpack::pack(sbuf, 3);
size_t offset = 0; size_t offset = 0;
msgpack::unpacked msg; msgpack::unpacked msg;
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
EXPECT_EQ(1, msg.get().as<int>()); EXPECT_EQ(1, msg.get().as<int>());
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
EXPECT_EQ(2, msg.get().as<int>()); EXPECT_EQ(2, msg.get().as<int>());
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
EXPECT_EQ(3, msg.get().as<int>()); EXPECT_EQ(3, msg.get().as<int>());
} }
TEST(unpack, sequence_compat) TEST(unpack, sequence_compat)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1); msgpack::pack(sbuf, 1);
msgpack::pack(sbuf, 2); msgpack::pack(sbuf, 2);
msgpack::pack(sbuf, 3); msgpack::pack(sbuf, 3);
size_t offset = 0; size_t offset = 0;
msgpack::zone z; msgpack::zone z;
msgpack::object obj; msgpack::object obj;
msgpack::unpack_return ret; msgpack::unpack_return ret;
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, z, obj); ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, z, obj);
EXPECT_TRUE(ret >= 0); EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
EXPECT_EQ(1, obj.as<int>()); EXPECT_EQ(1, obj.as<int>());
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, z, obj); ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, z, obj);
EXPECT_TRUE(ret >= 0); EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
EXPECT_EQ(2, obj.as<int>()); EXPECT_EQ(2, obj.as<int>());
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, z, obj); ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, z, obj);
EXPECT_TRUE(ret >= 0); EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(3, obj.as<int>()); EXPECT_EQ(3, obj.as<int>());
} }

View File

@@ -4,67 +4,67 @@
TEST(pack, num) TEST(pack, num)
{ {
msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_int(pk, 1)); EXPECT_EQ(0, msgpack_pack_int(pk, 1));
msgpack_sbuffer_free(sbuf); msgpack_sbuffer_free(sbuf);
msgpack_packer_free(pk); msgpack_packer_free(pk);
} }
TEST(pack, array) TEST(pack, array)
{ {
msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_array(pk, 3)); EXPECT_EQ(0, msgpack_pack_array(pk, 3));
EXPECT_EQ(0, msgpack_pack_int(pk, 1)); EXPECT_EQ(0, msgpack_pack_int(pk, 1));
EXPECT_EQ(0, msgpack_pack_int(pk, 2)); EXPECT_EQ(0, msgpack_pack_int(pk, 2));
EXPECT_EQ(0, msgpack_pack_int(pk, 3)); EXPECT_EQ(0, msgpack_pack_int(pk, 3));
msgpack_sbuffer_free(sbuf); msgpack_sbuffer_free(sbuf);
msgpack_packer_free(pk); msgpack_packer_free(pk);
} }
TEST(unpack, sequence) TEST(unpack, sequence)
{ {
msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_int(pk, 1)); EXPECT_EQ(0, msgpack_pack_int(pk, 1));
EXPECT_EQ(0, msgpack_pack_int(pk, 2)); EXPECT_EQ(0, msgpack_pack_int(pk, 2));
EXPECT_EQ(0, msgpack_pack_int(pk, 3)); EXPECT_EQ(0, msgpack_pack_int(pk, 3));
msgpack_packer_free(pk); msgpack_packer_free(pk);
bool success; bool success;
size_t offset = 0; size_t offset = 0;
msgpack_unpacked msg; msgpack_unpacked msg;
msgpack_unpacked_init(&msg); msgpack_unpacked_init(&msg);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_TRUE(success); EXPECT_TRUE(success);
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
EXPECT_EQ(1, msg.data.via.u64); EXPECT_EQ(1, msg.data.via.u64);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_TRUE(success); EXPECT_TRUE(success);
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
EXPECT_EQ(2, msg.data.via.u64); EXPECT_EQ(2, msg.data.via.u64);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_TRUE(success); EXPECT_TRUE(success);
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
EXPECT_EQ(3, msg.data.via.u64); EXPECT_EQ(3, msg.data.via.u64);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_FALSE(success); EXPECT_FALSE(success);
msgpack_sbuffer_free(sbuf); msgpack_sbuffer_free(sbuf);
msgpack_unpacked_destroy(&msg); msgpack_unpacked_destroy(&msg);
} }

View File

@@ -4,217 +4,217 @@
TEST(streaming, basic) TEST(streaming, basic)
{ {
msgpack::sbuffer buffer; msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer); msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack(1); pk.pack(1);
pk.pack(2); pk.pack(2);
pk.pack(3); pk.pack(3);
const char* input = buffer.data(); const char* input = buffer.data();
const char* const eof = input + buffer.size(); const char* const eof = input + buffer.size();
msgpack::unpacker pac; msgpack::unpacker pac;
msgpack::unpacked result; msgpack::unpacked result;
int count = 0; int count = 0;
while(count < 3) { while(count < 3) {
pac.reserve_buffer(32*1024); pac.reserve_buffer(32*1024);
// read buffer into pac.buffer() upto // read buffer into pac.buffer() upto
// pac.buffer_capacity() bytes. // pac.buffer_capacity() bytes.
size_t len = 1; size_t len = 1;
memcpy(pac.buffer(), input, len); memcpy(pac.buffer(), input, len);
input += len; input += len;
pac.buffer_consumed(len); pac.buffer_consumed(len);
while(pac.next(&result)) { while(pac.next(&result)) {
msgpack::object obj = result.get(); msgpack::object obj = result.get();
switch(count++) { switch(count++) {
case 0: case 0:
EXPECT_EQ(1, obj.as<int>()); EXPECT_EQ(1, obj.as<int>());
break; break;
case 1: case 1:
EXPECT_EQ(2, obj.as<int>()); EXPECT_EQ(2, obj.as<int>());
break; break;
case 2: case 2:
EXPECT_EQ(3, obj.as<int>()); EXPECT_EQ(3, obj.as<int>());
return; return;
} }
} }
EXPECT_TRUE(input < eof); EXPECT_TRUE(input < eof);
} }
} }
class event_handler { class event_handler {
public: public:
event_handler(std::istream& input) : input(input) { } event_handler(std::istream& input) : input(input) { }
~event_handler() { } ~event_handler() { }
void on_read() void on_read()
{ {
while(true) { while(true) {
pac.reserve_buffer(32*1024); pac.reserve_buffer(32*1024);
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
if(len == 0) { if(len == 0) {
return; return;
} }
pac.buffer_consumed(len); pac.buffer_consumed(len);
msgpack::unpacked result; msgpack::unpacked result;
while(pac.next(&result)) { while(pac.next(&result)) {
on_message(result.get(), msgpack::move(result.zone())); on_message(result.get(), msgpack::move(result.zone()));
} }
if(pac.message_size() > 10*1024*1024) { if(pac.message_size() > 10*1024*1024) {
throw std::runtime_error("message is too large"); throw std::runtime_error("message is too large");
} }
} }
} }
void on_message(msgpack::object obj, msgpack::unique_ptr<msgpack::zone> z) void on_message(msgpack::object obj, msgpack::unique_ptr<msgpack::zone> z)
{ {
EXPECT_EQ(expect, obj.as<int>()); EXPECT_EQ(expect, obj.as<int>());
} }
int expect; int expect;
private: private:
std::istream& input; std::istream& input;
msgpack::unpacker pac; msgpack::unpacker pac;
}; };
TEST(streaming, event) TEST(streaming, event)
{ {
std::stringstream stream; std::stringstream stream;
msgpack::packer<std::ostream> pk(&stream); msgpack::packer<std::ostream> pk(&stream);
event_handler handler(stream); event_handler handler(stream);
pk.pack(1); pk.pack(1);
handler.expect = 1; handler.expect = 1;
handler.on_read(); handler.on_read();
pk.pack(2); pk.pack(2);
handler.expect = 2; handler.expect = 2;
handler.on_read(); handler.on_read();
pk.pack(3); pk.pack(3);
handler.expect = 3; handler.expect = 3;
handler.on_read(); handler.on_read();
} }
// backward compatibility // backward compatibility
TEST(streaming, basic_compat) TEST(streaming, basic_compat)
{ {
std::ostringstream stream; std::ostringstream stream;
msgpack::packer<std::ostream> pk(&stream); msgpack::packer<std::ostream> pk(&stream);
pk.pack(1); pk.pack(1);
pk.pack(2); pk.pack(2);
pk.pack(3); pk.pack(3);
std::istringstream input(stream.str()); std::istringstream input(stream.str());
msgpack::unpacker pac; msgpack::unpacker pac;
int count = 0; int count = 0;
while(count < 3) { while(count < 3) {
pac.reserve_buffer(32*1024); pac.reserve_buffer(32*1024);
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
pac.buffer_consumed(len); pac.buffer_consumed(len);
while(pac.execute()) { while(pac.execute()) {
msgpack::unique_ptr<msgpack::zone> z(pac.release_zone()); msgpack::unique_ptr<msgpack::zone> z(pac.release_zone());
msgpack::object obj = pac.data(); msgpack::object obj = pac.data();
pac.reset(); pac.reset();
switch(count++) { switch(count++) {
case 0: case 0:
EXPECT_EQ(1, obj.as<int>()); EXPECT_EQ(1, obj.as<int>());
break; break;
case 1: case 1:
EXPECT_EQ(2, obj.as<int>()); EXPECT_EQ(2, obj.as<int>());
break; break;
case 2: case 2:
EXPECT_EQ(3, obj.as<int>()); EXPECT_EQ(3, obj.as<int>());
return; return;
} }
} }
} }
} }
// backward compatibility // backward compatibility
class event_handler_compat { class event_handler_compat {
public: public:
event_handler_compat(std::istream& input) : input(input) { } event_handler_compat(std::istream& input) : input(input) { }
~event_handler_compat() { } ~event_handler_compat() { }
void on_read() void on_read()
{ {
while(true) { while(true) {
pac.reserve_buffer(32*1024); pac.reserve_buffer(32*1024);
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
if(len == 0) { if(len == 0) {
return; return;
} }
pac.buffer_consumed(len); pac.buffer_consumed(len);
while(pac.execute()) { while(pac.execute()) {
msgpack::unique_ptr<msgpack::zone> z(pac.release_zone()); msgpack::unique_ptr<msgpack::zone> z(pac.release_zone());
msgpack::object obj = pac.data(); msgpack::object obj = pac.data();
pac.reset(); pac.reset();
on_message(obj, msgpack::move(z)); on_message(obj, msgpack::move(z));
} }
if(pac.message_size() > 10*1024*1024) { if(pac.message_size() > 10*1024*1024) {
throw std::runtime_error("message is too large"); throw std::runtime_error("message is too large");
} }
} }
} }
void on_message(msgpack::object obj, msgpack::unique_ptr<msgpack::zone> z) void on_message(msgpack::object obj, msgpack::unique_ptr<msgpack::zone> z)
{ {
EXPECT_EQ(expect, obj.as<int>()); EXPECT_EQ(expect, obj.as<int>());
} }
int expect; int expect;
private: private:
std::istream& input; std::istream& input;
msgpack::unpacker pac; msgpack::unpacker pac;
}; };
TEST(streaming, event_compat) TEST(streaming, event_compat)
{ {
std::stringstream stream; std::stringstream stream;
msgpack::packer<std::ostream> pk(&stream); msgpack::packer<std::ostream> pk(&stream);
event_handler_compat handler(stream); event_handler_compat handler(stream);
pk.pack(1); pk.pack(1);
handler.expect = 1; handler.expect = 1;
handler.on_read(); handler.on_read();
pk.pack(2); pk.pack(2);
handler.expect = 2; handler.expect = 2;
handler.on_read(); handler.on_read();
pk.pack(3); pk.pack(3);
handler.expect = 3; handler.expect = 3;
handler.on_read(); handler.on_read();
} }

View File

@@ -4,111 +4,111 @@
TEST(streaming, basic) TEST(streaming, basic)
{ {
msgpack_sbuffer* buffer = msgpack_sbuffer_new(); msgpack_sbuffer* buffer = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write); msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
// 1, 2, 3, "str", ["str_data"], "bin", ["bin_data"], {0.3: 0.4} // 1, 2, 3, "str", ["str_data"], "bin", ["bin_data"], {0.3: 0.4}
EXPECT_EQ(0, msgpack_pack_int(pk, 1)); EXPECT_EQ(0, msgpack_pack_int(pk, 1));
EXPECT_EQ(0, msgpack_pack_int(pk, 2)); EXPECT_EQ(0, msgpack_pack_int(pk, 2));
EXPECT_EQ(0, msgpack_pack_int(pk, 3)); EXPECT_EQ(0, msgpack_pack_int(pk, 3));
EXPECT_EQ(0, msgpack_pack_str(pk, 3)); EXPECT_EQ(0, msgpack_pack_str(pk, 3));
EXPECT_EQ(0, msgpack_pack_str_body(pk, "str", 3)); EXPECT_EQ(0, msgpack_pack_str_body(pk, "str", 3));
EXPECT_EQ(0, msgpack_pack_array(pk, 1)); EXPECT_EQ(0, msgpack_pack_array(pk, 1));
EXPECT_EQ(0, msgpack_pack_str(pk, 8)); EXPECT_EQ(0, msgpack_pack_str(pk, 8));
EXPECT_EQ(0, msgpack_pack_str_body(pk, "str_data", 8)); EXPECT_EQ(0, msgpack_pack_str_body(pk, "str_data", 8));
EXPECT_EQ(0, msgpack_pack_bin(pk, 3)); EXPECT_EQ(0, msgpack_pack_bin(pk, 3));
EXPECT_EQ(0, msgpack_pack_bin_body(pk, "bin", 3)); EXPECT_EQ(0, msgpack_pack_bin_body(pk, "bin", 3));
EXPECT_EQ(0, msgpack_pack_array(pk, 1)); EXPECT_EQ(0, msgpack_pack_array(pk, 1));
EXPECT_EQ(0, msgpack_pack_bin(pk, 8)); EXPECT_EQ(0, msgpack_pack_bin(pk, 8));
EXPECT_EQ(0, msgpack_pack_bin_body(pk, "bin_data", 8)); EXPECT_EQ(0, msgpack_pack_bin_body(pk, "bin_data", 8));
EXPECT_EQ(0, msgpack_pack_map(pk, 1)); EXPECT_EQ(0, msgpack_pack_map(pk, 1));
EXPECT_EQ(0, msgpack_pack_float(pk, 0.4)); EXPECT_EQ(0, msgpack_pack_float(pk, 0.4));
EXPECT_EQ(0, msgpack_pack_double(pk, 0.8)); EXPECT_EQ(0, msgpack_pack_double(pk, 0.8));
int max_count = 6; int max_count = 6;
msgpack_packer_free(pk); msgpack_packer_free(pk);
const char* input = buffer->data; const char* input = buffer->data;
const char* const eof = input + buffer->size; const char* const eof = input + buffer->size;
msgpack_unpacker pac; msgpack_unpacker pac;
msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE); msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
msgpack_unpacked result; msgpack_unpacked result;
msgpack_unpacked_init(&result); msgpack_unpacked_init(&result);
int count = 0; int count = 0;
while(count < max_count) { while(count < max_count) {
bool unpacked = false; bool unpacked = false;
msgpack_unpacker_reserve_buffer(&pac, 32*1024); msgpack_unpacker_reserve_buffer(&pac, 32*1024);
while(!unpacked) { while(!unpacked) {
/* read buffer into msgpack_unapcker_buffer(&pac) upto /* read buffer into msgpack_unapcker_buffer(&pac) upto
* msgpack_unpacker_buffer_capacity(&pac) bytes. */ * msgpack_unpacker_buffer_capacity(&pac) bytes. */
memcpy(msgpack_unpacker_buffer(&pac), input, 1); memcpy(msgpack_unpacker_buffer(&pac), input, 1);
input += 1; input += 1;
EXPECT_TRUE(input <= eof); EXPECT_TRUE(input <= eof);
msgpack_unpacker_buffer_consumed(&pac, 1); msgpack_unpacker_buffer_consumed(&pac, 1);
while(msgpack_unpacker_next(&pac, &result)) { while(msgpack_unpacker_next(&pac, &result)) {
unpacked = 1; unpacked = 1;
msgpack_object obj = result.data; msgpack_object obj = result.data;
msgpack_object e; msgpack_object e;
switch(count++) { switch(count++) {
case 0: case 0:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
EXPECT_EQ(1, obj.via.u64); EXPECT_EQ(1, obj.via.u64);
break; break;
case 1: case 1:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
EXPECT_EQ(2, obj.via.u64); EXPECT_EQ(2, obj.via.u64);
break; break;
case 2: case 2:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
EXPECT_EQ(3, obj.via.u64); EXPECT_EQ(3, obj.via.u64);
break; break;
case 3: case 3:
EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type);
EXPECT_EQ(std::string("str",3), std::string(obj.via.str.ptr, obj.via.str.size)); EXPECT_EQ(std::string("str",3), std::string(obj.via.str.ptr, obj.via.str.size));
break; break;
case 4: case 4:
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type); EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
EXPECT_EQ(1, obj.via.array.size); EXPECT_EQ(1, obj.via.array.size);
e = obj.via.array.ptr[0]; e = obj.via.array.ptr[0];
EXPECT_EQ(MSGPACK_OBJECT_STR, e.type); EXPECT_EQ(MSGPACK_OBJECT_STR, e.type);
EXPECT_EQ(std::string("str_data",8), std::string(e.via.str.ptr, e.via.str.size)); EXPECT_EQ(std::string("str_data",8), std::string(e.via.str.ptr, e.via.str.size));
break; break;
case 5: case 5:
EXPECT_EQ(MSGPACK_OBJECT_BIN, obj.type); EXPECT_EQ(MSGPACK_OBJECT_BIN, obj.type);
EXPECT_EQ(std::string("bin",3), std::string(obj.via.bin.ptr, obj.via.bin.size)); EXPECT_EQ(std::string("bin",3), std::string(obj.via.bin.ptr, obj.via.bin.size));
break; break;
case 6: case 6:
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type); EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
EXPECT_EQ(1, obj.via.array.size); EXPECT_EQ(1, obj.via.array.size);
e = obj.via.array.ptr[0]; e = obj.via.array.ptr[0];
EXPECT_EQ(MSGPACK_OBJECT_BIN, e.type); EXPECT_EQ(MSGPACK_OBJECT_BIN, e.type);
EXPECT_EQ(std::string("bin_data",8), std::string(e.via.bin.ptr, e.via.bin.size)); EXPECT_EQ(std::string("bin_data",8), std::string(e.via.bin.ptr, e.via.bin.size));
break; break;
case 7: case 7:
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type); EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
EXPECT_EQ(1, obj.via.map.size); EXPECT_EQ(1, obj.via.map.size);
e = obj.via.map.ptr[0].key; e = obj.via.map.ptr[0].key;
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type); EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type);
ASSERT_FLOAT_EQ(0.4, (float)e.via.dec); ASSERT_FLOAT_EQ(0.4, (float)e.via.dec);
e = obj.via.map.ptr[0].val; e = obj.via.map.ptr[0].val;
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type); EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type);
ASSERT_DOUBLE_EQ(0.8, e.via.dec); ASSERT_DOUBLE_EQ(0.8, e.via.dec);
break; break;
} }
} }
} }
} }
msgpack_unpacker_destroy(&pac); msgpack_unpacker_destroy(&pac);
msgpack_unpacked_destroy(&result); msgpack_unpacked_destroy(&result);
} }

View File

@@ -3,11 +3,11 @@
TEST(version, print) TEST(version, print)
{ {
printf("MSGPACK_VERSION : %s\n", MSGPACK_VERSION); printf("MSGPACK_VERSION : %s\n", MSGPACK_VERSION);
printf("MSGPACK_VERSION_MAJOR : %d\n", MSGPACK_VERSION_MAJOR); printf("MSGPACK_VERSION_MAJOR : %d\n", MSGPACK_VERSION_MAJOR);
printf("MSGPACK_VERSION_MINOR : %d\n", MSGPACK_VERSION_MINOR); printf("MSGPACK_VERSION_MINOR : %d\n", MSGPACK_VERSION_MINOR);
printf("msgpack_version() : %s\n", msgpack_version()); printf("msgpack_version() : %s\n", msgpack_version());
printf("msgpack_version_major() : %d\n", msgpack_version_major()); printf("msgpack_version_major() : %d\n", msgpack_version_major());
printf("msgpack_version_minor() : %d\n", msgpack_version_minor()); printf("msgpack_version_minor() : %d\n", msgpack_version_minor());
} }

View File

@@ -3,76 +3,76 @@
TEST(zone, allocate_align) TEST(zone, allocate_align)
{ {
msgpack::zone z; msgpack::zone z;
char* buf1 = (char*)z.allocate_align(4); char* buf1 = (char*)z.allocate_align(4);
memcpy(buf1, "test", 4); memcpy(buf1, "test", 4);
char* buf2 = (char*)z.allocate_align(4); char* buf2 = (char*)z.allocate_align(4);
memcpy(buf2, "test", 4); memcpy(buf2, "test", 4);
} }
class myclass { class myclass {
public: public:
myclass() : num(0), str("default") { } myclass() : num(0), str("default") { }
myclass(int num, const std::string& str) : myclass(int num, const std::string& str) :
num(num), str(str) { } num(num), str(str) { }
~myclass() { } ~myclass() { }
int num; int num;
std::string str; std::string str;
private: private:
myclass(const myclass&); myclass(const myclass&);
}; };
TEST(zone, allocate) TEST(zone, allocate)
{ {
msgpack::zone z; msgpack::zone z;
myclass* m = z.allocate<myclass>(); myclass* m = z.allocate<myclass>();
EXPECT_EQ(m->num, 0); EXPECT_EQ(m->num, 0);
EXPECT_EQ(m->str, "default"); EXPECT_EQ(m->str, "default");
} }
TEST(zone, allocate_constructor) TEST(zone, allocate_constructor)
{ {
msgpack::zone z; msgpack::zone z;
myclass* m = z.allocate<myclass>(7, "msgpack"); myclass* m = z.allocate<myclass>(7, "msgpack");
EXPECT_EQ(m->num, 7); EXPECT_EQ(m->num, 7);
EXPECT_EQ(m->str, "msgpack"); EXPECT_EQ(m->str, "msgpack");
} }
static void custom_finalizer_func(void* user) static void custom_finalizer_func(void* user)
{ {
myclass* m = (myclass*)user; myclass* m = (myclass*)user;
delete m; delete m;
} }
TEST(zone, push_finalizer) TEST(zone, push_finalizer)
{ {
msgpack::zone z; msgpack::zone z;
myclass* m = new myclass(); myclass* m = new myclass();
z.push_finalizer(custom_finalizer_func, (void*)m); z.push_finalizer(custom_finalizer_func, (void*)m);
} }
TEST(zone, push_finalizer_unique_ptr) TEST(zone, push_finalizer_unique_ptr)
{ {
msgpack::zone z; msgpack::zone z;
msgpack::unique_ptr<myclass> am(new myclass()); msgpack::unique_ptr<myclass> am(new myclass());
z.push_finalizer(msgpack::move(am)); z.push_finalizer(msgpack::move(am));
} }
TEST(zone, allocate_no_align) TEST(zone, allocate_no_align)
{ {
msgpack::zone z; msgpack::zone z;
char* buf1 = (char*)z.allocate_no_align(4); char* buf1 = (char*)z.allocate_no_align(4);
char* buf2 = (char*)z.allocate_no_align(4); char* buf2 = (char*)z.allocate_no_align(4);
EXPECT_EQ(buf1+4, buf2); EXPECT_EQ(buf1+4, buf2);
} }