summaryrefslogtreecommitdiff
path: root/cpp/unpack.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/unpack.hpp')
-rw-r--r--cpp/unpack.hpp48
1 files changed, 42 insertions, 6 deletions
diff --git a/cpp/unpack.hpp b/cpp/unpack.hpp
index 61ba781..df4a636 100644
--- a/cpp/unpack.hpp
+++ b/cpp/unpack.hpp
@@ -5,6 +5,10 @@
#include "msgpack/zone.hpp"
#include <stdexcept>
+#ifndef MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE
+#define MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE 8*1024
+#endif
+
namespace msgpack {
@@ -16,26 +20,58 @@ struct unpack_error : public std::runtime_error {
class unpacker {
public:
- unpacker(zone& z);
+ unpacker();
~unpacker();
+
public:
- size_t execute(const void* data, size_t len, size_t off);
- bool is_finished() { return m_finished; }
+ void reserve_buffer(size_t len);
+ void* buffer();
+ size_t buffer_capacity() const;
+ void buffer_consumed(size_t len);
+ bool execute();
+ zone* release_zone(); // never throw
object data();
void reset();
+
private:
+ zone* m_zone;
+
struct context;
context* m_ctx;
- zone& m_zone;
- bool m_finished;
+
+ void* m_buffer;
+ size_t m_used;
+ size_t m_free;
+ size_t m_off;
+ void expand_buffer(size_t len);
+
private:
- unpacker();
unpacker(const unpacker&);
+
public:
static object unpack(const void* data, size_t len, zone& z);
};
+inline void unpacker::reserve_buffer(size_t len)
+{
+ if(m_free >= len) { return; }
+ expand_buffer(len);
+}
+
+inline void* unpacker::buffer()
+ { return (void*)(((char*)m_buffer)+m_used); }
+
+inline size_t unpacker::buffer_capacity() const
+ { return m_free; }
+
+inline void unpacker::buffer_consumed(size_t len)
+{
+ m_used += len;
+ m_free -= len;
+}
+
+
inline object unpack(const void* data, size_t len, zone& z)
{
return unpacker::unpack(data, len, z);