From 4f4fa39cd569f4f4c329c55f1d84d33c53ee8dd4 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Sun, 1 Mar 2009 00:59:15 +0900 Subject: [PATCH] c: msgpack_sbuffer; cpp: msgpack::sbuffer --- c/sbuffer.h | 37 ++++++++++++++++++------- cpp/sbuffer.hpp | 72 ++++++++++++++++++++++++++++++------------------ cpp/zone.hpp.erb | 1 - example/simple.c | 2 +- 4 files changed, 73 insertions(+), 39 deletions(-) diff --git a/c/sbuffer.h b/c/sbuffer.h index 3694dbde..8dae1032 100644 --- a/c/sbuffer.h +++ b/c/sbuffer.h @@ -21,14 +21,18 @@ #include #include +#ifndef MSGPACK_SBUFFER_INIT_SIZE +#define MSGPACK_SBUFFER_INIT_SIZE 2048 +#endif + #ifdef __cplusplus extern "C" { #endif -typedef struct { - char* ptr; +typedef struct msgpack_sbuffer { size_t size; - size_t capacity; + char* data; + size_t alloc; } msgpack_sbuffer; static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf) @@ -38,27 +42,40 @@ static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf) static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf) { - free(sbuf->ptr); + free(sbuf->data); } static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len) { msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data; - if(sbuf->capacity - sbuf->size < len) { - size_t nsize = (sbuf->capacity ? sbuf->capacity*2 : 2048); + + if(sbuf->alloc - sbuf->size < len) { + size_t nsize = (sbuf->alloc) ? + sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; + while(nsize < sbuf->size + len) { nsize *= 2; } - void* tmp = realloc(sbuf->ptr, nsize); + void* tmp = realloc(sbuf->data, nsize); if(!tmp) { return -1; } - sbuf->ptr = (char*)tmp; - sbuf->capacity = nsize; + sbuf->data = (char*)tmp; + sbuf->alloc = nsize; } - memcpy(sbuf->ptr + sbuf->size, buf, len); + + memcpy(sbuf->data + sbuf->size, buf, len); sbuf->size += len; return 0; } +static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf) +{ + char* tmp = sbuf->data; + sbuf->data = NULL; + sbuf->size = 0; + sbuf->alloc = NULL; + return tmp; +} + #ifdef __cplusplus } diff --git a/cpp/sbuffer.hpp b/cpp/sbuffer.hpp index 1dac6da9..37ede490 100644 --- a/cpp/sbuffer.hpp +++ b/cpp/sbuffer.hpp @@ -18,62 +18,80 @@ #ifndef MSGPACK_SBUFFER_HPP__ #define MSGPACK_SBUFFER_HPP__ -#include -#include +#include "msgpack/sbuffer.h" #include namespace msgpack { -class sbuffer { +class sbuffer : public msgpack_sbuffer { public: - sbuffer() : m_capacity(0), m_size(0), m_ptr(NULL) { } + sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE) + { + msgpack_sbuffer* sbuf = static_cast(this); + + sbuf->data = (char*)::malloc(initsz); + if(!sbuf->data) { + throw std::bad_alloc(); + } + + sbuf->size = 0; + sbuf->alloc = initsz; + } ~sbuffer() { - free(m_ptr); + msgpack_sbuffer* sbuf = static_cast(this); + ::free(sbuf->data); } public: - void write(const char* buf, size_t len) + void write(const char* buf, unsigned int len) { - if(m_capacity - m_size < len) { - size_t nsize = (m_capacity ? m_capacity*2 : 2048); - while(nsize < m_size + len) { nsize *= 2; } - - char* tmp = (char*)realloc(m_ptr, nsize); - if(!tmp) { throw std::bad_alloc(); } - - m_ptr = tmp; - m_capacity = nsize; + msgpack_sbuffer* sbuf = static_cast(this); + if(sbuf->alloc - sbuf->size < len) { + expand_buffer(len); } - memcpy(m_ptr + m_size, buf, len); - m_size += len; + memcpy(sbuf->data + sbuf->size, buf, len); + sbuf->size += len; } char* data() { - return m_ptr; + msgpack_sbuffer* sbuf = static_cast(this); + return sbuf->data; } size_t size() const { - return m_size; + const msgpack_sbuffer* sbuf = static_cast(this); + return sbuf->size; } char* release() { - char* tmp = m_ptr; - m_capacity = 0; - m_size = 0; - m_ptr = NULL; - return tmp; + msgpack_sbuffer* sbuf = static_cast(this); + return msgpack_sbuffer_release(sbuf); } private: - size_t m_capacity; - size_t m_size; - char* m_ptr; + void expand_buffer(size_t len) + { + msgpack_sbuffer* sbuf = static_cast(this); + + size_t nsize = (sbuf->alloc) ? + sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; + + while(nsize < sbuf->size + len) { nsize *= 2; } + + void* tmp = realloc(sbuf->data, nsize); + if(!tmp) { + throw std::bad_alloc(); + } + + sbuf->data = (char*)tmp; + sbuf->alloc = nsize; + } private: sbuffer(const sbuffer&); diff --git a/cpp/zone.hpp.erb b/cpp/zone.hpp.erb index 06cb9d39..a2536270 100644 --- a/cpp/zone.hpp.erb +++ b/cpp/zone.hpp.erb @@ -99,4 +99,3 @@ T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>) #endif /* msgpack/zone.hpp */ -// vim: ft=cpp ts=4 sw=4 softtabstop=4 noexpandtab smarttab diff --git a/example/simple.c b/example/simple.c index df604249..41d8bb70 100644 --- a/example/simple.c +++ b/example/simple.c @@ -23,7 +23,7 @@ int main(void) msgpack_zone_init(&mempool, 2048); msgpack_object deserialized; - msgpack_unpack(sbuf.ptr, sbuf.size, NULL, &mempool, &deserialized); + msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized); /* print the deserialized object. */ msgpack_object_print(stdout, deserialized);