A couple of people have asked for an example of how to serialize to and from a
file with Thrift. I wrote a C++ test program quite a while ago that does that.
I recently tried to attach it, but the attachment got stripped. Since it was
just one file, and it's really not very big, I thought I'd just post the code.
(I also discovered that I had added some extra test code that is very specific
to our environment. This version has that code stripped out, but the test has
sort of moved on from this original "how does this work?" version.)
Here it is. It uses the structures defined in test/ThriftTest.thrift, and you
can use different transport types, although I'm not sure that DENSE works these
days. Using JSON is useful because you can look at the file with a text editor.
Obviously, you need to change the path "/Users/rmanbert/TFileTestData" to
something that works for you. (It's hardcoded twice - once for write and once
for read.)
I also need to mention that we are running on an old version of Thrift, so I
don't know what changes you might need to make for the current version.
I hope this is useful to someone,
Rush
-----------------------------------------------------------------------------------------
#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <protocol/TBinaryProtocol.h>
#include <protocol/TDenseProtocol.h>
#include <protocol/TJSONProtocol.h>
#include <transport/TTransportUtils.h>
#include <transport/TFDTransport.h>
#include <boost/shared_ptr.hpp>
#include "ThriftTest.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
// Define which protocol to use
#define JSON
//#define BINARY
//#define DENSE
// Define which tests to run
#define Test_Struct
#define Test_NestedStruct
#define Test_Insanity
using namespace boost;
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace thrift::test;
int main(int argc, char * const argv[]) {
int fd = open("/Users/rmanbert/TFileTestData", O_CREAT | O_TRUNC | O_WRONLY,
S_IRUSR | S_IWUSR | S_IXUSR);
if (-1 == fd)
{
printf("ERROR: Open/create for write failed!\n");
return -1;
}
shared_ptr<TFDTransport> innerTransport(new TFDTransport(fd));
shared_ptr<TBufferedTransport> transport(new
TBufferedTransport(innerTransport));
#if defined(BINARY)
shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
#elif defined(DENSE)
shared_ptr<TDenseProtocol> protocol(new TDenseProtocol(transport));
#elif defined(JSON)
shared_ptr<TJSONProtocol> protocol(new TJSONProtocol(transport));
#endif
transport->open();
#ifdef Test_Struct
/**
* STRUCT TEST
*/
printf("testStruct({\"Zero\", 1, -3, -5})\n");
Xtruct out;
out.string_thing = "Zero";
out.byte_thing = 1;
out.i32_thing = -3;
out.i64_thing = -5;
#if defined(DENSE)
// protocol->setTypeSpec(out.local_reflection);
#endif
out.write(protocol.get());
#endif // Test_Struct
#ifdef Test_NestedStruct
/**
* NESTED STRUCT TEST
*/
printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}\n");
Xtruct2 out2;
out2.byte_thing = 1;
out2.struct_thing = out;
out2.i32_thing = 5;
#if defined(DENSE)
// protocol->setTypeSpec(out2.local_reflection);
#endif
out2.write(protocol.get());
#endif // Test_NestedStruct
#ifdef Test_Insanity
/**
* INSANITY TEST
*/
printf("test Insanity\n");
Insanity insane;
insane.userMap.insert(make_pair(FIVE, 5000));
insane.userMap.insert(make_pair(THREE, 3333));
Xtruct truck;
truck.string_thing = "Truck";
truck.byte_thing = 8;
truck.i32_thing = 8;
truck.i64_thing = 8;
insane.xtructs.push_back(truck);
truck.string_thing = "Tractor";
truck.byte_thing = 88;
truck.i32_thing = 12345;
truck.i64_thing = 32475862891754ll;
insane.xtructs.push_back(truck);
truck.string_thing = "Freight Train";
truck.byte_thing = 255;
truck.i32_thing = ~0;
truck.i64_thing = ~0;
insane.xtructs.push_back(truck);
#if defined(DENSE)
// protocol->setTypeSpec(insane.local_reflection);
#endif
insane.write(protocol.get());
#endif // Test_Insanity
transport->close();
fd = open("/Users/rmanbert/TFileTestData", O_RDONLY);
if (-1 == fd)
{
printf("ERROR: Open for read failed!\n");
return -1;
}
shared_ptr<TFDTransport> innerTransport2(new TFDTransport(fd));
shared_ptr<TBufferedTransport> transport2(new
TBufferedTransport(innerTransport2));
#if defined(BINARY)
shared_ptr<TBinaryProtocol> protocol2(new TBinaryProtocol(transport2));
#elif defined(DENSE)
shared_ptr<TDenseProtocol> protocol2(new TDenseProtocol(transport2));
#elif defined(JSON)
shared_ptr<TJSONProtocol> protocol2(new TJSONProtocol(transport2));
#endif
transport2->open();
#ifdef Test_Struct
{
printf("Read Xtruct test:\n");
Xtruct in;
# if defined(DENSE)
//protocol2->setTypeSpec(in.local_reflection);
# endif
in.read(protocol2.get());
if (in != out)
{
printf ("ERROR: Xtruct read in does not match wat was
written!\n");
}
else
{
printf ("Structure read from file matches the
original.\n");
}
}
#endif // Test_Struct
#ifdef Test_NestedStruct
{
printf("Read Xtruct2 test:\n");
Xtruct2 in2;
# if defined(DENSE)
//protocol2->setTypeSpec(in2.local_reflection);
# endif
in2.read(protocol2.get());
if (in2 != out2)
{
printf ("ERROR: Xtruct2 read in does not match wat was
written!\n");
}
else
{
printf ("Structure read from file matches the
original.\n");
}
}
#endif // Test_NestedStruct
#ifdef Test_Insanity
{
printf("Read Insanity test:\n");
Insanity insane2;
# if defined(DENSE)
//protocol2->setTypeSpec(insane2.local_reflection);
# endif
insane2.read(protocol2.get());
if (insane2 != insane)
{
printf ("ERROR: Insanity read in does not match wat was
written!\n");
}
else
{
printf ("Structure read from file matches the
original.\n");
}
}
#endif // Test_Insanity
printf("\nAll tests done.\n");
return 0;
}