mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-19 13:02:13 +01:00

git-svn-id: file:///Users/frsyuki/project/msgpack-git/svn/x@58 5a5092ae-2292-43ba-b2d5-dcab9c1a2731
164 lines
4.2 KiB
Plaintext
164 lines
4.2 KiB
Plaintext
#ifndef MSGPACK_ZONE_HPP__
|
|
#define MSGPACK_ZONE_HPP__
|
|
#include <iostream>
|
|
|
|
#include "msgpack/object.hpp"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdexcept>
|
|
|
|
#ifndef MSGPACK_ZONE_CHUNK_SIZE
|
|
#define MSGPACK_ZONE_CHUNK_SIZE 8*1024
|
|
#endif
|
|
|
|
namespace msgpack {
|
|
|
|
|
|
static const size_t ZONE_CHUNK_SIZE = MSGPACK_ZONE_CHUNK_SIZE;
|
|
|
|
|
|
class zone {
|
|
public:
|
|
zone() : m_used(0) { }
|
|
~zone() { clear(); }
|
|
|
|
public:
|
|
template <typename T>
|
|
void push_finalizer(void (*func)(void* obj, void* user), T* obj, void* user);
|
|
|
|
public:
|
|
object_nil* nnil() { return new (alloc()) object_nil(); }
|
|
object_true* ntrue() { return new (alloc()) object_true(); }
|
|
object_false* nfalse() { return new (alloc()) object_false(); }
|
|
object_u8* nu8( uint8_t v) { return new (alloc()) object_u8(v); }
|
|
object_u16* nu16(uint16_t v) { return new (alloc()) object_u16(v); }
|
|
object_u32* nu32(uint32_t v) { return new (alloc()) object_u32(v); }
|
|
object_u64* nu64(uint64_t v) { return new (alloc()) object_u64(v); }
|
|
object_i8* ni8( int8_t v) { return new (alloc()) object_i8(v); }
|
|
object_i16* ni16( int16_t v) { return new (alloc()) object_i16(v); }
|
|
object_i32* ni32( int32_t v) { return new (alloc()) object_i32(v); }
|
|
object_i64* ni64( int64_t v) { return new (alloc()) object_i64(v); }
|
|
object_float* nfloat( float v) { return new (alloc()) object_float(v); }
|
|
object_double* ndouble( double v) { return new (alloc()) object_double(v); }
|
|
|
|
object_raw_ref* nraw_ref(void* ptr, uint32_t len)
|
|
{ return new (alloc()) object_raw_ref(ptr, len); }
|
|
|
|
object_const_raw_ref* nraw_ref(const void* ptr, uint32_t len)
|
|
{ return new (alloc()) object_const_raw_ref(ptr, len); }
|
|
|
|
object_raw_ref* nraw_copy(const void* ptr, uint32_t len)
|
|
{
|
|
void* copy = malloc(len);
|
|
if(!copy) { throw std::bad_alloc(); }
|
|
object_raw_ref* o;
|
|
try {
|
|
o = new (alloc()) object_raw_ref(copy, len);
|
|
push_finalizer<void>(&zone::finalize_free, NULL, copy);
|
|
} catch (...) {
|
|
free(copy);
|
|
throw;
|
|
}
|
|
memcpy(copy, ptr, len);
|
|
return o;
|
|
}
|
|
|
|
object_array* narray()
|
|
{ return new (alloc()) object_array(); }
|
|
|
|
object_array* narray(size_t reserve_size)
|
|
{ return new (alloc()) object_array(reserve_size); }
|
|
|
|
object_map* nmap()
|
|
{ return new (alloc()) object_map(); }
|
|
|
|
<% GENERATION_SIZE = 16 %>
|
|
<% 1.upto(GENERATION_SIZE) {|i| %>
|
|
object_array* narray(<% 1.upto(i-1) {|n| %>object o<%=n%>, <% } %>object o<%=i%>)
|
|
{ object_array* a = new (alloc()) object_array(<%=i%>);
|
|
<% 1.upto(i) {|n| %>a->push_back(o<%=n%>);
|
|
<% } %>return a; }
|
|
<% } %>
|
|
|
|
<% 1.upto(GENERATION_SIZE) {|i| %>
|
|
object_map* nmap(<% 1.upto(i-1) {|n| %>object k<%=n%>, object v<%=n%>, <% } %>object k<%=i%>, object v<%=i%>)
|
|
{ object_map* m = new (alloc()) object_map();
|
|
<% 1.upto(i) {|n| %>m->store(k<%=n%>, v<%=n%>);
|
|
<% } %>return m; }
|
|
<% } %>
|
|
|
|
public:
|
|
void clear();
|
|
bool empty() const;
|
|
|
|
private:
|
|
void* alloc();
|
|
|
|
private:
|
|
size_t m_used;
|
|
|
|
static const size_t MAX_OBJECT_SIZE =
|
|
sizeof(object_raw_ref) > sizeof(object_array)
|
|
? ( sizeof(object_raw_ref) > sizeof(object_map)
|
|
? sizeof(object_raw_ref)
|
|
: sizeof(object_map)
|
|
)
|
|
: ( sizeof(object_array) > sizeof(object_map)
|
|
? sizeof(object_array)
|
|
: sizeof(object_map)
|
|
)
|
|
;
|
|
|
|
struct cell_t {
|
|
char data[MAX_OBJECT_SIZE];
|
|
};
|
|
|
|
typedef std::vector<cell_t*> pool_t;
|
|
pool_t m_pool;
|
|
|
|
|
|
class finalizer {
|
|
public:
|
|
finalizer(void (*func)(void*, void*), void* obj, void* user) :
|
|
m_obj(obj), m_user(user), m_func(func) {}
|
|
void call() { (*m_func)(m_obj, m_user); }
|
|
private:
|
|
void* m_obj;
|
|
void* m_user;
|
|
void (*m_func)(void*, void*);
|
|
};
|
|
|
|
typedef std::vector<finalizer> user_finalizer_t;
|
|
user_finalizer_t m_user_finalizer;
|
|
|
|
private:
|
|
void resize_pool(size_t n);
|
|
|
|
public:
|
|
static void finalize_free(void* obj, void* user)
|
|
{ free(user); }
|
|
|
|
private:
|
|
zone(const zone&);
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
inline void zone::push_finalizer(void (*func)(void* obj, void* user), T* obj, void* user)
|
|
{
|
|
m_user_finalizer.push_back( finalizer(
|
|
func, reinterpret_cast<void*>(obj),
|
|
user) );
|
|
}
|
|
|
|
inline bool zone::empty() const
|
|
{
|
|
return m_used == 0 && m_user_finalizer.empty();
|
|
}
|
|
|
|
|
|
} // namespace msgpack
|
|
|
|
#endif /* msgpack/zone.hpp */
|
|
|