root/lang/c/msgpack/trunk/cpp/test.cpp @ 19271

Revision 19271, 3.7 kB (checked in by frsyuki, 5 years ago)

lang/c/msgpack: reimplemented C++ binding with template-based static resolution design

Line 
1#include <iostream>
2#include <string>
3#include <msgpack.hpp>
4#include <sstream>
5#include <memory>
6
7using namespace msgpack;
8
9class checker {
10public:
11        template <typename T>
12        void check(const char* d, size_t len, T should) {
13                try {
14                        std::cout << "----" << std::endl;
15
16                        object o;
17                        try {
18                                o = unpack(d, len, m_zone);
19                        } catch (std::runtime_error& e) {
20                                std::cout << o << std::endl;
21                                std::cout << "**" << e.what() << "**" << std::endl;
22                                return;
23                        }
24
25                        std::cout << o << std::endl;
26
27                        try {
28                                std::stringstream s;
29                                pack(should, s);
30                                std::string str(s.str());
31                                object ro = unpack(str.data(), str.size(), m_zone);
32                                std::cout << ro << std::endl;
33                                if(ro != o) { throw std::runtime_error("NOT MATCH"); }
34                        } catch (std::runtime_error& e) {
35                                std::cout << "** REUNPACK FAILED **" << std::endl;
36                                std::cout << e.what() << std::endl;
37                        } catch (...) {
38                                std::cout << "** REUNPACK FAILED **" << std::endl;
39                                std::cout << "unknown error" << std::endl;
40                        }
41
42                } catch (...) { m_zone.clear(); throw; }
43                m_zone.clear();
44        }
45private:
46        zone m_zone;
47};
48
49int main(void)
50{
51        checker c;
52
53        {  // SimpleValue
54                const char d[] = {
55                        0x93, 0xc0, 0xc2, 0xc3,
56                };
57                c.check(d, sizeof(d),
58                        type::make_tuple(
59                                type::nil(), false, true
60                        )
61                );
62        }
63
64        {  // Fixnum
65                const char d[] = {
66                        0x92,
67                                0x93, 0x00, 0x40, 0x7f,
68                                0x93, 0xe0, 0xf0, 0xff,
69                };
70                c.check(d, sizeof(d),
71                        type::make_tuple(
72                                type::make_tuple(
73                                        0, 64, 127
74                                ),
75                                type::make_tuple(
76                                        -32, -16, -1
77                                )
78                        )
79                );
80        }
81
82        {  // FixArray
83                const char d[] = {
84                        0x92,
85                                0x90,
86                                0x91,
87                                        0x91, 0xc0,
88                };
89                std::vector<int> empty;
90                c.check(d, sizeof(d),
91                        type::make_tuple(
92                                empty,
93                                type::make_tuple(
94                                        type::make_tuple(
95                                                type::nil()
96                                        )
97                                )
98                        )
99                );
100        }
101
102        {  // FixRaw
103                const char d[] = {
104                        0x94,
105                                0xa0,
106                                0xa1, 'a',
107                                0xa2, 'b', 'c',
108                                0xa3, 'd', 'e', 'f',
109                };
110                c.check(d, sizeof(d),
111                        type::make_tuple(
112                                std::string(""),
113                                std::string("a"),
114                                std::string("bc"),
115                                type::raw_ref("def", 3)
116                        )
117                );
118        }
119
120
121        static const unsigned TASK_ARRAY = 100;
122        static const unsigned TASK_REPEAT = 10;
123        std::vector<std::string> task;
124
125        // create task
126        {
127                static char traw[64];
128                memset(traw, 'a', sizeof(traw));
129       
130                task.resize(TASK_ARRAY);
131                for(unsigned i=0; i < TASK_ARRAY; ++i) {
132                        task[i] = std::string(traw, sizeof(traw));
133                }
134        }
135
136
137        std::stringstream stream;
138
139        // send message
140        {
141                for(unsigned i=0; i < TASK_REPEAT; ++i) {
142                        pack(task, stream);
143                }
144                std::cout << "send " << stream.str().size() << " bytes" << std::endl;
145        }
146
147        ssize_t total_bytes = stream.str().size();
148        stream.seekg(0);
149
150        // reserive message
151        {
152                unsigned num_msg = 0;
153                static const size_t RESERVE_SIZE = 32;//*1024;
154
155                std::auto_ptr<zone> pz(new zone());
156
157                unpacker pac(*pz);
158
159                while(stream.good() && total_bytes > 0) {
160
161                        // 1. reserve buffer
162                        pac.reserve_buffer(RESERVE_SIZE);
163
164                        // 2. read data to buffer() up to buffer_capacity() bytes
165                        size_t sz = stream.readsome(
166                                        pac.buffer(),
167                                        pac.buffer_capacity());
168
169                        total_bytes -= sz;
170                        std::cout << "read " << sz << " bytes to capacity "
171                                        << pac.buffer_capacity() << " bytes"
172                                        << std::endl;
173
174                        // 3. specify the number of  bytes actually copied
175                        pac.buffer_consumed(sz);
176
177                        // 4. repeat execute() until it returns false
178                        while( pac.execute() ) {
179                                // 5.1. take out the parsed object
180                                object o = pac.data();
181
182                                // do something using pz and o
183                                std::cout << "message parsed: " << o << std::endl;
184                                ++num_msg;
185
186                                // 5.3 re-initialize unpacker with next zone */
187                                pz.reset(new zone());
188                                pac.reset(*pz);
189                        }
190
191                }
192
193                std::cout << "stream finished" << std::endl;
194                std::cout << num_msg << " messages reached" << std::endl;
195        }
196
197        return 0;
198}
199
Note: See TracBrowser for help on using the browser.