summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorUENISHI Kota <kuenishi+github@gmail.com>2010-06-03 00:14:19 +0900
committerUENISHI Kota <kuenishi+github@gmail.com>2010-06-03 00:14:19 +0900
commit8ecaf7ad4ce4185e81fae775332282ed551fa886 (patch)
tree68b7fb5c875f5620033ac8fa4e046bfdd51f78d0 /cpp/src
parent49f3872d047624b1995b8c60edec8bad35429fd3 (diff)
parentd4049fe593ae4465e7a258d138c2166571a0f1a7 (diff)
downloadmsgpack-python-8ecaf7ad4ce4185e81fae775332282ed551fa886.tar.gz
Merge branch 'master' of ssh://github.com/msgpack/msgpack
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile.am17
-rw-r--r--cpp/src/msgpack.h5
-rw-r--r--cpp/src/msgpack/object.h8
-rw-r--r--cpp/src/msgpack/pack.h15
-rw-r--r--cpp/src/msgpack/sbuffer.h29
-rw-r--r--cpp/src/msgpack/unpack.h139
-rw-r--r--cpp/src/msgpack/unpack.hpp15
-rw-r--r--cpp/src/msgpack/vrefbuffer.h45
-rw-r--r--cpp/src/msgpack/zbuffer.h43
-rw-r--r--cpp/src/msgpack/zone.h7
-rw-r--r--cpp/src/unpack.c70
-rw-r--r--cpp/src/zone.c1
12 files changed, 361 insertions, 33 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am
index 4cfa87e..6b6457e 100644
--- a/cpp/src/Makefile.am
+++ b/cpp/src/Makefile.am
@@ -73,3 +73,20 @@ EXTRA_DIST = \
msgpack/type/define.hpp.erb \
msgpack/type/tuple.hpp.erb
+
+doxygen_c:
+ cat ../Doxyfile > Doxyfile_c
+ echo "FILE_PATTERNS = *.h" >> Doxyfile_c
+ echo "OUTPUT_DIRECTORY = doc_c" >> Doxyfile_c
+ echo "PROJECT_NAME = \"MessagePack for C\"" >> Doxyfile_c
+ doxygen Doxyfile_c
+
+doxygen_cpp:
+ cat ../Doxyfile > Doxyfile_cpp
+ echo "FILE_PATTERNS = *.hpp" >> Doxyfile_cpp
+ echo "OUTPUT_DIRECTORY = doc_cpp" >> Doxyfile_cpp
+ echo "PROJECT_NAME = \"MessagePack for C++\"" >> Doxyfile_cpp
+ doxygen Doxyfile_cpp
+
+doxygen: doxygen_c doxygen_cpp
+
diff --git a/cpp/src/msgpack.h b/cpp/src/msgpack.h
index 21729f4..0cd8a19 100644
--- a/cpp/src/msgpack.h
+++ b/cpp/src/msgpack.h
@@ -15,6 +15,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+/**
+ * @defgroup msgpack MessagePack C
+ * @{
+ * @}
+ */
#include "msgpack/object.h"
#include "msgpack/zone.h"
#include "msgpack/pack.h"
diff --git a/cpp/src/msgpack/object.h b/cpp/src/msgpack/object.h
index 71a27bb..cf0b4c1 100644
--- a/cpp/src/msgpack/object.h
+++ b/cpp/src/msgpack/object.h
@@ -26,6 +26,12 @@ extern "C" {
#endif
+/**
+ * @defgroup msgpack_object Dynamically typed object
+ * @ingroup msgpack
+ * @{
+ */
+
typedef enum {
MSGPACK_OBJECT_NIL = 0x00,
MSGPACK_OBJECT_BOOLEAN = 0x01,
@@ -81,6 +87,8 @@ void msgpack_object_print(FILE* out, msgpack_object o);
bool msgpack_object_equal(const msgpack_object x, const msgpack_object y);
+/** @} */
+
#ifdef __cplusplus
}
diff --git a/cpp/src/msgpack/pack.h b/cpp/src/msgpack/pack.h
index 1525e0f..1252895 100644
--- a/cpp/src/msgpack/pack.h
+++ b/cpp/src/msgpack/pack.h
@@ -27,6 +27,19 @@ extern "C" {
#endif
+/**
+ * @defgroup msgpack_buffer Buffers
+ * @ingroup msgpack
+ * @{
+ * @}
+ */
+
+/**
+ * @defgroup msgpack_pack Serializer
+ * @ingroup msgpack
+ * @{
+ */
+
typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len);
typedef struct msgpack_packer {
@@ -74,6 +87,8 @@ static int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l);
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
+/** @} */
+
#define msgpack_pack_inline_func(name) \
inline int msgpack_pack ## name
diff --git a/cpp/src/msgpack/sbuffer.h b/cpp/src/msgpack/sbuffer.h
index 57f424a..778dea7 100644
--- a/cpp/src/msgpack/sbuffer.h
+++ b/cpp/src/msgpack/sbuffer.h
@@ -21,15 +21,17 @@
#include <stdlib.h>
#include <string.h>
-#ifndef MSGPACK_SBUFFER_INIT_SIZE
-#define MSGPACK_SBUFFER_INIT_SIZE 8192
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * @defgroup msgpack_sbuffer Simple buffer
+ * @ingroup msgpack_buffer
+ * @{
+ */
+
typedef struct msgpack_sbuffer {
size_t size;
char* data;
@@ -46,6 +48,22 @@ static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
free(sbuf->data);
}
+static inline msgpack_sbuffer* msgpack_sbuffer_new(void)
+{
+ return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer));
+}
+
+static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf)
+{
+ if(sbuf == NULL) { return; }
+ msgpack_sbuffer_destroy(sbuf);
+ free(sbuf);
+}
+
+#ifndef MSGPACK_SBUFFER_INIT_SIZE
+#define MSGPACK_SBUFFER_INIT_SIZE 8192
+#endif
+
static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
@@ -82,6 +100,9 @@ static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf)
sbuf->size = 0;
}
+/** @} */
+
+
#ifdef __cplusplus
}
#endif
diff --git a/cpp/src/msgpack/unpack.h b/cpp/src/msgpack/unpack.h
index e17d0d8..82698fc 100644
--- a/cpp/src/msgpack/unpack.h
+++ b/cpp/src/msgpack/unpack.h
@@ -20,12 +20,36 @@
#include "msgpack/zone.h"
#include "msgpack/object.h"
+#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * @defgroup msgpack_unpack Deserializer
+ * @ingroup msgpack
+ * @{
+ */
+
+typedef struct msgpack_unpacked {
+ msgpack_zone* zone;
+ msgpack_object data;
+} msgpack_unpacked;
+
+bool msgpack_unpack_next(msgpack_unpacked* result,
+ const char* data, size_t len, size_t* off);
+
+/** @} */
+
+
+/**
+ * @defgroup msgpack_unpacker Streaming deserializer
+ * @ingroup msgpack
+ * @{
+ */
+
typedef struct msgpack_unpacker {
char* buffer;
size_t used;
@@ -38,18 +62,102 @@ typedef struct msgpack_unpacker {
} msgpack_unpacker;
+#ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE
+#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024)
+#endif
+
+/**
+ * Initializes a streaming deserializer.
+ * The initialized deserializer must be destroyed by msgpack_unpacker_destroy(msgpack_unpacker*).
+ */
bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size);
+
+/**
+ * Destroys a streaming deserializer initialized by msgpack_unpacker_init(msgpack_unpacker*, size_t).
+ */
void msgpack_unpacker_destroy(msgpack_unpacker* mpac);
+
+/**
+ * Creates a streaming deserializer.
+ * The created deserializer must be destroyed by msgpack_unpacker_free(msgpack_unpacker*).
+ */
msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size);
+
+/**
+ * Frees a streaming deserializer created by msgpack_unpacker_new(size_t).
+ */
void msgpack_unpacker_free(msgpack_unpacker* mpac);
+
+#ifndef MSGPACK_UNPACKER_RESERVE_SIZE
+#define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024)
+#endif
+
+/**
+ * Reserves free space of the internal buffer.
+ * Use this function to fill the internal buffer with
+ * msgpack_unpacker_buffer(msgpack_unpacker*),
+ * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and
+ * msgpack_unpacker_buffer_consumed(msgpack_unpacker*).
+ */
static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size);
+
+/**
+ * Gets pointer to the free space of the internal buffer.
+ * Use this function to fill the internal buffer with
+ * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t),
+ * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and
+ * msgpack_unpacker_buffer_consumed(msgpack_unpacker*).
+ */
static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac);
+
+/**
+ * Gets size of the free space of the internal buffer.
+ * Use this function to fill the internal buffer with
+ * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t),
+ * msgpack_unpacker_buffer(const msgpack_unpacker*) and
+ * msgpack_unpacker_buffer_consumed(msgpack_unpacker*).
+ */
static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac);
+
+/**
+ * Notifies the deserializer that the internal buffer filled.
+ * Use this function to fill the internal buffer with
+ * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t),
+ * msgpack_unpacker_buffer(msgpack_unpacker*) and
+ * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*).
+ */
static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size);
+/**
+ * Deserializes one object.
+ * Returns true if it successes. Otherwise false is returned.
+ * @param pac pointer to an initialized msgpack_unpacked object.
+ */
+bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* pac);
+
+/**
+ * Initializes a msgpack_unpacked object.
+ * The initialized object must be destroyed by msgpack_unpacked_destroy(msgpack_unpacker*).
+ * Use the object with msgpack_unpacker_next(msgpack_unpacker*, msgpack_unpacked*) or
+ * msgpack_unpack_next(msgpack_unpacked*, const char*, size_t, size_t*).
+ */
+static inline void msgpack_unpacked_init(msgpack_unpacked* result);
+
+/**
+ * Destroys a streaming deserializer initialized by msgpack_unpacked().
+ */
+static inline void msgpack_unpacked_destroy(msgpack_unpacked* result);
+
+/**
+ * Releases the memory zone from msgpack_unpacked object.
+ * The released zone must be freed by msgpack_zone_free(msgpack_zone*).
+ */
+static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result);
+
+
int msgpack_unpacker_execute(msgpack_unpacker* mpac);
msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac);
@@ -63,7 +171,10 @@ void msgpack_unpacker_reset(msgpack_unpacker* mpac);
static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac);
+/** @} */
+
+// obsolete
typedef enum {
MSGPACK_UNPACK_SUCCESS = 2,
MSGPACK_UNPACK_EXTRA_BYTES = 1,
@@ -71,9 +182,10 @@ typedef enum {
MSGPACK_UNPACK_PARSE_ERROR = -1,
} msgpack_unpack_return;
+// obsolete
msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off,
- msgpack_zone* z, msgpack_object* result);
+ msgpack_zone* result_zone, msgpack_object* result);
static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac);
@@ -115,6 +227,31 @@ size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac)
}
+void msgpack_unpacked_init(msgpack_unpacked* result)
+{
+ memset(result, 0, sizeof(msgpack_unpacked));
+}
+
+void msgpack_unpacked_destroy(msgpack_unpacked* result)
+{
+ if(result->zone != NULL) {
+ msgpack_zone_free(result->zone);
+ result->zone = NULL;
+ memset(&result->data, 0, sizeof(msgpack_object));
+ }
+}
+
+msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result)
+{
+ if(result->zone != NULL) {
+ msgpack_zone* z = result->zone;
+ result->zone = NULL;
+ return z;
+ }
+ return NULL;
+}
+
+
#ifdef __cplusplus
}
#endif
diff --git a/cpp/src/msgpack/unpack.hpp b/cpp/src/msgpack/unpack.hpp
index 56ce0f6..7b45017 100644
--- a/cpp/src/msgpack/unpack.hpp
+++ b/cpp/src/msgpack/unpack.hpp
@@ -24,8 +24,9 @@
#include <memory>
#include <stdexcept>
+// backward compatibility
#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
-#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE (32*1024)
+#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE
#endif
namespace msgpack {
@@ -64,12 +65,12 @@ private:
class unpacker : public msgpack_unpacker {
public:
- unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE);
+ unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
~unpacker();
public:
/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
- void reserve_buffer(size_t size);
+ void reserve_buffer(size_t size = MSGPACK_UNPACKER_RESERVE_SIZE);
/*! 2. read data to the buffer() up to buffer_capacity() bytes */
char* buffer();
@@ -160,7 +161,7 @@ private:
};
-static bool unpack(unpacked* result,
+static void unpack(unpacked* result,
const char* data, size_t len, size_t* offset = NULL);
@@ -312,7 +313,7 @@ inline void unpacker::remove_nonparsed_buffer()
}
-inline bool unpack(unpacked* result,
+inline void unpack(unpacked* result,
const char* data, size_t len, size_t* offset)
{
msgpack::object obj;
@@ -326,12 +327,12 @@ inline bool unpack(unpacked* result,
case UNPACK_SUCCESS:
result->get() = obj;
result->zone() = z;
- return false;
+ return;
case UNPACK_EXTRA_BYTES:
result->get() = obj;
result->zone() = z;
- return true;
+ return;
case UNPACK_CONTINUE:
throw unpack_error("insufficient bytes");
diff --git a/cpp/src/msgpack/vrefbuffer.h b/cpp/src/msgpack/vrefbuffer.h
index a08e0d0..123499d 100644
--- a/cpp/src/msgpack/vrefbuffer.h
+++ b/cpp/src/msgpack/vrefbuffer.h
@@ -19,6 +19,7 @@
#define MSGPACK_VREFBUFFER_H__
#include "msgpack/zone.h"
+#include <stdlib.h>
#ifndef _WIN32
#include <sys/uio.h>
@@ -29,19 +30,17 @@ struct iovec {
};
#endif
-#ifndef MSGPACK_VREFBUFFER_REF_SIZE
-#define MSGPACK_VREFBUFFER_REF_SIZE 32
-#endif
-
-#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE
-#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * @defgroup msgpack_vrefbuffer Vectored Referencing buffer
+ * @ingroup msgpack_buffer
+ * @{
+ */
+
struct msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk;
@@ -63,10 +62,21 @@ typedef struct msgpack_vrefbuffer {
} msgpack_vrefbuffer;
+#ifndef MSGPACK_VREFBUFFER_REF_SIZE
+#define MSGPACK_VREFBUFFER_REF_SIZE 32
+#endif
+
+#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE
+#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192
+#endif
+
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size);
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf);
+static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size);
+static inline void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf);
+
static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len);
static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref);
@@ -82,6 +92,25 @@ int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vref);
+/** @} */
+
+
+msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size)
+{
+ msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)malloc(sizeof(msgpack_vrefbuffer));
+ if(!msgpack_vrefbuffer_init(vbuf, ref_size, chunk_size)) {
+ free(vbuf);
+ return NULL;
+ }
+ return vbuf;
+}
+
+void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf)
+{
+ if(vbuf == NULL) { return; }
+ msgpack_vrefbuffer_destroy(vbuf);
+ free(vbuf);
+}
int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len)
{
diff --git a/cpp/src/msgpack/zbuffer.h b/cpp/src/msgpack/zbuffer.h
index 2a32206..abb9c50 100644
--- a/cpp/src/msgpack/zbuffer.h
+++ b/cpp/src/msgpack/zbuffer.h
@@ -23,30 +23,34 @@
#include <string.h>
#include <zlib.h>
-#ifndef MSGPACK_ZBUFFER_INIT_SIZE
-#define MSGPACK_ZBUFFER_INIT_SIZE 8192
-#endif
-
-#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE
-#define MSGPACK_ZBUFFER_RESERVE_SIZE 512
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * @defgroup msgpack_zbuffer Compressed buffer
+ * @ingroup msgpack_buffer
+ * @{
+ */
+
typedef struct msgpack_zbuffer {
z_stream stream;
char* data;
size_t init_size;
} msgpack_zbuffer;
+#ifndef MSGPACK_ZBUFFER_INIT_SIZE
+#define MSGPACK_ZBUFFER_INIT_SIZE 8192
+#endif
static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
int level, size_t init_size);
static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf);
+static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size);
+static inline void msgpack_zbuffer_free(msgpack_zbuffer* zbuf);
+
static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf);
static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf);
@@ -57,6 +61,10 @@ static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf);
static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf);
+#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE
+#define MSGPACK_ZBUFFER_RESERVE_SIZE 512
+#endif
+
static inline int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len);
static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf);
@@ -80,6 +88,23 @@ void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf)
free(zbuf->data);
}
+msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size)
+{
+ msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer));
+ if(!msgpack_zbuffer_init(zbuf, level, init_size)) {
+ free(zbuf);
+ return NULL;
+ }
+ return zbuf;
+}
+
+void msgpack_zbuffer_free(msgpack_zbuffer* zbuf)
+{
+ if(zbuf == NULL) { return; }
+ msgpack_zbuffer_destroy(zbuf);
+ free(zbuf);
+}
+
bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf)
{
size_t used = (char*)zbuf->stream.next_out - zbuf->data;
@@ -171,6 +196,8 @@ char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf)
return tmp;
}
+/** @} */
+
#ifdef __cplusplus
}
diff --git a/cpp/src/msgpack/zone.h b/cpp/src/msgpack/zone.h
index ce5be6d..0e811df 100644
--- a/cpp/src/msgpack/zone.h
+++ b/cpp/src/msgpack/zone.h
@@ -25,6 +25,12 @@ extern "C" {
#endif
+/**
+ * @defgroup msgpack_zone Memory zone
+ * @ingroup msgpack
+ * @{
+ */
+
typedef struct msgpack_zone_finalizer {
void (*func)(void* data);
void* data;
@@ -71,6 +77,7 @@ bool msgpack_zone_is_empty(msgpack_zone* zone);
void msgpack_zone_clear(msgpack_zone* zone);
+/** @} */
#ifndef MSGPACK_ZONE_ALIGN
diff --git a/cpp/src/unpack.c b/cpp/src/unpack.c
index 4a42526..0c21780 100644
--- a/cpp/src/unpack.c
+++ b/cpp/src/unpack.c
@@ -363,20 +363,46 @@ void msgpack_unpacker_reset(msgpack_unpacker* mpac)
mpac->parsed = 0;
}
+bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result)
+{
+ if(result->zone != NULL) {
+ msgpack_zone_free(result->zone);
+ }
+
+ int ret = msgpack_unpacker_execute(mpac);
+
+ if(ret <= 0) {
+ result->zone = NULL;
+ memset(&result->data, 0, sizeof(msgpack_object));
+ return false;
+ }
+
+ result->zone = msgpack_unpacker_release_zone(mpac);
+ result->data = msgpack_unpacker_data(mpac);
+ msgpack_unpacker_reset(mpac);
+
+ return true;
+}
+
msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off,
- msgpack_zone* z, msgpack_object* result)
+ msgpack_zone* result_zone, msgpack_object* result)
{
+ size_t noff = 0;
+ if(off != NULL) { noff = *off; }
+
+ if(len <= noff) {
+ // FIXME
+ return MSGPACK_UNPACK_CONTINUE;
+ }
+
template_context ctx;
template_init(&ctx);
- ctx.user.z = z;
+ ctx.user.z = result_zone;
ctx.user.referenced = false;
- size_t noff = 0;
- if(off != NULL) { noff = *off; }
-
int e = template_execute(&ctx, data, len, &noff);
if(e < 0) {
return MSGPACK_UNPACK_PARSE_ERROR;
@@ -397,3 +423,37 @@ msgpack_unpack(const char* data, size_t len, size_t* off,
return MSGPACK_UNPACK_SUCCESS;
}
+bool msgpack_unpack_next(msgpack_unpacked* result,
+ const char* data, size_t len, size_t* off)
+{
+ msgpack_unpacked_destroy(result);
+
+ size_t noff = 0;
+ if(off != NULL) { noff = *off; }
+
+ if(len <= noff) {
+ return false;
+ }
+
+ msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
+
+ template_context ctx;
+ template_init(&ctx);
+
+ ctx.user.z = z;
+ ctx.user.referenced = false;
+
+ int e = template_execute(&ctx, data, len, &noff);
+ if(e <= 0) {
+ msgpack_zone_free(z);
+ return false;
+ }
+
+ if(off != NULL) { *off = noff; }
+
+ result->zone = z;
+ result->data = template_data(&ctx);
+
+ return true;
+}
+
diff --git a/cpp/src/zone.c b/cpp/src/zone.c
index 85de765..8cc8b0d 100644
--- a/cpp/src/zone.c
+++ b/cpp/src/zone.c
@@ -214,6 +214,7 @@ msgpack_zone* msgpack_zone_new(size_t chunk_size)
void msgpack_zone_free(msgpack_zone* zone)
{
+ if(zone == NULL) { return; }
msgpack_zone_destroy(zone);
free(zone);
}