mirror of
https://github.com/tmate-io/tmate.git
synced 2024-12-04 22:11:31 +01:00
134 lines
2.4 KiB
C++
134 lines
2.4 KiB
C++
|
//
|
||
|
// MessagePack cross-language test tool
|
||
|
//
|
||
|
// $ cd ../cpp && ./configure && make && make install
|
||
|
// or
|
||
|
// $ port install msgpack # MacPorts
|
||
|
//
|
||
|
// $ g++ -Wall -lmsgpack crosslang.cc
|
||
|
//
|
||
|
#include <msgpack.hpp>
|
||
|
#include <iostream>
|
||
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
static int run(int infd, int outfd)
|
||
|
try {
|
||
|
msgpack::unpacker pac;
|
||
|
|
||
|
while(true) {
|
||
|
pac.reserve_buffer(32*1024);
|
||
|
|
||
|
ssize_t count =
|
||
|
read(infd, pac.buffer(), pac.buffer_capacity());
|
||
|
|
||
|
if(count <= 0) {
|
||
|
if(count == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
if(errno == EAGAIN || errno == EINTR) {
|
||
|
continue;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
pac.buffer_consumed(count);
|
||
|
|
||
|
msgpack::unpacked result;
|
||
|
while(pac.next(&result)) {
|
||
|
msgpack::sbuffer sbuf;
|
||
|
msgpack::pack(sbuf, result.get());
|
||
|
|
||
|
const char* p = sbuf.data();
|
||
|
const char* const pend = p + sbuf.size();
|
||
|
while(p < pend) {
|
||
|
ssize_t bytes = write(outfd, p, pend-p);
|
||
|
|
||
|
if(bytes <= 0) {
|
||
|
if(count == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
if(errno == EAGAIN || errno == EINTR) {
|
||
|
continue;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
p += bytes;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
} catch (std::exception& e) {
|
||
|
std::cerr << e.what() << std::endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static void usage(const char* prog)
|
||
|
{
|
||
|
printf(
|
||
|
"Usage: %s [in-file] [out-file]\n"
|
||
|
"\n"
|
||
|
"This tool is for testing of MessagePack implementation.\n"
|
||
|
"This does following behavior:\n"
|
||
|
"\n"
|
||
|
" 1. Reads objects serialized by MessagePack from <in-file> (default: stdin)\n"
|
||
|
" 2. Re-serializes the objects using C++ implementation of MessagePack (Note that C++ implementation is considered valid)\n"
|
||
|
" 3. Writes the re-serialized objects into <out-file> (default: stdout)\n"
|
||
|
"\n"
|
||
|
, prog);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char* argv[])
|
||
|
{
|
||
|
int infd = 0;
|
||
|
int outfd = 1;
|
||
|
|
||
|
if(argc < 1 || argc > 3) {
|
||
|
usage(argv[0]);
|
||
|
}
|
||
|
|
||
|
for(int i=1; i < argc; ++i) {
|
||
|
if(strlen(argv[i]) > 1 && argv[i][0] == '-') {
|
||
|
usage(argv[0]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(argc >= 2) {
|
||
|
const char* fname = argv[1];
|
||
|
if(strcmp(fname, "-") != 0) {
|
||
|
infd = open(fname, O_RDONLY);
|
||
|
if(infd < 0) {
|
||
|
perror("can't open input file");
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(argc >= 3) {
|
||
|
const char* fname = argv[2];
|
||
|
if(strcmp(fname, "-") != 0) {
|
||
|
outfd = open(fname, O_WRONLY | O_CREAT| O_TRUNC, 0666);
|
||
|
if(outfd < 0) {
|
||
|
perror("can't open output file");
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int code = run(infd, outfd);
|
||
|
|
||
|
close(infd);
|
||
|
close(outfd);
|
||
|
|
||
|
return code;
|
||
|
}
|
||
|
|