mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-19 13:02:13 +01:00
c: msgpack_sbuffer; cpp: msgpack::sbuffer
This commit is contained in:
parent
c60b6be548
commit
4f4fa39cd5
37
c/sbuffer.h
37
c/sbuffer.h
@ -21,14 +21,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
@ -18,62 +18,80 @@
|
||||
#ifndef MSGPACK_SBUFFER_HPP__
|
||||
#define MSGPACK_SBUFFER_HPP__
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "msgpack/sbuffer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
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<msgpack_sbuffer*>(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<msgpack_sbuffer*>(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<msgpack_sbuffer*>(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<msgpack_sbuffer*>(this);
|
||||
return sbuf->data;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_size;
|
||||
const msgpack_sbuffer* sbuf = static_cast<const msgpack_sbuffer*>(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<msgpack_sbuffer*>(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<msgpack_sbuffer*>(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&);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user