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

git-svn-id: file:///Users/frsyuki/project/msgpack-git/svn/x@67 5a5092ae-2292-43ba-b2d5-dcab9c1a2731
This commit is contained in:
frsyuki
2009-02-15 09:09:58 +00:00
parent 1222466a1c
commit 9923cf4daf
26 changed files with 1338 additions and 1116 deletions

View File

@@ -1,37 +1,35 @@
#include <iostream>
#include <string>
//#include <msgpack/unpack.hpp>
//#include <msgpack/pack.hpp>
#include <msgpack.hpp>
#include <sstream>
#include <memory>
using namespace msgpack;
class checker {
public:
void check(const char* d, size_t len, msgpack::object should) {
using msgpack::object;
template <typename T>
void check(const char* d, size_t len, T should) {
try {
std::cout << "----" << std::endl;
object o;
try {
o = msgpack::unpack(d, len, m_zone);
o = unpack(d, len, m_zone);
} catch (std::runtime_error& e) {
std::cout << should << std::endl;
std::cout << o << std::endl;
std::cout << "**" << e.what() << "**" << std::endl;
return;
}
std::cout << o << std::endl;
if(o != should) {
std::cout << "** TEST FAILED **" << std::endl;
}
try {
std::stringstream s;
msgpack::pack(s, o);
pack(should, s);
std::string str(s.str());
object ro = msgpack::unpack(str.data(), str.size(), m_zone);
object ro = unpack(str.data(), str.size(), m_zone);
std::cout << ro << std::endl;
if(ro != o) { throw std::runtime_error("NOT MATCH"); }
} catch (std::runtime_error& e) {
std::cout << "** REUNPACK FAILED **" << std::endl;
@@ -45,7 +43,7 @@ public:
m_zone.clear();
}
private:
msgpack::zone m_zone;
zone m_zone;
};
int main(void)
@@ -53,54 +51,48 @@ int main(void)
checker c;
{ // SimpleValue
msgpack::zone z;
const char d[] = {
0x93, 0xc0, 0xc2, 0xc3,
};
c.check(d, sizeof(d),
z.narray(
z.nnil(), z.nfalse(), z.ntrue()
type::make_tuple(
type::nil(), false, true
)
);
}
{ // Fixnum
msgpack::zone z;
const char d[] = {
0x92,
0x93, 0x00, 0x40, 0x7f,
0x93, 0xe0, 0xf0, 0xff,
};
c.check(d, sizeof(d),
z.narray(
z.narray(
z.nu8(0),
z.nu8(64),
z.nu8(127)
type::make_tuple(
type::make_tuple(
0, 64, 127
),
z.narray(
z.ni8(-32),
z.ni8(-16),
z.ni8(-1)
type::make_tuple(
-32, -16, -1
)
)
);
}
{ // FixArray
msgpack::zone z;
const char d[] = {
0x92,
0x90,
0x91,
0x91, 0xc0,
};
std::vector<int> empty;
c.check(d, sizeof(d),
z.narray(
z.narray(),
z.narray(
z.narray(
z.nnil()
type::make_tuple(
empty,
type::make_tuple(
type::make_tuple(
type::nil()
)
)
)
@@ -108,7 +100,6 @@ int main(void)
}
{ // FixRaw
msgpack::zone z;
const char d[] = {
0x94,
0xa0,
@@ -117,91 +108,84 @@ int main(void)
0xa3, 'd', 'e', 'f',
};
c.check(d, sizeof(d),
z.narray(
z.nraw_ref("", 0),
z.nraw_ref("a", 1),
z.nraw_ref("bc", 2),
z.nraw_ref("def", 3)
type::make_tuple(
std::string(""),
std::string("a"),
std::string("bc"),
type::raw_ref("def", 3)
)
);
}
static const uint16_t TASK_ARRAY = 100;
static char tarray[3];
static char traw[64];
static const unsigned TASK_ARRAY = 100;
static const unsigned TASK_REPEAT = 10;
std::vector<std::string> task;
// create task
{
static char traw[64];
memset(traw, 'a', sizeof(traw));
traw[0] = 0xda;
uint16_t n = htons(sizeof(traw)-3);
traw[1] = ((char*)&n)[0];
traw[2] = ((char*)&n)[1];
msgpack::zone z;
std::cout << msgpack::unpack(traw, sizeof(traw), z) << std::endl;;
}
{
tarray[0] = 0xdc;
uint16_t n = htons(TASK_ARRAY);
tarray[1] = ((char*)&n)[0];
tarray[2] = ((char*)&n)[1];
}
{
// write message
ssize_t total_bytes = 0;
std::stringstream stream;
for(unsigned q=0; q < 10; ++q) {
stream.write(tarray, sizeof(tarray));
total_bytes += sizeof(tarray);
for(uint16_t i=0; i < TASK_ARRAY; ++i) {
stream.write(traw, sizeof(traw));
total_bytes += sizeof(traw);
}
task.resize(TASK_ARRAY);
for(unsigned i=0; i < TASK_ARRAY; ++i) {
task[i] = std::string(traw, sizeof(traw));
}
}
stream.seekg(0);
// reserive message
std::stringstream stream;
// send message
{
for(unsigned i=0; i < TASK_REPEAT; ++i) {
pack(task, stream);
}
std::cout << "send " << stream.str().size() << " bytes" << std::endl;
}
ssize_t total_bytes = stream.str().size();
stream.seekg(0);
// reserive message
{
unsigned num_msg = 0;
static const size_t RESERVE_SIZE = 32;//*1024;
msgpack::unpacker upk;
std::auto_ptr<zone> pz(new zone());
unpacker pac(*pz);
while(stream.good() && total_bytes > 0) {
// 1. reserve buffer
upk.reserve_buffer(RESERVE_SIZE);
pac.reserve_buffer(RESERVE_SIZE);
// 2. read data to buffer() up to buffer_capacity() bytes
size_t sz = stream.readsome(
upk.buffer(),
upk.buffer_capacity());
pac.buffer(),
pac.buffer_capacity());
total_bytes -= sz;
std::cout << "read " << sz << " bytes to capacity "
<< upk.buffer_capacity() << " bytes"
<< pac.buffer_capacity() << " bytes"
<< std::endl;
// 3. specify the number of bytes actually copied
upk.buffer_consumed(sz);
pac.buffer_consumed(sz);
// 4. repeat execute() until it returns false
while( upk.execute() ) {
std::cout << "message parsed" << std::endl;
while( pac.execute() ) {
// 5.1. take out the parsed object
msgpack::object o = upk.data();
object o = pac.data();
// 5.2. the parsed object is valid until the zone is deleted
std::auto_ptr<msgpack::zone> pz(upk.release_zone());
std::cout << o << std::endl;
// do something using pz and o
std::cout << "message parsed: " << o << std::endl;
++num_msg;
// 5.3 re-initialize unpacker
upk.reset();
// 5.3 re-initialize unpacker with next zone */
pz.reset(new zone());
pac.reset(*pz);
}
}