1 /*
2  * Copyright 2022 Young Mei
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <cstdint>
10 #include <cstdio>
11 
12 #include <sstream>
13 #include <stdexcept>
14 
15 #include "SecondService.h"
16 #include "ThriftTest.h"
17 
18 using namespace std;
19 
20 using namespace apache::thrift;
21 using namespace apache::thrift::transport;
22 using namespace thrift::test;
23 
24 class TestHandler : public ThriftTestIf
25 {
26 public:
27 	TestHandler() = default;
28 
testVoid()29 	void testVoid() override
30 	{
31 		printf("testVoid()\n");
32 	}
33 
testString(string & out,const string & thing)34 	void testString(string &out, const string &thing) override
35 	{
36 		printf("testString(\"%s\")\n", thing.c_str());
37 		out = thing;
38 	}
39 
testBool(const bool thing)40 	bool testBool(const bool thing) override
41 	{
42 		printf("testBool(%s)\n", thing ? "true" : "false");
43 		return thing;
44 	}
45 
testByte(const int8_t thing)46 	int8_t testByte(const int8_t thing) override
47 	{
48 		printf("testByte(%d)\n", (int)thing);
49 		return thing;
50 	}
51 
testI32(const int32_t thing)52 	int32_t testI32(const int32_t thing) override
53 	{
54 		printf("testI32(%d)\n", thing);
55 		return thing;
56 	}
57 
testI64(const int64_t thing)58 	int64_t testI64(const int64_t thing) override
59 	{
60 		printf("testI64(%" PRId64 ")\n", thing);
61 		return thing;
62 	}
63 
testDouble(const double thing)64 	double testDouble(const double thing) override
65 	{
66 		printf("testDouble(%f)\n", thing);
67 		return thing;
68 	}
69 
testBinary(std::string & _return,const std::string & thing)70 	void testBinary(std::string &_return, const std::string &thing) override
71 	{
72 		std::ostringstream hexstr;
73 
74 		hexstr << std::hex << thing;
75 		printf("testBinary(%lu: %s)\n", safe_numeric_cast<unsigned long>(thing.size()),
76 		       hexstr.str().c_str());
77 		_return = thing;
78 	}
79 
testStruct(Xtruct & out,const Xtruct & thing)80 	void testStruct(Xtruct &out, const Xtruct &thing) override
81 	{
82 		printf("testStruct({\"%s\", %d, %d, %" PRId64 "})\n", thing.string_thing.c_str(),
83 		       (int)thing.byte_thing, thing.i32_thing, thing.i64_thing);
84 		out = thing;
85 	}
86 
testNest(Xtruct2 & out,const Xtruct2 & nest)87 	void testNest(Xtruct2 &out, const Xtruct2 &nest) override
88 	{
89 		const Xtruct &thing = nest.struct_thing;
90 
91 		printf("testNest({%d, {\"%s\", %d, %d, %" PRId64 "}, %d})\n", (int)nest.byte_thing,
92 		       thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing,
93 		       thing.i64_thing, nest.i32_thing);
94 		out = nest;
95 	}
96 
testMap(map<int32_t,int32_t> & out,const map<int32_t,int32_t> & thing)97 	void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) override
98 	{
99 		map<int32_t, int32_t>::const_iterator m_iter;
100 		bool first = true;
101 
102 		printf("testMap({");
103 		for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
104 			if (first) {
105 				first = false;
106 			} else {
107 				printf(", ");
108 			}
109 
110 			printf("%d => %d", m_iter->first, m_iter->second);
111 		}
112 
113 		printf("})\n");
114 		out = thing;
115 	}
116 
testStringMap(map<std::string,std::string> & out,const map<std::string,std::string> & thing)117 	void testStringMap(map<std::string, std::string> &out,
118 			   const map<std::string, std::string> &thing) override
119 	{
120 		map<std::string, std::string>::const_iterator m_iter;
121 		bool first = true;
122 
123 		printf("testMap({");
124 		for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
125 			if (first) {
126 				first = false;
127 			} else {
128 				printf(", ");
129 			}
130 			printf("%s => %s", (m_iter->first).c_str(), (m_iter->second).c_str());
131 		}
132 
133 		printf("})\n");
134 		out = thing;
135 	}
136 
testSet(set<int32_t> & out,const set<int32_t> & thing)137 	void testSet(set<int32_t> &out, const set<int32_t> &thing) override
138 	{
139 		set<int32_t>::const_iterator s_iter;
140 		bool first = true;
141 
142 		printf("testSet({");
143 		for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
144 			if (first) {
145 				first = false;
146 			} else {
147 				printf(", ");
148 			}
149 
150 			printf("%d", *s_iter);
151 		}
152 
153 		printf("})\n");
154 		out = thing;
155 	}
156 
testList(vector<int32_t> & out,const vector<int32_t> & thing)157 	void testList(vector<int32_t> &out, const vector<int32_t> &thing) override
158 	{
159 		vector<int32_t>::const_iterator l_iter;
160 		bool first = true;
161 
162 		printf("testList({");
163 		for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
164 			if (first) {
165 				first = false;
166 			} else {
167 				printf(", ");
168 			}
169 			printf("%d", *l_iter);
170 		}
171 
172 		printf("})\n");
173 		out = thing;
174 	}
175 
testEnum(const Numberz::type thing)176 	Numberz::type testEnum(const Numberz::type thing) override
177 	{
178 		printf("testEnum(%d)\n", thing);
179 		return thing;
180 	}
181 
testTypedef(const UserId thing)182 	UserId testTypedef(const UserId thing) override
183 	{
184 		printf("testTypedef(%" PRId64 ")\n", thing);
185 		return thing;
186 	}
187 
testMapMap(map<int32_t,map<int32_t,int32_t>> & mapmap,const int32_t hello)188 	void testMapMap(map<int32_t, map<int32_t, int32_t>> &mapmap, const int32_t hello) override
189 	{
190 		map<int32_t, int32_t> pos;
191 		map<int32_t, int32_t> neg;
192 
193 		printf("testMapMap(%d)\n", hello);
194 		for (int i = 1; i < 5; i++) {
195 			pos.insert(make_pair(i, i));
196 			neg.insert(make_pair(-i, -i));
197 		}
198 
199 		mapmap.insert(make_pair(4, pos));
200 		mapmap.insert(make_pair(-4, neg));
201 	}
202 
testInsanity(map<UserId,map<Numberz::type,Insanity>> & insane,const Insanity & argument)203 	void testInsanity(map<UserId, map<Numberz::type, Insanity>> &insane,
204 			  const Insanity &argument) override
205 	{
206 		Insanity looney;
207 		map<Numberz::type, Insanity> first_map;
208 		map<Numberz::type, Insanity> second_map;
209 
210 		first_map.insert(make_pair(Numberz::TWO, argument));
211 		first_map.insert(make_pair(Numberz::THREE, argument));
212 
213 		second_map.insert(make_pair(Numberz::SIX, looney));
214 
215 		insane.insert(make_pair(1, first_map));
216 		insane.insert(make_pair(2, second_map));
217 
218 		printf("testInsanity()\n");
219 		printf("return");
220 		printf(" = {");
221 		map<UserId, map<Numberz::type, Insanity>>::const_iterator i_iter;
222 
223 		for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
224 			printf("%" PRId64 " => {", i_iter->first);
225 			map<Numberz::type, Insanity>::const_iterator i2_iter;
226 
227 			for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end();
228 			     ++i2_iter) {
229 				printf("%d => {", i2_iter->first);
230 				map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
231 				map<Numberz::type, UserId>::const_iterator um;
232 
233 				printf("{");
234 				for (um = userMap.begin(); um != userMap.end(); ++um) {
235 					printf("%d => %" PRId64 ", ", um->first, um->second);
236 				}
237 
238 				printf("}, ");
239 				vector<Xtruct> xtructs = i2_iter->second.xtructs;
240 				vector<Xtruct>::const_iterator x;
241 
242 				printf("{");
243 				for (x = xtructs.begin(); x != xtructs.end(); ++x) {
244 					printf("{\"%s\", %d, %d, %" PRId64 "}, ",
245 					       x->string_thing.c_str(), (int)x->byte_thing,
246 					       x->i32_thing, x->i64_thing);
247 				}
248 
249 				printf("}");
250 				printf("}, ");
251 			}
252 
253 			printf("}, ");
254 		}
255 
256 		printf("}\n");
257 	}
258 
testMulti(Xtruct & hello,const int8_t arg0,const int32_t arg1,const int64_t arg2,const std::map<int16_t,std::string> & arg3,const Numberz::type arg4,const UserId arg5)259 	void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2,
260 		       const std::map<int16_t, std::string> &arg3, const Numberz::type arg4,
261 		       const UserId arg5) override
262 	{
263 		(void)arg3;
264 		(void)arg4;
265 		(void)arg5;
266 		printf("testMulti()\n");
267 		hello.string_thing = "Hello2";
268 		hello.byte_thing = arg0;
269 		hello.i32_thing = arg1;
270 		hello.i64_thing = (int64_t)arg2;
271 	}
272 
testException(const std::string & arg)273 	void testException(const std::string &arg) override
274 	{
275 		printf("testException(%s)\n", arg.c_str());
276 		if (arg.compare("Xception") == 0) {
277 			Xception e;
278 			e.errorCode = 1001;
279 			e.message = arg;
280 			throw e;
281 		} else if (arg.compare("TException") == 0) {
282 			apache::thrift::TException e;
283 			throw e;
284 		} else {
285 			Xtruct result;
286 			result.string_thing = arg;
287 			return;
288 		}
289 	}
290 
testMultiException(Xtruct & result,const std::string & arg0,const std::string & arg1)291 	void testMultiException(Xtruct &result, const std::string &arg0,
292 				const std::string &arg1) override
293 	{
294 
295 		printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());
296 		if (arg0.compare("Xception") == 0) {
297 			Xception e;
298 			e.errorCode = 1001;
299 			e.message = "This is an Xception";
300 			throw e;
301 		} else if (arg0.compare("Xception2") == 0) {
302 			Xception2 e;
303 			e.errorCode = 2002;
304 			e.struct_thing.string_thing = "This is an Xception2";
305 			throw e;
306 		} else {
307 			result.string_thing = arg1;
308 			return;
309 		}
310 	}
311 
testOneway(const int32_t aNum)312 	void testOneway(const int32_t aNum) override
313 	{
314 		printf("testOneway(%d): call received\n", aNum);
315 	}
316 };
317 
318 class SecondHandler : public SecondServiceIf
319 {
320 public:
secondtestString(std::string & result,const std::string & thing)321 	void secondtestString(std::string &result, const std::string &thing) override
322 	{
323 		result = "testString(\"" + thing + "\")";
324 	}
325 };
326