root/lang/c/msgpack/trunk/cpp/unpack.hpp @ 18666

Revision 18666, 2.7 kB (checked in by frsyuki, 5 years ago)

lang/c/msgpack: C++ binding: support non-MessagePack? message that follows after MessagePack? message

Line 
1#ifndef MSGPACK_UNPACK_HPP__
2#define MSGPACK_UNPACK_HPP__
3
4#include "msgpack/object.hpp"
5#include "msgpack/zone.hpp"
6#include <stdexcept>
7
8#ifndef MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE
9#define MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE 8*1024
10#endif
11
12namespace msgpack {
13
14
15struct unpack_error : public std::runtime_error {
16        unpack_error(const std::string& msg) :
17                std::runtime_error(msg) { }
18};
19
20
21class unpacker {
22public:
23        unpacker();
24        ~unpacker();
25
26public:
27        /*! 1. reserve buffer. at least `len' bytes of capacity will be ready */
28        void reserve_buffer(size_t len);
29
30        /*! 2. read data to the buffer() up to buffer_capacity() bytes */
31        void* buffer();
32        size_t buffer_capacity() const;
33
34        /*! 3. specify the number of bytes actually copied */
35        void buffer_consumed(size_t len);
36
37        /*! 4. repeat execute() until it retunrs false */
38        bool execute();
39
40        /*! 5.1. if execute() returns true, take out the parsed object */
41        object data();
42
43        /*! 5.2. the parsed object is valid until the zone is deleted */
44        // Note that once release_zone() from unpacker, you must delete it
45        // otherwise the memrory will leak.
46        zone* release_zone();
47
48        /*! 5.3. after release_zone(), re-initialize unpacker */
49        void reset();
50
51public:
52        // These functions are usable when non-MessagePack message follows after
53        // MessagePack message.
54        // Note that there are no parsed buffer when execute() returned true.
55
56        /*! get address of buffer that is not parsed */
57        void* nonparsed_buffer();
58        size_t nonparsed_size() const;
59
60        /*! get the number of bytes that is already parsed */
61        size_t parsed_size() const;
62
63        /*! remove unparsed buffer from unpacker */
64        // Note that reset() leaves non-parsed buffer.
65        void remove_nonparsed_buffer();
66
67private:
68        zone* m_zone;
69
70        struct context;
71        context* m_ctx;
72
73        void* m_buffer;
74        size_t m_used;
75        size_t m_free;
76        size_t m_off;
77        void expand_buffer(size_t len);
78
79private:
80        unpacker(const unpacker&);
81
82public:
83        static object unpack(const void* data, size_t len, zone& z);
84};
85
86
87inline void unpacker::reserve_buffer(size_t len)
88{
89        if(m_free >= len) { return; }
90        expand_buffer(len);
91}
92
93inline void* unpacker::buffer()
94        { return (void*)(((char*)m_buffer)+m_used); }
95
96inline size_t unpacker::buffer_capacity() const
97        { return m_free; }
98
99inline void unpacker::buffer_consumed(size_t len)
100{
101        m_used += len;
102        m_free -= len;
103}
104
105
106inline void* unpacker::nonparsed_buffer()
107        { return (void*)(((char*)m_buffer)+m_off); }
108
109inline size_t unpacker::nonparsed_size() const
110        { return m_used - m_off; }
111
112inline size_t unpacker::parsed_size() const
113        { return m_off; }
114
115inline void unpacker::remove_nonparsed_buffer()
116        { m_used = m_off; }
117
118
119inline object unpack(const void* data, size_t len, zone& z)
120{
121        return unpacker::unpack(data, len, z);
122}
123
124
125}  // namespace msgpack
126
127#endif /* msgpack/unpack.hpp */
128
Note: See TracBrowser for help on using the browser.