blob: 3f6075479fe1b353606381ffef7b2ecc55dcef90 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
Todd Lipcon53ae9f32009-12-07 00:42:38 +000018 *
19 * Contains some contributions under the Thrift Software License.
20 * Please see doc/old-thrift-license.txt in the Thrift distribution for
21 * details.
David Reissea2cba82009-03-30 21:35:00 +000022 */
23
David Reiss8320a922007-08-14 19:59:26 +000024#include <cassert>
25#include <map>
26#include <iostream>
Roger Meier49ff8b12012-04-13 09:12:31 +000027#include <thrift/protocol/TDebugProtocol.h>
28#include <thrift/protocol/TBinaryProtocol.h>
29#include <thrift/transport/TBufferTransports.h>
David Reiss8320a922007-08-14 19:59:26 +000030#include "gen-cpp/OptionalRequiredTest_types.h"
31
32using std::cout;
33using std::endl;
34using std::map;
35using std::string;
36using namespace thrift::test;
T Jake Lucianib5e62212009-01-31 22:36:20 +000037using namespace apache::thrift;
38using namespace apache::thrift::transport;
39using namespace apache::thrift::protocol;
David Reiss8320a922007-08-14 19:59:26 +000040
David Reiss8320a922007-08-14 19:59:26 +000041/*
42template<typename Struct>
43void trywrite(const Struct& s, bool should_work) {
44 bool worked;
45 try {
46 TBinaryProtocol protocol(boost::shared_ptr<TTransport>(new TMemoryBuffer));
47 s.write(&protocol);
48 worked = true;
49 } catch (TProtocolException & ex) {
50 worked = false;
51 }
52 assert(worked == should_work);
53}
54*/
55
56template <typename Struct1, typename Struct2>
Konrad Grochowski16a23a62014-11-13 15:33:38 +010057void write_to_read(const Struct1& w, Struct2& r) {
David Reiss8320a922007-08-14 19:59:26 +000058 TBinaryProtocol protocol(boost::shared_ptr<TTransport>(new TMemoryBuffer));
59 w.write(&protocol);
60 r.read(&protocol);
61}
62
David Reiss8320a922007-08-14 19:59:26 +000063int main() {
64
65 cout << "This old school struct should have three fields." << endl;
66 {
67 OldSchool o;
68 cout << ThriftDebugString(o) << endl;
69 }
70 cout << endl;
71
72 cout << "Setting a value before setting isset." << endl;
73 {
74 Simple s;
75 cout << ThriftDebugString(s) << endl;
76 s.im_optional = 10;
77 cout << ThriftDebugString(s) << endl;
78 s.__isset.im_optional = true;
79 cout << ThriftDebugString(s) << endl;
80 }
81 cout << endl;
82
83 cout << "Setting isset before setting a value." << endl;
84 {
85 Simple s;
86 cout << ThriftDebugString(s) << endl;
87 s.__isset.im_optional = true;
88 cout << ThriftDebugString(s) << endl;
89 s.im_optional = 10;
90 cout << ThriftDebugString(s) << endl;
91 }
92 cout << endl;
93
Konrad Grochowski9db4b512014-12-04 23:32:52 +010094 // assign/copy-construct with non-required fields
95 {
96 Simple s1, s2;
97 s1.__isset.im_default = true;
98 s1.__set_im_optional(10);
99 assert(s1.__isset.im_default);
100 assert(s1.__isset.im_optional);
101
102 s2 = s1;
103
104 assert(s2.__isset.im_default);
105 assert(s2.__isset.im_optional);
106
107 Simple s3(s1);
108
109 assert(s3.__isset.im_default);
110 assert(s3.__isset.im_optional);
111 }
112
David Reiss8320a922007-08-14 19:59:26 +0000113 // Write-to-read with optional fields.
114 {
115 Simple s1, s2, s3;
116 s1.im_optional = 10;
117 assert(!s1.__isset.im_default);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100118 // assert(!s1.__isset.im_required); // Compile error.
David Reiss8320a922007-08-14 19:59:26 +0000119 assert(!s1.__isset.im_optional);
120
121 write_to_read(s1, s2);
122
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100123 assert(s2.__isset.im_default);
124 // assert( s2.__isset.im_required); // Compile error.
David Reiss8320a922007-08-14 19:59:26 +0000125 assert(!s2.__isset.im_optional);
126 assert(s3.im_optional == 0);
127
128 s1.__isset.im_optional = true;
129 write_to_read(s1, s3);
130
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100131 assert(s3.__isset.im_default);
132 // assert( s3.__isset.im_required); // Compile error.
133 assert(s3.__isset.im_optional);
David Reiss8320a922007-08-14 19:59:26 +0000134 assert(s3.im_optional == 10);
135 }
136
137 // Writing between optional and default.
138 {
139 Tricky1 t1;
140 Tricky2 t2;
141
142 t2.im_optional = 10;
143 write_to_read(t2, t1);
144 write_to_read(t1, t2);
145 assert(!t1.__isset.im_default);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100146 assert(t2.__isset.im_optional);
David Reiss8320a922007-08-14 19:59:26 +0000147 assert(t1.im_default == t2.im_optional);
148 assert(t1.im_default == 0);
149 }
150
151 // Writing between default and required.
152 {
153 Tricky1 t1;
154 Tricky3 t3;
155 write_to_read(t1, t3);
156 write_to_read(t3, t1);
157 assert(t1.__isset.im_default);
158 }
159
160 // Writing between optional and required.
161 {
162 Tricky2 t2;
163 Tricky3 t3;
164 t2.__isset.im_optional = true;
165 write_to_read(t2, t3);
166 write_to_read(t3, t2);
167 }
168
169 // Mu-hu-ha-ha-ha!
170 {
171 Tricky2 t2;
172 Tricky3 t3;
173 try {
174 write_to_read(t2, t3);
175 abort();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100176 } catch (const TProtocolException&) {
David Reiss8320a922007-08-14 19:59:26 +0000177 }
David Reiss8320a922007-08-14 19:59:26 +0000178
179 write_to_read(t3, t2);
180 assert(t2.__isset.im_optional);
181 }
182
183 cout << "Complex struct, simple test." << endl;
184 {
185 Complex c;
186 cout << ThriftDebugString(c) << endl;
187 }
188
David Reiss8320a922007-08-14 19:59:26 +0000189 {
190 Tricky1 t1;
191 Tricky2 t2;
192 // Compile error.
193 //(void)(t1 == t2);
194 }
195
196 {
197 OldSchool o1, o2, o3;
198 assert(o1 == o2);
199 o1.im_int = o2.im_int = 10;
200 assert(o1 == o2);
201 o1.__isset.im_int = true;
202 o2.__isset.im_int = false;
203 assert(o1 == o2);
204 o1.im_int = 20;
205 o1.__isset.im_int = false;
206 assert(o1 != o2);
207 o1.im_int = 10;
208 assert(o1 == o2);
209 o1.im_str = o2.im_str = "foo";
210 assert(o1 == o2);
211 o1.__isset.im_str = o2.__isset.im_str = true;
212 assert(o1 == o2);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100213 map<int32_t, string> mymap;
David Reiss8320a922007-08-14 19:59:26 +0000214 mymap[1] = "bar";
215 mymap[2] = "baz";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100216 o1.im_big.push_back(map<int32_t, string>());
David Reiss8320a922007-08-14 19:59:26 +0000217 assert(o1 != o2);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100218 o2.im_big.push_back(map<int32_t, string>());
David Reiss8320a922007-08-14 19:59:26 +0000219 assert(o1 == o2);
220 o2.im_big.push_back(mymap);
221 assert(o1 != o2);
222 o1.im_big.push_back(mymap);
223 assert(o1 == o2);
224
225 TBinaryProtocol protocol(boost::shared_ptr<TTransport>(new TMemoryBuffer));
226 o1.write(&protocol);
227
228 o1.im_big.push_back(mymap);
229 mymap[3] = "qux";
230 o2.im_big.push_back(mymap);
231 assert(o1 != o2);
232 o1.im_big.back()[3] = "qux";
233 assert(o1 == o2);
234
235 o3.read(&protocol);
236 o3.im_big.push_back(mymap);
237 assert(o1 == o3);
238
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100239 // cout << ThriftDebugString(o3) << endl;
David Reiss8320a922007-08-14 19:59:26 +0000240 }
241
242 {
243 Tricky2 t1, t2;
244 assert(t1.__isset.im_optional == false);
245 assert(t2.__isset.im_optional == false);
246 assert(t1 == t2);
247 t1.im_optional = 5;
248 assert(t1 == t2);
249 t2.im_optional = 5;
250 assert(t1 == t2);
251 t1.__isset.im_optional = true;
252 assert(t1 != t2);
253 t2.__isset.im_optional = true;
254 assert(t1 == t2);
255 t1.im_optional = 10;
256 assert(t1 != t2);
257 t2.__isset.im_optional = false;
258 assert(t1 != t2);
259 }
260
Jake Farrellf9f01fa2012-01-27 04:48:26 +0000261 {
262 OptionalDefault t1, t2;
263 cout << ThriftDebugString(t1) << endl;
264 assert(t1.__isset.opt_int == true);
265 assert(t1.__isset.opt_str == true);
266 assert(t1.opt_int == t2.opt_int);
267 assert(t1.opt_str == t2.opt_str);
268
269 write_to_read(t1, t2);
270 cout << ThriftDebugString(t2) << endl;
271 assert(t2.__isset.opt_int == true);
272 assert(t2.__isset.opt_str == true);
273 assert(t1.opt_int == t2.opt_int);
274 assert(t1.opt_str == t2.opt_str);
275 }
276
David Reiss8320a922007-08-14 19:59:26 +0000277 return 0;
278}