summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/AUTHORS1
-rw-r--r--cpp/COPYING14
-rw-r--r--cpp/ChangeLog0
-rw-r--r--cpp/Makefile.am7
-rw-r--r--cpp/NEWS0
-rw-r--r--cpp/README21
-rwxr-xr-xcpp/bootstrap3
-rw-r--r--cpp/configure.in23
-rw-r--r--cpp/type/array.hpp2
-rw-r--r--cpp/type/boolean.hpp2
-rw-r--r--cpp/type/float.hpp2
-rw-r--r--cpp/type/integer.hpp2
-rw-r--r--cpp/type/map.hpp2
-rw-r--r--cpp/type/nil.hpp2
-rw-r--r--cpp/type/raw.hpp2
-rw-r--r--cpp/type/tuple.hpp.erb2
-rw-r--r--cpp/unpack.cpp369
-rw-r--r--cpp/unpack.hpp157
-rw-r--r--cpp/zone.cpp100
-rw-r--r--cpp/zone.hpp.erb59
20 files changed, 162 insertions, 608 deletions
diff --git a/cpp/AUTHORS b/cpp/AUTHORS
deleted file mode 100644
index ababacb..0000000
--- a/cpp/AUTHORS
+++ /dev/null
@@ -1 +0,0 @@
-FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
diff --git a/cpp/COPYING b/cpp/COPYING
deleted file mode 100644
index 6f5f220..0000000
--- a/cpp/COPYING
+++ /dev/null
@@ -1,14 +0,0 @@
-Copyright (C) 2008-2009 FURUHASHI Sadayuki
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
diff --git a/cpp/ChangeLog b/cpp/ChangeLog
deleted file mode 100644
index e69de29..0000000
--- a/cpp/ChangeLog
+++ /dev/null
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index c7ddf4b..406c57b 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -1,9 +1,7 @@
lib_LTLIBRARIES = libmsgpack.la
libmsgpack_la_SOURCES = \
- object.cpp \
- unpack.cpp \
- zone.cpp
+ object.cpp
nobase_include_HEADERS = \
msgpack.hpp \
@@ -28,7 +26,6 @@ noinst_HEADERS = \
# FIXME
object.lo: msgpack/type/tuple.hpp
unpack.lo: msgpack/type/tuple.hpp msgpack/zone.hpp
-zone.lo: msgpack/type/tuple.hpp msgpack/zone.hpp
msgpack/type/tuple.hpp: msgpack/type/tuple.hpp.erb
$(ERB) $< > $@.tmp
@@ -42,6 +39,8 @@ MOSTLYCLEANFILES = \
msgpack/type/tuple.hpp \
msgpack/zone.hpp
+libmsgpack_la_LIBADD = -L../c -lmsgpackc
+
# -version-info CURRENT:REVISION:AGE
libmsgpack_la_LDFLAGS = -version-info 1:0:0
diff --git a/cpp/NEWS b/cpp/NEWS
deleted file mode 100644
index e69de29..0000000
--- a/cpp/NEWS
+++ /dev/null
diff --git a/cpp/README b/cpp/README
deleted file mode 100644
index 96f18b1..0000000
--- a/cpp/README
+++ /dev/null
@@ -1,21 +0,0 @@
-MessagePack for C++
--------------------
-MessagePack is a binary-based efficient data interchange format.
-
-
-
-Copyright (C) 2008-2009 FURUHASHI Sadayuki
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
diff --git a/cpp/bootstrap b/cpp/bootstrap
deleted file mode 100755
index 7e61b82..0000000
--- a/cpp/bootstrap
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-NO_NEST=1
-. ../bootstrap
diff --git a/cpp/configure.in b/cpp/configure.in
deleted file mode 100644
index 2c3e5d0..0000000
--- a/cpp/configure.in
+++ /dev/null
@@ -1,23 +0,0 @@
-AC_INIT(object.cpp)
-AM_INIT_AUTOMAKE(msgpack, 0.1.0)
-AC_CONFIG_HEADER(config.h)
-
-AC_SUBST(CXXFLAGS)
-if test "" = "$CXXFLAGS"; then
- CXXFLAGS="-g -O4"
-fi
-
-AC_PROG_CXX
-AC_PROG_LIBTOOL
-
-AC_CHECK_PROG(ERB, erb, erb)
-if test "x$ERB" = x; then
- AC_MSG_ERROR([cannot find erb. Ruby is needed to build.])
-fi
-
-AC_CHECK_LIB(stdc++, main)
-
-CXXFLAGS="-O4 -Wall $CXXFLAGS -I.."
-
-AC_OUTPUT([Makefile])
-
diff --git a/cpp/type/array.hpp b/cpp/type/array.hpp
index b2a81ef..6027251 100644
--- a/cpp/type/array.hpp
+++ b/cpp/type/array.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/boolean.hpp b/cpp/type/boolean.hpp
index 60f1714..86bd697 100644
--- a/cpp/type/boolean.hpp
+++ b/cpp/type/boolean.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/float.hpp b/cpp/type/float.hpp
index 2178434..108709d 100644
--- a/cpp/type/float.hpp
+++ b/cpp/type/float.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/integer.hpp b/cpp/type/integer.hpp
index 5cd10f6..ecb7b89 100644
--- a/cpp/type/integer.hpp
+++ b/cpp/type/integer.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/map.hpp b/cpp/type/map.hpp
index 4585d66..c136d53 100644
--- a/cpp/type/map.hpp
+++ b/cpp/type/map.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/nil.hpp b/cpp/type/nil.hpp
index ab0c363..93e66ff 100644
--- a/cpp/type/nil.hpp
+++ b/cpp/type/nil.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/raw.hpp b/cpp/type/raw.hpp
index b102ee8..b6ace3f 100644
--- a/cpp/type/raw.hpp
+++ b/cpp/type/raw.hpp
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/type/tuple.hpp.erb b/cpp/type/tuple.hpp.erb
index a20f5d9..586d84c 100644
--- a/cpp/type/tuple.hpp.erb
+++ b/cpp/type/tuple.hpp.erb
@@ -1,7 +1,7 @@
//
// MessagePack for C++ static resolution routine
//
-// Copyright (C) 2008 FURUHASHI Sadayuki
+// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/cpp/unpack.cpp b/cpp/unpack.cpp
deleted file mode 100644
index 0b9a476..0000000
--- a/cpp/unpack.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-//
-// MessagePack for C++ deserializing routine
-//
-// Copyright (C) 2008-2009 FURUHASHI Sadayuki
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "msgpack/unpack.hpp"
-#include "msgpack/unpack_define.h"
-#include <stdlib.h>
-
-namespace msgpack {
-
-
-//namespace {
-struct unpack_user {
- zone* z;
- bool referenced;
-};
-//} // noname namespace
-
-
-#define msgpack_unpack_struct(name) \
- struct msgpack_unpacker ## name
-
-#define msgpack_unpack_func(ret, name) \
- ret msgpack_unpacker ## name
-
-#define msgpack_unpack_callback(name) \
- msgpack_unpack ## name
-
-#define msgpack_unpack_object object
-
-#define msgpack_unpack_user unpack_user
-
-
-struct msgpack_unpacker_context;
-
-static void msgpack_unpacker_init(struct msgpack_unpacker_context* ctx);
-
-static object msgpack_unpacker_data(struct msgpack_unpacker_context* ctx);
-
-static int msgpack_unpacker_execute(struct msgpack_unpacker_context* ctx,
- const char* data, size_t len, size_t* off);
-
-
-static inline object msgpack_unpack_init(unpack_user* u)
-{ return object(); }
-
-static inline object msgpack_unpack_uint8(unpack_user* u, uint8_t d)
-{ object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
-
-static inline object msgpack_unpack_uint16(unpack_user* u, uint16_t d)
-{ object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
-
-static inline object msgpack_unpack_uint32(unpack_user* u, uint32_t d)
-{ object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
-
-static inline object msgpack_unpack_uint64(unpack_user* u, uint64_t d)
-{ object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
-
-static inline object msgpack_unpack_int8(unpack_user* u, int8_t d)
-{ if(d >= 0) { object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
- else { object o; o.type = type::NEGATIVE_INTEGER; o.via.i64 = d; return o; } }
-
-static inline object msgpack_unpack_int16(unpack_user* u, int16_t d)
-{ if(d >= 0) { object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
- else { object o; o.type = type::NEGATIVE_INTEGER; o.via.i64 = d; return o; } }
-
-static inline object msgpack_unpack_int32(unpack_user* u, int32_t d)
-{ if(d >= 0) { object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
- else { object o; o.type = type::NEGATIVE_INTEGER; o.via.i64 = d; return o; } }
-
-static inline object msgpack_unpack_int64(unpack_user* u, int64_t d)
-{ if(d >= 0) { object o; o.type = type::POSITIVE_INTEGER; o.via.u64 = d; return o; }
- else { object o; o.type = type::NEGATIVE_INTEGER; o.via.i64 = d; return o; } }
-
-static inline object msgpack_unpack_float(unpack_user* u, float d)
-{ object o; o.type = type::DOUBLE; o.via.dec = d; return o; }
-
-static inline object msgpack_unpack_double(unpack_user* u, double d)
-{ object o; o.type = type::DOUBLE; o.via.dec = d; return o; }
-
-static inline object msgpack_unpack_nil(unpack_user* u)
-{ object o; o.type = type::NIL; return o; }
-
-static inline object msgpack_unpack_true(unpack_user* u)
-{ object o; o.type = type::BOOLEAN; o.via.boolean = true; return o; }
-
-static inline object msgpack_unpack_false(unpack_user* u)
-{ object o; o.type = type::BOOLEAN; o.via.boolean = false; return o; }
-
-static inline object msgpack_unpack_array(unpack_user* u, unsigned int n)
-{
- object o;
- o.type = type::ARRAY;
- o.via.array.size = 0;
- o.via.array.ptr = (object*)u->z->malloc(n*sizeof(object));
- return o;
-}
-
-static inline void msgpack_unpack_array_item(unpack_user* u, object* c, object o)
-{ c->via.array.ptr[c->via.array.size++] = o; }
-
-static inline object msgpack_unpack_map(unpack_user* u, unsigned int n)
-{
- object o;
- o.type = type::MAP;
- o.via.map.size = 0;
- o.via.map.ptr = (object_kv*)u->z->malloc(n*sizeof(object_kv));
- return o;
-}
-
-static inline void msgpack_unpack_map_item(unpack_user* u, object* c, object k, object v)
-{
- c->via.map.ptr[c->via.map.size].key = k;
- c->via.map.ptr[c->via.map.size].val = v;
- ++c->via.map.size;
-}
-
-static inline object msgpack_unpack_raw(unpack_user* u, const char* b, const char* p, unsigned int l)
-{
- object o;
- o.type = type::RAW;
- o.via.raw.ptr = p;
- o.via.raw.size = l;
- u->referenced = true;
- return o;
-}
-
-#include "msgpack/unpack_template.h"
-
-
-namespace {
-struct context {
- context()
- {
- msgpack_unpacker_init(&m_ctx);
- unpack_user u = {NULL, false};
- m_ctx.user = u;
- }
-
- ~context() { }
-
- int execute(const char* data, size_t len, size_t* off)
- {
- return msgpack_unpacker_execute(&m_ctx, data, len, off);
- }
-
- object data()
- {
- return msgpack_unpacker_data(&m_ctx);
- }
-
- void reset()
- {
- zone* z = m_ctx.user.z;
- msgpack_unpacker_init(&m_ctx);
- unpack_user u = {z, false};
- m_ctx.user = u;
- }
-
- void set_zone(zone* z)
- {
- m_ctx.user.z = z;
- }
-
- bool is_referenced() const
- {
- return m_ctx.user.referenced;
- }
-
-private:
- msgpack_unpacker_context m_ctx;
- zone* m_zone;
-
-private:
- context(const context&);
-};
-
-static inline context* as_ctx(void* m)
-{
- return reinterpret_cast<context*>(m);
-}
-
-
-static const size_t COUNTER_SIZE = sizeof(unsigned int);
-
-static inline void init_count(void* buffer)
-{
- *(volatile unsigned int*)buffer = 1;
-}
-
-static inline void decl_count(void* buffer)
-{
- //if(--*(unsigned int*)buffer == 0) {
- if(__sync_sub_and_fetch((unsigned int*)buffer, 1) == 0) {
- free(buffer);
- }
-}
-
-static inline void incr_count(void* buffer)
-{
- //++*(unsigned int*)buffer;
- __sync_add_and_fetch((unsigned int*)buffer, 1);
-}
-
-static inline unsigned int get_count(void* buffer)
-{
- return *(volatile unsigned int*)buffer;
-}
-
-} // noname namespace
-
-
-unpacker::unpacker(size_t initial_buffer_size) :
- m_buffer(NULL),
- m_used(0),
- m_free(0),
- m_off(0),
- m_zone(new zone()),
- m_ctx(new context()),
- m_initial_buffer_size(initial_buffer_size)
-{
- if(m_initial_buffer_size < COUNTER_SIZE) {
- m_initial_buffer_size = COUNTER_SIZE;
- }
-
- as_ctx(m_ctx)->set_zone(m_zone.get());
-
- m_buffer = (char*)::malloc(m_initial_buffer_size);
- if(!m_buffer) { throw std::bad_alloc(); }
- init_count(m_buffer);
-
- m_used = COUNTER_SIZE;
- m_free = m_initial_buffer_size - m_used;
- m_off = COUNTER_SIZE;
-}
-
-
-unpacker::~unpacker()
-{
- delete as_ctx(m_ctx);
- decl_count(m_buffer);
-}
-
-void unpacker::expand_buffer(size_t len)
-{
- if(m_used == m_off && get_count(m_buffer) == 1 &&
- !as_ctx(m_ctx)->is_referenced()) {
- // rewind buffer
- m_free += m_used - COUNTER_SIZE;
- m_used = COUNTER_SIZE;
- m_off = COUNTER_SIZE;
- if(m_free >= len) { return; }
- }
-
- if(m_off == COUNTER_SIZE) {
- size_t next_size = (m_used + m_free) * 2;
- while(next_size < len + m_used) { next_size *= 2; }
-
- char* tmp = (char*)::realloc(m_buffer, next_size);
- if(!tmp) { throw std::bad_alloc(); }
-
- m_buffer = tmp;
- m_free = next_size - m_used;
-
- } else {
- size_t next_size = m_initial_buffer_size; // include COUNTER_SIZE
- size_t not_parsed = m_used - m_off;
- while(next_size < len + not_parsed + COUNTER_SIZE) { next_size *= 2; }
-
- char* tmp = (char*)::malloc(next_size);
- if(!tmp) { throw std::bad_alloc(); }
- init_count(tmp);
-
- try {
- m_zone->push_finalizer(decl_count, m_buffer);
- } catch (...) { free(tmp); throw; }
-
- memcpy(tmp+COUNTER_SIZE, m_buffer+m_off, not_parsed);
-
- m_buffer = tmp;
- m_used = not_parsed + COUNTER_SIZE;
- m_free = next_size - m_used;
- m_off = COUNTER_SIZE;
- }
-}
-
-bool unpacker::execute()
-{
- int ret = as_ctx(m_ctx)->execute(m_buffer, m_used, &m_off);
- if(ret < 0) {
- throw unpack_error("parse error");
- } else if(ret == 0) {
- return false;
- } else {
- return true;
- }
-}
-
-zone* unpacker::release_zone()
-{
- m_zone->push_finalizer(decl_count, m_buffer);
- incr_count(m_buffer);
-
- //std::auto_ptr<zone> old(new zone());
- //m_zone.swap(old);
- zone* n = new zone();
- std::auto_ptr<zone> old(m_zone.release());
- m_zone.reset(n);
-
- as_ctx(m_ctx)->set_zone(m_zone.get());
-
- return old.release();
-}
-
-object unpacker::data()
-{
- return as_ctx(m_ctx)->data();
-}
-
-void unpacker::reset()
-{
- //if(!m_zone->empty()) { delete release_zone(); }
- as_ctx(m_ctx)->reset();
-}
-
-
-object unpacker::unpack(const char* data, size_t len, zone& z, size_t* off)
-{
- context ctx;
- ctx.set_zone(&z);
- if(off) {
- size_t noff = *off;
- int ret = ctx.execute(data, len, &noff);
- if(ret < 0) {
- throw unpack_error("parse error");
- } else if(ret == 0) {
- throw unpack_error("insufficient bytes");
- }
- *off = noff;
- } else {
- size_t noff = 0;
- int ret = ctx.execute(data, len, &noff);
- if(ret < 0) {
- throw unpack_error("parse error");
- } else if(ret == 0) {
- throw unpack_error("insufficient bytes");
- } else if(noff < len) {
- throw unpack_error("extra bytes");
- }
- }
- return ctx.data();
-}
-
-
-} // namespace msgpack
-
diff --git a/cpp/unpack.hpp b/cpp/unpack.hpp
index cde45e7..8c77726 100644
--- a/cpp/unpack.hpp
+++ b/cpp/unpack.hpp
@@ -18,6 +18,7 @@
#ifndef MSGPACK_UNPACK_HPP__
#define MSGPACK_UNPACK_HPP__
+#include "msgpack/unpack.h"
#include "msgpack/object.hpp"
#include "msgpack/zone.hpp"
#include <memory>
@@ -36,21 +37,21 @@ struct unpack_error : public std::runtime_error {
};
-class unpacker {
+class unpacker : public msgpack_unpacker {
public:
unpacker(size_t initial_buffer_size = MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE);
~unpacker();
public:
- /*! 1. reserve buffer. at least `len' bytes of capacity will be ready */
- void reserve_buffer(size_t len);
+ /*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
+ void reserve_buffer(size_t size);
/*! 2. read data to the buffer() up to buffer_capacity() bytes */
char* buffer();
size_t buffer_capacity() const;
/*! 3. specify the number of bytes actually copied */
- void buffer_consumed(size_t len);
+ void buffer_consumed(size_t size);
/*! 4. repeat execute() until it retunrs false */
bool execute();
@@ -114,71 +115,157 @@ public:
size_t nonparsed_size() const;
/*! skip specified size of non-parsed buffer, leaving the buffer */
- // Note that the `len' argument must be smaller than nonparsed_size()
- void skip_nonparsed_buffer(size_t len);
+ // Note that the `size' argument must be smaller than nonparsed_size()
+ void skip_nonparsed_buffer(size_t size);
/*! remove unparsed buffer from unpacker */
// Note that reset() leaves non-parsed buffer.
void remove_nonparsed_buffer();
private:
- char* m_buffer;
- size_t m_used;
- size_t m_free;
- size_t m_off;
+ unpacker(const unpacker&);
+};
- std::auto_ptr<zone> m_zone;
- void* m_ctx;
+typedef enum {
+ MSGPACK_UNPACK_SUCCESS = 2,
+ MSGPACK_UNPACK_EXTRA_BYTES = 1,
+ MSGPACK_UNPACK_CONTINUE = 0,
+ MSGPACK_UNPACK_PARSE_ERROR = -1,
+} unpack_return;
- size_t m_initial_buffer_size;
+static unpack_return unpack(const char* data, size_t len, size_t* off,
+ zone* z, object* result);
-private:
- void expand_buffer(size_t len);
-private:
- unpacker(const unpacker&);
+// obsolete
+static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);
-public:
- static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);
-};
+inline unpacker::unpacker(size_t initial_buffer_size)
+{
+ if(!msgpack_unpacker_init(this, initial_buffer_size)) {
+ throw std::bad_alloc();
+ }
+}
+
+inline unpacker::~unpacker()
+{
+ msgpack_unpacker_destroy(this);
+}
-inline void unpacker::reserve_buffer(size_t len)
+inline void unpacker::reserve_buffer(size_t size)
{
- if(m_free >= len) { return; }
- expand_buffer(len);
+ if(!msgpack_unpacker_reserve_buffer(this, size)) {
+ throw std::bad_alloc();
+ }
}
inline char* unpacker::buffer()
- { return m_buffer + m_used; }
+{
+ return msgpack_unpacker_buffer(this);
+}
inline size_t unpacker::buffer_capacity() const
- { return m_free; }
+{
+ return msgpack_unpacker_buffer_capacity(this);
+}
-inline void unpacker::buffer_consumed(size_t len)
+inline void unpacker::buffer_consumed(size_t size)
{
- m_used += len;
- m_free -= len;
+ return msgpack_unpacker_buffer_consumed(this, size);
+}
+
+
+inline bool unpacker::execute()
+{
+ int ret = msgpack_unpacker_execute(this);
+ if(ret < 0) {
+ throw unpack_error("parse error");
+ } else if(ret == 0) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+inline object unpacker::data()
+{
+ msgpack_object obj = msgpack_unpacker_data(this);
+ return *reinterpret_cast<object*>(&obj);
+}
+
+inline zone* unpacker::release_zone()
+{
+ if(!msgpack_unpacker_flush_zone(this)) {
+ throw std::bad_alloc();
+ }
+
+ zone* r = new zone();
+
+ msgpack_zone old = *this->z;
+ *this->z = *z;
+ *z = old;
+
+ return r;
+}
+
+inline void unpacker::reset()
+{
+ msgpack_unpacker_reset(this);
}
inline char* unpacker::nonparsed_buffer()
- { return m_buffer + m_off; }
+{
+ return buf + off;
+}
inline size_t unpacker::nonparsed_size() const
- { return m_used - m_off; }
+{
+ return used - off;
+}
-inline void unpacker::skip_nonparsed_buffer(size_t len)
- { m_off += len; }
+inline void unpacker::skip_nonparsed_buffer(size_t size)
+{
+ off += size;
+}
inline void unpacker::remove_nonparsed_buffer()
- { m_used = m_off; }
+{
+ used = off;
+}
+
+inline unpack_return unpack(const char* data, size_t len, size_t* off,
+ zone* z, object* result)
+{
+ return (unpack_return)msgpack_unpack(data, len, off,
+ z, reinterpret_cast<msgpack_object*>(result));
+}
-inline object unpack(const char* data, size_t len, zone& z, size_t* off = NULL)
+inline object unpack(const char* data, size_t len, zone& z, size_t* off)
{
- return unpacker::unpack(data, len, z, off);
+ object result;
+
+ switch( msgpack::unpack(data, len, off, &z, &result) ) {
+ case MSGPACK_UNPACK_SUCCESS:
+ return result;
+
+ case MSGPACK_UNPACK_EXTRA_BYTES:
+ if(off) {
+ return result;
+ } else {
+ throw unpack_error("extra bytes");
+ }
+
+ case MSGPACK_UNPACK_CONTINUE:
+ throw unpack_error("insufficient bytes");
+
+ case MSGPACK_UNPACK_PARSE_ERROR:
+ default:
+ throw unpack_error("parse error");
+ }
}
diff --git a/cpp/zone.cpp b/cpp/zone.cpp
deleted file mode 100644
index f765266..0000000
--- a/cpp/zone.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// MessagePack for C++ memory pool
-//
-// Copyright (C) 2008-2009 FURUHASHI Sadayuki
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "msgpack/zone.hpp"
-#include <algorithm>
-
-namespace msgpack {
-
-
-zone::zone(size_t chunk_size) :
- m_chunk_size(chunk_size)
-{
- chunk dummy = {0, NULL, NULL};
- m_chunk_array.push_back(dummy);
-}
-
-zone::~zone()
-{
- clear();
-}
-
-namespace {
- template <typename Private>
- struct zone_finalize {
- void operator() (Private& f) {
- (*f.func)(f.obj);
- }
- };
-
- template <typename Private>
- struct zone_free {
- void operator() (Private& c) {
- ::free(c.alloc);
- }
- };
-}
-
-void zone::clear()
-{
- std::for_each(m_finalizers.rbegin(), m_finalizers.rend(),
- zone_finalize<finalizer>());
- m_finalizers.clear();
-
- std::for_each(m_chunk_array.begin(), m_chunk_array.end(),
- zone_free<chunk>());
- m_chunk_array.resize(1);
- m_chunk_array[0].ptr = NULL;
- m_chunk_array[0].free = 0;
-}
-
-bool zone::empty() const
-{
- return m_chunk_array.back().alloc == NULL &&
- m_finalizers.empty();
-}
-
-void* zone::malloc(size_t size)
-{
- if(m_chunk_array.back().free > size) {
- char* p = (char*)m_chunk_array.back().ptr;
- m_chunk_array.back().ptr = p + size;
- m_chunk_array.back().free -= size;
- return p;
- }
-
- size_t sz = m_chunk_size;
- while(sz < size) { sz *= 2; }
-
- chunk dummy = {0, NULL, NULL};
- m_chunk_array.push_back(dummy);
-
- char* p = (char*)::malloc(sz);
- if(!p) {
- m_chunk_array.pop_back();
- throw std::bad_alloc();
- }
-
- m_chunk_array.back().free = sz - size;
- m_chunk_array.back().ptr = p + size;
- m_chunk_array.back().alloc = p;
- return p;
-}
-
-
-} // namespace msgpack
-
diff --git a/cpp/zone.hpp.erb b/cpp/zone.hpp.erb
index c0eb2e3..06cb9d3 100644
--- a/cpp/zone.hpp.erb
+++ b/cpp/zone.hpp.erb
@@ -19,17 +19,15 @@
#define MSGPACK_ZONE_HPP__
#include "msgpack/object.hpp"
+#include "msgpack/zone.h"
#include <cstdlib>
#include <vector>
-#ifndef MSGPACK_ZONE_CHUNK_SIZE
-#define MSGPACK_ZONE_CHUNK_SIZE 2048
-#endif
<% GENERATION_LIMIT = 15 %>
namespace msgpack {
-class zone {
+class zone : public msgpack_zone {
public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
~zone();
@@ -37,11 +35,7 @@ public:
public:
void* malloc(size_t size);
- void push_finalizer(void (*func)(void*), void* obj);
-
- void clear();
-
- bool empty() const;
+ void push_finalizer(void (*func)(void*), void* data);
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
@@ -49,35 +43,39 @@ public:
<%}%>
private:
- struct chunk {
- size_t free;
- void* ptr;
- void* alloc;
- };
-
- std::vector<chunk> m_chunk_array;
-
- struct finalizer {
- void (*func)(void*);
- void* obj;
- };
-
- std::vector<finalizer> m_finalizers;
-
template <typename T>
static void object_destructor(void* obj);
- size_t m_chunk_size;
-
private:
zone(const zone&);
};
-inline void zone::push_finalizer(void (*func)(void*), void* obj)
+
+inline zone::zone(size_t chunk_size)
+{
+ msgpack_zone_init(this, chunk_size);
+}
+
+inline zone::~zone()
+{
+ msgpack_zone_destroy(this);
+}
+
+inline void* zone::malloc(size_t size)
+{
+ void* ptr = msgpack_zone_malloc(this, size);
+ if(!ptr) {
+ throw std::bad_alloc();
+ }
+ return ptr;
+}
+
+inline void zone::push_finalizer(void (*func)(void*), void* data)
{
- finalizer f = {func, obj};
- m_finalizers.push_back(f);
+ if(!msgpack_zone_push_finalizer(this, func, data)) {
+ throw std::bad_alloc();
+ }
}
template <typename T>
@@ -93,7 +91,7 @@ T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
void* x = malloc(sizeof(T));
push_finalizer(&zone::object_destructor<T>, x);
try { return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); }
- catch (...) { m_finalizers.pop_back(); throw; }
+ catch (...) { --finalizer_array.tail; throw; }
}
<%}%>
@@ -101,3 +99,4 @@ 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