mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-16 18:56:54 +02:00
add examples
git-svn-id: file:///Users/frsyuki/project/msgpack-git/svn/x@84 5a5092ae-2292-43ba-b2d5-dcab9c1a2731
This commit is contained in:
86
example/protocol.cc
Normal file
86
example/protocol.cc
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace myprotocol {
|
||||||
|
using namespace msgpack::type;
|
||||||
|
using msgpack::define;
|
||||||
|
|
||||||
|
struct Get : define< tuple<uint32_t, std::string> > {
|
||||||
|
Get() { }
|
||||||
|
Get(uint32_t f, const std::string& k) :
|
||||||
|
define_type(msgpack_type(f, k)) { }
|
||||||
|
uint32_t& flags() { return get<0>(); }
|
||||||
|
std::string& key() { return get<1>(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Put : define< tuple<uint32_t, std::string, raw_ref> > {
|
||||||
|
Put() { }
|
||||||
|
Put(uint32_t f, const std::string& k, const char* valref, size_t vallen) :
|
||||||
|
define_type(msgpack_type( f, k, raw_ref(valref,vallen) )) { }
|
||||||
|
uint32_t& flags() { return get<0>(); }
|
||||||
|
std::string& key() { return get<1>(); }
|
||||||
|
raw_ref& value() { return get<2>(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MultiGet : define< std::vector<Get> > {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// send Get request
|
||||||
|
std::stringstream stream;
|
||||||
|
{
|
||||||
|
myprotocol::Get req;
|
||||||
|
req.flags() = 0;
|
||||||
|
req.key() = "key0";
|
||||||
|
msgpack::pack(stream, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.seekg(0);
|
||||||
|
|
||||||
|
// receive Get request
|
||||||
|
{
|
||||||
|
std::string buffer(stream.str());
|
||||||
|
|
||||||
|
msgpack::zone mempool;
|
||||||
|
msgpack::object o =
|
||||||
|
msgpack::unpack(buffer.data(), buffer.size(), mempool);
|
||||||
|
|
||||||
|
myprotocol::Get req;
|
||||||
|
msgpack::convert(req, o);
|
||||||
|
std::cout << "received: " << o << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream.str("");
|
||||||
|
|
||||||
|
|
||||||
|
// send MultiGet request
|
||||||
|
{
|
||||||
|
myprotocol::MultiGet req;
|
||||||
|
req.push_back( myprotocol::Get(1, "key1") );
|
||||||
|
req.push_back( myprotocol::Get(2, "key2") );
|
||||||
|
req.push_back( myprotocol::Get(3, "key3") );
|
||||||
|
msgpack::pack(stream, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.seekg(0);
|
||||||
|
|
||||||
|
// receive MultiGet request
|
||||||
|
{
|
||||||
|
std::string buffer(stream.str());
|
||||||
|
|
||||||
|
msgpack::zone mempool;
|
||||||
|
msgpack::object o =
|
||||||
|
msgpack::unpack(buffer.data(), buffer.size(), mempool);
|
||||||
|
|
||||||
|
myprotocol::MultiGet req;
|
||||||
|
msgpack::convert(req, o);
|
||||||
|
std::cout << "received: " << o << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
31
example/simple.cc
Normal file
31
example/simple.cc
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// this is target object
|
||||||
|
msgpack::type::tuple<int, bool, std::string> src(1, true, "example");
|
||||||
|
|
||||||
|
// any classes that implements write(const char*,size_t) can be a buffer
|
||||||
|
std::stringstream buffer;
|
||||||
|
msgpack::pack(buffer, src);
|
||||||
|
|
||||||
|
// send the buffer ...
|
||||||
|
buffer.seekg(0);
|
||||||
|
|
||||||
|
// deserialize the buffer into msgpack::object type
|
||||||
|
msgpack::zone mempool;
|
||||||
|
std::string str(buffer.str());
|
||||||
|
msgpack::object deserialized =
|
||||||
|
msgpack::unpack(str.data(), str.size(), mempool);
|
||||||
|
|
||||||
|
// msgpack::object supports ostream
|
||||||
|
std::cout << deserialized << std::endl;
|
||||||
|
|
||||||
|
// convert msgpack::object type into the original type
|
||||||
|
msgpack::type::tuple<int, bool, std::string> dst;
|
||||||
|
msgpack::convert(dst, deserialized);
|
||||||
|
}
|
||||||
|
|
5
example/simple.rb
Normal file
5
example/simple.rb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
require 'msgpack'
|
||||||
|
|
||||||
|
serialized = [1, -1, true, false, nil, {"key" => "value"}].to_msgpack
|
||||||
|
p MessagePack.unpack(serialized)
|
||||||
|
|
131
example/stream.cc
Normal file
131
example/stream.cc
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
class Server {
|
||||||
|
public:
|
||||||
|
Server(int sock) : m_sock(sock) { }
|
||||||
|
~Server() { }
|
||||||
|
|
||||||
|
typedef std::auto_ptr<msgpack::zone> auto_zone;
|
||||||
|
|
||||||
|
void socket_readable()
|
||||||
|
{
|
||||||
|
m_pac.reserve_buffer(1024);
|
||||||
|
|
||||||
|
ssize_t count =
|
||||||
|
read(m_sock, m_pac.buffer(), m_pac.buffer_capacity());
|
||||||
|
|
||||||
|
if(count < 0) {
|
||||||
|
if(errno == EAGAIN || errno == EINTR) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error(strerror(errno));
|
||||||
|
}
|
||||||
|
} else if(count == 0) {
|
||||||
|
throw std::runtime_error("connection closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pac.buffer_consumed(count);
|
||||||
|
|
||||||
|
while(m_pac.execute()) {
|
||||||
|
msgpack::object msg = m_pac.data();
|
||||||
|
|
||||||
|
auto_zone life( m_pac.release_zone() );
|
||||||
|
|
||||||
|
m_pac.reset();
|
||||||
|
|
||||||
|
process_message(msg, life);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void process_message(msgpack::object msg, auto_zone& life)
|
||||||
|
{
|
||||||
|
std::cout << "message reached: " << msg << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_sock;
|
||||||
|
msgpack::unpacker m_pac;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void* run_server(void* arg)
|
||||||
|
try {
|
||||||
|
Server* srv = reinterpret_cast<Server*>(arg);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
srv->socket_readable();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
std::cerr << "error while processing client packet: "
|
||||||
|
<< e.what() << std::endl;
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr << "error while processing client packet: "
|
||||||
|
<< "unknown error" << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct fwriter {
|
||||||
|
fwriter(int fd) : m_fp( fdopen(fd, "w") ) { }
|
||||||
|
|
||||||
|
void write(const char* buf, size_t buflen)
|
||||||
|
{
|
||||||
|
size_t count = fwrite(buf, buflen, 1, m_fp);
|
||||||
|
//if(fwrite(buf, buflen, 1, m_fp) < 1) {
|
||||||
|
if(count < 1) {
|
||||||
|
std::cout << buflen << std::endl;
|
||||||
|
std::cout << count << std::endl;
|
||||||
|
throw std::runtime_error(strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush() { fflush(m_fp); }
|
||||||
|
|
||||||
|
void close() { fclose(m_fp); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE* m_fp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int pair[2];
|
||||||
|
pipe(pair);
|
||||||
|
|
||||||
|
// run server thread
|
||||||
|
Server srv(pair[0]);
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_create(&thread, NULL,
|
||||||
|
run_server, reinterpret_cast<void*>(&srv));
|
||||||
|
|
||||||
|
// client thread:
|
||||||
|
fwriter writer(pair[1]);
|
||||||
|
|
||||||
|
typedef msgpack::type::tuple<std::string, std::string, std::string> put_t;
|
||||||
|
typedef msgpack::type::tuple<std::string, std::string> get_t;
|
||||||
|
|
||||||
|
put_t req1("put", "apple", "red");
|
||||||
|
put_t req2("put", "lemon", "yellow");
|
||||||
|
get_t req3("get", "apple");
|
||||||
|
msgpack::pack(writer, req1);
|
||||||
|
msgpack::pack(writer, req2);
|
||||||
|
msgpack::pack(writer, req3);
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
pthread_join(thread, NULL);
|
||||||
|
}
|
||||||
|
|
67
example/stream.rb
Normal file
67
example/stream.rb
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
require 'msgpack'
|
||||||
|
|
||||||
|
class Server
|
||||||
|
def initialize(sock)
|
||||||
|
@sock = sock
|
||||||
|
@pk = MessagePack::Unpacker.new
|
||||||
|
@buffer = ''
|
||||||
|
@nread = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
while true
|
||||||
|
begin
|
||||||
|
data = @sock.sysread(1024)
|
||||||
|
rescue
|
||||||
|
puts "connection closed (#{$!})"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
receive_data(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def receive_data(data)
|
||||||
|
@buffer << data
|
||||||
|
|
||||||
|
while true
|
||||||
|
@nread = @pk.execute(@buffer, @nread)
|
||||||
|
|
||||||
|
if @pk.finished?
|
||||||
|
msg = @pk.data
|
||||||
|
process_message(msg)
|
||||||
|
|
||||||
|
@pk.reset
|
||||||
|
@buffer.slice!(0, @nread)
|
||||||
|
@nread = 0
|
||||||
|
next unless @buffer.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue
|
||||||
|
puts "error while processing client packet: #{$!}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_message(msg)
|
||||||
|
puts "message reached: #{msg.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
rpipe, wpipe = IO.pipe
|
||||||
|
|
||||||
|
# run server thread
|
||||||
|
thread = Thread.new(Server.new(rpipe)) {|srv|
|
||||||
|
srv.run
|
||||||
|
}
|
||||||
|
|
||||||
|
# client thread:
|
||||||
|
wpipe.write ["put", "apple", "red"].to_msgpack
|
||||||
|
wpipe.write ["put", "lemon", "yellow"].to_msgpack
|
||||||
|
wpipe.write ["get", "apple"].to_msgpack
|
||||||
|
wpipe.close
|
||||||
|
|
||||||
|
thread.join
|
||||||
|
|
Reference in New Issue
Block a user