2 ../compiler/cpp/thrift -cpp -dense DebugProtoTest.thrift
3 ../compiler/cpp/thrift -cpp -dense OptionalRequiredTest.thrift
4 g++ -Wall -g -I../lib/cpp/src -I/usr/local/include/boost-1_33_1 \
5 gen-cpp/OptionalRequiredTest_types.cpp \
6 gen-cpp/DebugProtoTest_types.cpp \
7 DenseProtoTest.cpp ../lib/cpp/.libs/libthrift.a -o DenseProtoTest
11 // I do this to reach into the guts of TDenseProtocol. Sorry.
12 #define private public
21 #include "gen-cpp/DebugProtoTest_types.h"
22 #include "gen-cpp/OptionalRequiredTest_types.h"
23 #include <protocol/TDenseProtocol.h>
24 #include <transport/TTransportUtils.h>
27 // Can't use memcmp here. GCC is too smart.
28 bool my_memeq(const char* str1
, const char* str2
, int len
) {
29 for (int i
= 0; i
< len
; i
++) {
30 if (str1
[i
] != str2
[i
]) {
42 using boost::shared_ptr
;
43 using namespace thrift::test
;
44 using namespace facebook::thrift::transport
;
45 using namespace facebook::thrift::protocol
;
52 ooe
.integer16
= 27000;
53 ooe
.integer32
= 1<<24;
54 ooe
.integer64
= (uint64_t)6000 * 1000 * 1000;
55 ooe
.double_precision
= M_PI
;
56 ooe
.some_characters
= "Debug THIS!";
57 ooe
.zomg_unicode
= "\xd7\n\a\t";
59 //cout << facebook::thrift::ThriftDebugString(ooe) << endl << endl;
64 n
.my_ooe
.integer16
= 16;
65 n
.my_ooe
.integer32
= 32;
66 n
.my_ooe
.integer64
= 64;
67 n
.my_ooe
.double_precision
= (std::sqrt(5)+1)/2;
68 n
.my_ooe
.some_characters
= ":R (me going \"rrrr\")";
69 n
.my_ooe
.zomg_unicode
= "\xd3\x80\xe2\x85\xae\xce\x9d\x20"
70 "\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"
71 "\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80\xbc";
72 n
.my_bonk
.type
= 31337;
73 n
.my_bonk
.message
= "I am a bonk... xor!";
75 //cout << facebook::thrift::ThriftDebugString(n) << endl << endl;
80 hm
.big
.push_back(ooe
);
81 hm
.big
.push_back(n
.my_ooe
);
82 hm
.big
[0].a_bite
= 0x22;
83 hm
.big
[1].a_bite
= 0x33;
85 std::vector
<std::string
> stage1
;
86 stage1
.push_back("and a one");
87 stage1
.push_back("and a two");
88 hm
.contain
.insert(stage1
);
90 stage1
.push_back("then a one, two");
91 stage1
.push_back("three!");
92 stage1
.push_back("FOUR!!");
93 hm
.contain
.insert(stage1
);
95 hm
.contain
.insert(stage1
);
97 std::vector
<Bonk
> stage2
;
98 hm
.bonks
["nothing"] = stage2
;
99 stage2
.resize(stage2
.size()+1);
100 stage2
.back().type
= 1;
101 stage2
.back().message
= "Wait.";
102 stage2
.resize(stage2
.size()+1);
103 stage2
.back().type
= 2;
104 stage2
.back().message
= "What?";
105 hm
.bonks
["something"] = stage2
;
107 stage2
.resize(stage2
.size()+1);
108 stage2
.back().type
= 3;
109 stage2
.back().message
= "quoth";
110 stage2
.resize(stage2
.size()+1);
111 stage2
.back().type
= 4;
112 stage2
.back().message
= "the raven";
113 stage2
.resize(stage2
.size()+1);
114 stage2
.back().type
= 5;
115 stage2
.back().message
= "nevermore";
116 hm
.bonks
["poe"] = stage2
;
118 //cout << facebook::thrift::ThriftDebugString(hm) << endl << endl;
120 shared_ptr
<TMemoryBuffer
> buffer(new TMemoryBuffer());
121 shared_ptr
<TDenseProtocol
> proto(new TDenseProtocol(buffer
));
122 proto
->setTypeSpec(HolyMoley::local_reflection
);
124 hm
.write(proto
.get());
126 hm2
.read(proto
.get());
131 // Let's test out the variable-length ints, shall we?
133 #define checkout(i, c) { \
134 buffer->resetBuffer(); \
135 proto->vlqWrite(i); \
136 proto->getTransport()->flush(); \
137 assert(my_memeq(buffer->getBufferAsString().data(), c, sizeof(c)-1)); \
138 proto->vlqRead(vlq); \
142 checkout(0x00000000, "\x00");
143 checkout(0x00000040, "\x40");
144 checkout(0x0000007F, "\x7F");
145 checkout(0x00000080, "\x81\x00");
146 checkout(0x00002000, "\xC0\x00");
147 checkout(0x00003FFF, "\xFF\x7F");
148 checkout(0x00004000, "\x81\x80\x00");
149 checkout(0x00100000, "\xC0\x80\x00");
150 checkout(0x001FFFFF, "\xFF\xFF\x7F");
151 checkout(0x00200000, "\x81\x80\x80\x00");
152 checkout(0x08000000, "\xC0\x80\x80\x00");
153 checkout(0x0FFFFFFF, "\xFF\xFF\xFF\x7F");
154 checkout(0x10000000, "\x81\x80\x80\x80\x00");
155 checkout(0x20000000, "\x82\x80\x80\x80\x00");
156 checkout(0x1FFFFFFF, "\x81\xFF\xFF\xFF\x7F");
157 checkout(0xFFFFFFFF, "\x8F\xFF\xFF\xFF\x7F");
159 checkout(0x0000000100000000ull
, "\x90\x80\x80\x80\x00");
160 checkout(0x0000000200000000ull
, "\xA0\x80\x80\x80\x00");
161 checkout(0x0000000300000000ull
, "\xB0\x80\x80\x80\x00");
162 checkout(0x0000000700000000ull
, "\xF0\x80\x80\x80\x00");
163 checkout(0x00000007F0000000ull
, "\xFF\x80\x80\x80\x00");
164 checkout(0x00000007FFFFFFFFull
, "\xFF\xFF\xFF\xFF\x7F");
165 checkout(0x0000000800000000ull
, "\x81\x80\x80\x80\x80\x00");
166 checkout(0x1FFFFFFFFFFFFFFFull
, "\x9F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
167 checkout(0x7FFFFFFFFFFFFFFFull
, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
168 checkout(0xFFFFFFFFFFFFFFFFull
, "\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
170 // Test out the slow path with a TBufferedTransport.
171 shared_ptr
<TBufferedTransport
> buff_trans(new TBufferedTransport(buffer
, 3));
172 proto
.reset(new TDenseProtocol(buff_trans
));
173 checkout(0x0000000100000000ull
, "\x90\x80\x80\x80\x00");
174 checkout(0x0000000200000000ull
, "\xA0\x80\x80\x80\x00");
175 checkout(0x0000000300000000ull
, "\xB0\x80\x80\x80\x00");
176 checkout(0x0000000700000000ull
, "\xF0\x80\x80\x80\x00");
177 checkout(0x00000007F0000000ull
, "\xFF\x80\x80\x80\x00");
178 checkout(0x00000007FFFFFFFFull
, "\xFF\xFF\xFF\xFF\x7F");
179 checkout(0x0000000800000000ull
, "\x81\x80\x80\x80\x80\x00");
180 checkout(0x1FFFFFFFFFFFFFFFull
, "\x9F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
181 checkout(0x7FFFFFFFFFFFFFFFull
, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
182 checkout(0xFFFFFFFFFFFFFFFFull
, "\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
184 // Test optional stuff.
185 proto
.reset(new TDenseProtocol(buffer
));
186 proto
->setTypeSpec(ManyOpt::local_reflection
);
187 ManyOpt mo1
, mo2
, mo3
, mo4
, mo5
, mo6
;
188 mo1
.opt1
= 923759347;
189 mo1
.opt2
= 392749274;
190 mo1
.opt3
= 395739402;
191 mo1
.def4
= 294730928;
192 mo1
.opt5
= 394309218;
193 mo1
.opt6
= 832194723;
194 mo1
.__isset
.opt1
= true;
195 mo1
.__isset
.opt2
= true;
196 mo1
.__isset
.opt3
= true;
197 mo1
.__isset
.def4
= true;
198 mo1
.__isset
.opt5
= true;
199 mo1
.__isset
.opt6
= true;
201 mo1
.write(proto
.get());
202 mo2
.read(proto
.get());
204 assert(mo2
.__isset
.opt1
== true);
205 assert(mo2
.__isset
.opt2
== true);
206 assert(mo2
.__isset
.opt3
== true);
207 assert(mo2
.__isset
.def4
== true);
208 assert(mo2
.__isset
.opt5
== true);
209 assert(mo2
.__isset
.opt6
== true);
213 mo1
.__isset
.opt1
= false;
214 mo1
.__isset
.opt3
= false;
215 mo1
.__isset
.opt5
= false;
217 mo1
.write(proto
.get());
218 mo3
.read(proto
.get());
220 assert(mo3
.__isset
.opt1
== false);
221 assert(mo3
.__isset
.opt2
== true);
222 assert(mo3
.__isset
.opt3
== false);
223 assert(mo3
.__isset
.def4
== true);
224 assert(mo3
.__isset
.opt5
== false);
225 assert(mo3
.__isset
.opt6
== true);
229 mo1
.__isset
.opt1
= true;
230 mo1
.__isset
.opt3
= true;
231 mo1
.__isset
.opt5
= true;
232 mo1
.__isset
.opt2
= false;
233 mo1
.__isset
.opt6
= false;
235 mo1
.write(proto
.get());
236 mo4
.read(proto
.get());
238 assert(mo4
.__isset
.opt1
== true);
239 assert(mo4
.__isset
.opt2
== false);
240 assert(mo4
.__isset
.opt3
== true);
241 assert(mo4
.__isset
.def4
== true);
242 assert(mo4
.__isset
.opt5
== true);
243 assert(mo4
.__isset
.opt6
== false);
247 mo1
.__isset
.opt1
= false;
248 mo1
.__isset
.opt5
= false;
250 mo1
.write(proto
.get());
251 mo5
.read(proto
.get());
253 assert(mo5
.__isset
.opt1
== false);
254 assert(mo5
.__isset
.opt2
== false);
255 assert(mo5
.__isset
.opt3
== true);
256 assert(mo5
.__isset
.def4
== true);
257 assert(mo5
.__isset
.opt5
== false);
258 assert(mo5
.__isset
.opt6
== false);
262 mo1
.__isset
.opt3
= false;
264 mo1
.write(proto
.get());
265 mo6
.read(proto
.get());
267 assert(mo6
.__isset
.opt1
== false);
268 assert(mo6
.__isset
.opt2
== false);
269 assert(mo6
.__isset
.opt3
== false);
270 assert(mo6
.__isset
.def4
== true);
271 assert(mo6
.__isset
.opt5
== false);
272 assert(mo6
.__isset
.opt6
== false);
277 // Test fingerprint checking stuff.
280 // Default and required have the same fingerprint.
283 assert(string(Tricky1::ascii_fingerprint
) == Tricky3::ascii_fingerprint
);
284 proto
->setTypeSpec(Tricky1::local_reflection
);
286 t1
.write(proto
.get());
287 proto
->setTypeSpec(Tricky3::local_reflection
);
288 t3
.read(proto
.get());
289 assert(t3
.im_required
== 227);
293 // Optional changes things.
296 assert(string(Tricky1::ascii_fingerprint
) != Tricky2::ascii_fingerprint
);
297 proto
->setTypeSpec(Tricky1::local_reflection
);
299 t1
.write(proto
.get());
301 proto
->setTypeSpec(Tricky2::local_reflection
);
302 t2
.read(proto
.get());
304 } catch (TProtocolException
& ex
) {
305 buffer
->resetBuffer();
310 // Holy cow. We can use the Tricky1 typespec with the Tricky2 structure.
313 proto
->setTypeSpec(Tricky1::local_reflection
);
315 t1
.write(proto
.get());
316 t2
.read(proto
.get());
317 assert(t2
.__isset
.im_optional
== true);
318 assert(t2
.im_optional
== 227);
322 // And totally off the wall.
325 assert(string(Tricky1::ascii_fingerprint
) != OneOfEach::ascii_fingerprint
);
326 proto
->setTypeSpec(Tricky1::local_reflection
);
328 t1
.write(proto
.get());
330 proto
->setTypeSpec(OneOfEach::local_reflection
);
331 ooe2
.read(proto
.get());
333 } catch (TProtocolException
& ex
) {
334 buffer
->resetBuffer();
338 // Okay, this is really off the wall.
340 cout
<< "Starting fuzz test. This takes a while. (20 dots.)" << endl
;
342 for (int i
= 0; i
< 2000; i
++) {
347 buffer
->resetBuffer();
348 // Make sure the fingerprint prefix is right.
349 buffer
->write(Nesting::binary_fingerprint
, 4);
350 for (int j
= 0; j
< 1024*1024; j
++) {
351 uint8_t r
= std::rand();
352 buffer
->write(&r
, 1);
355 proto
->setTypeSpec(OneOfEach::local_reflection
);
358 } catch (TProtocolException
& ex
) {
359 } catch (TTransportException
& ex
) {