1 /*
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.
18  */
19 
20 #include <inttypes.h>
21 #include <string.h>
22 #include <unistd.h>
23 
24 #include <thrift/c_glib/thrift.h>
25 #include <thrift/c_glib/thrift_application_exception.h>
26 
27 #include "thrift_test_handler.h"
28 
29 /* A handler that implements the TTestThriftTestIf interface */
30 
G_DEFINE_TYPE(ThriftTestHandler,thrift_test_handler,T_TEST_TYPE_THRIFT_TEST_HANDLER)31 G_DEFINE_TYPE (ThriftTestHandler,
32                thrift_test_handler,
33                T_TEST_TYPE_THRIFT_TEST_HANDLER)
34 
35 gboolean
36 thrift_test_handler_test_void (TTestThriftTestIf  *iface,
37                                GError            **error)
38 {
39   THRIFT_UNUSED_VAR (iface);
40   THRIFT_UNUSED_VAR (error);
41 
42   printf ("testVoid()\n");
43 
44   return TRUE;
45 }
46 
47 gboolean
thrift_test_handler_test_string(TTestThriftTestIf * iface,gchar ** _return,const gchar * thing,GError ** error)48 thrift_test_handler_test_string (TTestThriftTestIf  *iface,
49                                  gchar             **_return,
50                                  const gchar        *thing,
51                                  GError            **error)
52 {
53   THRIFT_UNUSED_VAR (iface);
54   THRIFT_UNUSED_VAR (error);
55 
56   printf ("testString(\"%s\")\n", thing);
57   *_return = g_strdup (thing);
58 
59   return TRUE;
60 }
61 
62 gboolean
thrift_test_handler_test_bool(TTestThriftTestIf * iface,gboolean * _return,const gboolean thing,GError ** error)63 thrift_test_handler_test_bool (TTestThriftTestIf  *iface,
64                                gboolean           *_return,
65                                const gboolean      thing,
66                                GError            **error)
67 {
68   THRIFT_UNUSED_VAR (iface);
69   THRIFT_UNUSED_VAR (error);
70 
71   printf ("testBool(%s)\n", thing ? "true" : "false");
72   *_return = thing;
73 
74   return TRUE;
75 }
76 
77 gboolean
thrift_test_handler_test_byte(TTestThriftTestIf * iface,gint8 * _return,const gint8 thing,GError ** error)78 thrift_test_handler_test_byte (TTestThriftTestIf  *iface,
79                                gint8              *_return,
80                                const gint8         thing,
81                                GError            **error)
82 {
83   THRIFT_UNUSED_VAR (iface);
84   THRIFT_UNUSED_VAR (error);
85 
86   printf ("testByte(%d)\n", (gint)thing);
87   *_return = thing;
88 
89   return TRUE;
90 }
91 
92 gboolean
thrift_test_handler_test_i32(TTestThriftTestIf * iface,gint32 * _return,const gint32 thing,GError ** error)93 thrift_test_handler_test_i32 (TTestThriftTestIf  *iface,
94                               gint32             *_return,
95                               const gint32        thing,
96                               GError            **error)
97 {
98   THRIFT_UNUSED_VAR (iface);
99   THRIFT_UNUSED_VAR (error);
100 
101   printf ("testI32(%d)\n", thing);
102   *_return = thing;
103 
104   return TRUE;
105 }
106 
107 gboolean
thrift_test_handler_test_i64(TTestThriftTestIf * iface,gint64 * _return,const gint64 thing,GError ** error)108 thrift_test_handler_test_i64 (TTestThriftTestIf  *iface,
109                               gint64             *_return,
110                               const gint64        thing,
111                               GError            **error)
112 {
113   THRIFT_UNUSED_VAR (iface);
114   THRIFT_UNUSED_VAR (error);
115 
116   printf ("testI64(%" PRId64 ")\n", thing);
117   *_return = thing;
118 
119   return TRUE;
120 }
121 
122 gboolean
thrift_test_handler_test_double(TTestThriftTestIf * iface,gdouble * _return,const gdouble thing,GError ** error)123 thrift_test_handler_test_double (TTestThriftTestIf  *iface,
124                                  gdouble            *_return,
125                                  const gdouble       thing,
126                                  GError            **error)
127 {
128   THRIFT_UNUSED_VAR (iface);
129   THRIFT_UNUSED_VAR (error);
130 
131   printf ("testDouble(%f)\n", thing);
132   *_return = thing;
133 
134   return TRUE;
135 }
136 
137 gboolean
thrift_test_handler_test_binary(TTestThriftTestIf * iface,GByteArray ** _return,const GByteArray * thing,GError ** error)138 thrift_test_handler_test_binary (TTestThriftTestIf *iface,
139                                  GByteArray ** _return,
140                                  const GByteArray * thing,
141                                  GError **error)
142 {
143   THRIFT_UNUSED_VAR (iface);
144   THRIFT_UNUSED_VAR (error);
145 
146   printf ("testBinary()\n");  // TODO: hex output
147   g_byte_array_ref((GByteArray *)thing);
148   *_return = (GByteArray *)thing;
149 
150   return TRUE;
151 }
152 
153 gboolean
thrift_test_handler_test_struct(TTestThriftTestIf * iface,TTestXtruct ** _return,const TTestXtruct * thing,GError ** error)154 thrift_test_handler_test_struct (TTestThriftTestIf  *iface,
155                                  TTestXtruct       **_return,
156                                  const TTestXtruct  *thing,
157                                  GError            **error)
158 {
159   gchar *string_thing = NULL;
160   gint   byte_thing;
161   gint   i32_thing;
162   gint64 i64_thing;
163 
164   THRIFT_UNUSED_VAR (iface);
165   THRIFT_UNUSED_VAR (error);
166 
167   g_object_get ((TTestXtruct *)thing,
168                 "string_thing", &string_thing,
169                 "byte_thing",   &byte_thing,
170                 "i32_thing",    &i32_thing,
171                 "i64_thing",    &i64_thing,
172                 NULL);
173 
174   printf ("testStruct({\"%s\", %d, %d, %" PRId64 "})\n",
175           string_thing,
176           (gint)byte_thing,
177           i32_thing,
178           i64_thing);
179 
180   g_object_set (*_return,
181                 "string_thing", string_thing,
182                 "byte_thing",   byte_thing,
183                 "i32_thing",    i32_thing,
184                 "i64_thing",    i64_thing,
185                 NULL);
186 
187   if (string_thing != NULL)
188     g_free (string_thing);
189 
190   return TRUE;
191 }
192 
193 gboolean
thrift_test_handler_test_nest(TTestThriftTestIf * iface,TTestXtruct2 ** _return,const TTestXtruct2 * thing,GError ** error)194 thrift_test_handler_test_nest (TTestThriftTestIf   *iface,
195                                TTestXtruct2       **_return,
196                                const TTestXtruct2  *thing,
197                                GError             **error)
198 {
199   gchar *inner_string_thing = NULL;
200   gint   byte_thing, inner_byte_thing;
201   gint   i32_thing, inner_i32_thing;
202   gint64 inner_i64_thing;
203   TTestXtruct *struct_thing;
204 
205   THRIFT_UNUSED_VAR (iface);
206   THRIFT_UNUSED_VAR (error);
207 
208   g_object_get ((TTestXtruct2 *)thing,
209                 "byte_thing",   &byte_thing,
210                 "struct_thing", &struct_thing,
211                 "i32_thing",    &i32_thing,
212                 NULL);
213   g_object_get (struct_thing,
214                 "string_thing", &inner_string_thing,
215                 "byte_thing",   &inner_byte_thing,
216                 "i32_thing",    &inner_i32_thing,
217                 "i64_thing",    &inner_i64_thing,
218                 NULL);
219 
220   printf ("testNest({%d, {\"%s\", %d, %d, %" PRId64 "}, %d})\n",
221           byte_thing,
222           inner_string_thing,
223           inner_byte_thing,
224           inner_i32_thing,
225           inner_i64_thing,
226           i32_thing);
227 
228   g_object_set (*_return,
229                 "byte_thing",   byte_thing,
230                 "struct_thing", struct_thing,
231                 "i32_thing",    i32_thing,
232                 NULL);
233 
234   if (inner_string_thing != NULL)
235     g_free (inner_string_thing);
236   g_object_unref (struct_thing);
237 
238   return TRUE;
239 }
240 
241 gboolean
thrift_test_handler_test_map(TTestThriftTestIf * iface,GHashTable ** _return,const GHashTable * thing,GError ** error)242 thrift_test_handler_test_map (TTestThriftTestIf  *iface,
243                               GHashTable        **_return,
244                               const GHashTable   *thing,
245                               GError            **error)
246 {
247   GHashTableIter hash_table_iter;
248   gpointer key;
249   gpointer value;
250   gboolean first = TRUE;
251 
252   THRIFT_UNUSED_VAR (iface);
253   THRIFT_UNUSED_VAR (error);
254 
255   printf ("testMap({");
256   g_hash_table_iter_init (&hash_table_iter, (GHashTable *)thing);
257   while (g_hash_table_iter_next (&hash_table_iter,
258                                  &key,
259                                  &value)) {
260     gint32 *new_key;
261     gint32 *new_value;
262 
263     if (first)
264       first = FALSE;
265     else
266       printf (", ");
267 
268     printf ("%d => %d", *(gint32 *)key, *(gint32 *)value);
269 
270     new_key = g_malloc (sizeof *new_key);
271     *new_key = *(gint32 *)key;
272     new_value = g_malloc (sizeof *new_value);
273     *new_value = *(gint32 *)value;
274     g_hash_table_insert (*_return, new_key, new_value);
275   }
276   printf ("})\n");
277 
278   return TRUE;
279 }
280 
281 gboolean
thrift_test_handler_test_string_map(TTestThriftTestIf * iface,GHashTable ** _return,const GHashTable * thing,GError ** error)282 thrift_test_handler_test_string_map (TTestThriftTestIf  *iface,
283                                      GHashTable        **_return,
284                                      const GHashTable   *thing,
285                                      GError            **error)
286 {
287   GHashTableIter hash_table_iter;
288   gpointer key;
289   gpointer value;
290   gboolean first = TRUE;
291 
292   THRIFT_UNUSED_VAR (iface);
293   THRIFT_UNUSED_VAR (error);
294 
295   printf ("testStringMap({");
296   g_hash_table_iter_init (&hash_table_iter, (GHashTable *)thing);
297   while (g_hash_table_iter_next (&hash_table_iter,
298                                  &key,
299                                  &value)) {
300     gchar *new_key;
301     gchar *new_value;
302 
303     if (first)
304       first = FALSE;
305     else
306       printf (", ");
307 
308     printf ("%s => %s", (gchar *)key, (gchar *)value);
309 
310     new_key = g_strdup ((gchar *)key);
311     new_value = g_strdup ((gchar *)value);
312     g_hash_table_insert (*_return, new_key, new_value);
313   }
314   printf ("})\n");
315 
316   return TRUE;
317 }
318 
319 gboolean
thrift_test_handler_test_set(TTestThriftTestIf * iface,GHashTable ** _return,const GHashTable * thing,GError ** error)320 thrift_test_handler_test_set (TTestThriftTestIf  *iface,
321                               GHashTable        **_return,
322                               const GHashTable   *thing,
323                               GError            **error)
324 {
325   GHashTableIter hash_table_iter;
326   gpointer key;
327   gboolean first = TRUE;
328 
329   THRIFT_UNUSED_VAR (iface);
330   THRIFT_UNUSED_VAR (error);
331 
332   printf ("testSet({");
333   g_hash_table_iter_init (&hash_table_iter, (GHashTable *)thing);
334   while (g_hash_table_iter_next (&hash_table_iter,
335                                  &key,
336                                  NULL)) {
337     gint32 *new_key;
338 
339     if (first)
340       first = FALSE;
341     else
342       printf (", ");
343 
344     printf ("%d", *(gint32 *)key);
345 
346     new_key = g_malloc (sizeof *new_key);
347     *new_key = *(gint32 *)key;
348     g_hash_table_insert (*_return, new_key, NULL);
349   }
350   printf ("})\n");
351 
352   return TRUE;
353 }
354 
355 gboolean
thrift_test_handler_test_list(TTestThriftTestIf * iface,GArray ** _return,const GArray * thing,GError ** error)356 thrift_test_handler_test_list (TTestThriftTestIf  *iface,
357                                GArray            **_return,
358                                const GArray       *thing,
359                                GError            **error)
360 {
361   guint i;
362   gboolean first = TRUE;
363 
364   THRIFT_UNUSED_VAR (iface);
365   THRIFT_UNUSED_VAR (error);
366 
367   printf ("testList({");
368   for (i = 0; i < thing->len; i += 1) {
369     gint32 value;
370     gint32 new_value;
371 
372     if (first)
373       first = FALSE;
374     else
375       printf (", ");
376 
377     value = g_array_index (thing, gint32, i);
378     printf ("%d", value);
379 
380     new_value = value;
381     g_array_append_val (*_return, new_value);
382   }
383   printf ("})\n");
384 
385   return TRUE;
386 }
387 
388 gboolean
thrift_test_handler_test_enum(TTestThriftTestIf * iface,TTestNumberz * _return,const TTestNumberz thing,GError ** error)389 thrift_test_handler_test_enum (TTestThriftTestIf   *iface,
390                                TTestNumberz        *_return,
391                                const TTestNumberz   thing,
392                                GError             **error)
393 {
394   THRIFT_UNUSED_VAR (iface);
395   THRIFT_UNUSED_VAR (error);
396 
397   printf ("testEnum(%d)\n", thing);
398   *_return = thing;
399 
400   return TRUE;
401 }
402 
403 gboolean
thrift_test_handler_test_typedef(TTestThriftTestIf * iface,TTestUserId * _return,const TTestUserId thing,GError ** error)404 thrift_test_handler_test_typedef (TTestThriftTestIf  *iface,
405                                   TTestUserId        *_return,
406                                   const TTestUserId   thing,
407                                   GError            **error)
408 {
409   THRIFT_UNUSED_VAR (iface);
410   THRIFT_UNUSED_VAR (error);
411 
412   printf ("testTypedef(%" PRId64 ")\n", thing);
413   *_return = thing;
414 
415   return TRUE;
416 }
417 
418 gboolean
thrift_test_handler_test_map_map(TTestThriftTestIf * iface,GHashTable ** _return,const gint32 hello,GError ** error)419 thrift_test_handler_test_map_map (TTestThriftTestIf  *iface,
420                                   GHashTable        **_return,
421                                   const gint32        hello,
422                                   GError            **error)
423 {
424   GHashTable *positive;
425   GHashTable *negative;
426   gint32 *key;
427   gint32 *value;
428   guint i;
429 
430   THRIFT_UNUSED_VAR (iface);
431   THRIFT_UNUSED_VAR (error);
432 
433   printf ("testMapMap(%d)\n", hello);
434 
435   positive = g_hash_table_new_full (g_int_hash,
436                                     g_int_equal,
437                                     g_free,
438                                     g_free);
439   negative = g_hash_table_new_full (g_int_hash,
440                                     g_int_equal,
441                                     g_free,
442                                     g_free);
443 
444   for (i = 1; i < 5; i += 1) {
445     key = g_malloc (sizeof *key);
446     value = g_malloc (sizeof *value);
447     *key = i;
448     *value = i;
449     g_hash_table_insert (positive, key, value);
450 
451     key = g_malloc (sizeof *key);
452     value = g_malloc (sizeof *value);
453     *key = -i;
454     *value = -i;
455     g_hash_table_insert (negative, key, value);
456   }
457 
458   key = g_malloc (sizeof *key);
459   *key = 4;
460   g_hash_table_insert (*_return, key, positive);
461 
462   key = g_malloc (sizeof *key);
463   *key = -4;
464   g_hash_table_insert (*_return, key, negative);
465 
466   return TRUE;
467 }
468 
469 gboolean
thrift_test_handler_test_insanity(TTestThriftTestIf * iface,GHashTable ** _return,const TTestInsanity * argument,GError ** error)470 thrift_test_handler_test_insanity (TTestThriftTestIf    *iface,
471                                    GHashTable          **_return,
472                                    const TTestInsanity  *argument,
473                                    GError              **error)
474 {
475   TTestXtruct *xtruct_in;
476 
477   gchar *string_thing = NULL;
478   gint   byte_thing;
479   gint   i32_thing;
480   gint64 i64_thing;
481 
482   GPtrArray *xtructs;
483 
484   TTestInsanity *looney;
485 
486   GHashTable *user_map;
487   GHashTable *first_map;
488   GHashTable *second_map;
489 
490   GHashTableIter hash_table_iter;
491   GHashTableIter inner_hash_table_iter;
492   GHashTableIter user_map_iter;
493 
494   gpointer key;
495   gpointer value;
496 
497   TTestUserId *user_id;
498 
499   guint i;
500 
501   THRIFT_UNUSED_VAR (iface);
502   THRIFT_UNUSED_VAR (error);
503 
504   printf ("testInsanity()\n");
505 
506   first_map = g_hash_table_new_full (g_direct_hash,
507                                      g_direct_equal,
508                                      NULL,
509                                      g_object_unref);
510   second_map = g_hash_table_new_full (g_direct_hash,
511                                       g_direct_equal,
512                                       NULL,
513                                       g_object_unref);
514 
515   g_hash_table_insert (first_map,
516                        GINT_TO_POINTER (T_TEST_NUMBERZ_TWO),
517                        (gpointer)argument);
518   g_hash_table_insert (first_map,
519                        GINT_TO_POINTER (T_TEST_NUMBERZ_THREE),
520                        (gpointer)argument);
521 
522   /* Increment argument's ref count by two because first_map now holds
523      two references to it and the caller is not aware we have made any
524      additional references to argument.  (That is, caller owns argument
525      and will unref it explicitly in addition to unref-ing *_return.)
526 
527      We do this instead of creating a copy of argument in order to mimic
528      the C++ implementation (and since, frankly, the world needs less
529      argument, not more). */
530   g_object_ref ((gpointer)argument);
531   g_object_ref ((gpointer)argument);
532 
533   looney = g_object_new (T_TEST_TYPE_INSANITY, NULL);
534   g_hash_table_insert (second_map,
535                        GINT_TO_POINTER (T_TEST_NUMBERZ_SIX),
536                        looney);
537 
538   user_id = g_malloc (sizeof *user_id);
539   *user_id = 1;
540   g_hash_table_insert (*_return, user_id, first_map);
541 
542   user_id = g_malloc (sizeof *user_id);
543   *user_id = 2;
544   g_hash_table_insert (*_return, user_id, second_map);
545 
546   printf ("return");
547   printf (" = {");
548   g_hash_table_iter_init (&hash_table_iter, *_return);
549   while (g_hash_table_iter_next (&hash_table_iter,
550                                  &key,
551                                  &value)) {
552     printf ("%" PRId64 " => {", *(TTestUserId *)key);
553 
554     g_hash_table_iter_init (&inner_hash_table_iter,
555                             (GHashTable *)value);
556     while (g_hash_table_iter_next (&inner_hash_table_iter,
557                                    &key,
558                                    &value)) {
559       printf ("%d => {", (TTestNumberz)key);
560 
561       g_object_get ((TTestInsanity *)value,
562                     "userMap", &user_map,
563                     "xtructs", &xtructs,
564                     NULL);
565 
566       printf ("{");
567       g_hash_table_iter_init (&user_map_iter, user_map);
568       while (g_hash_table_iter_next (&user_map_iter,
569                                      &key,
570                                      &value)) {
571         printf ("%d => %" PRId64 ", ",
572                 (TTestNumberz)key,
573                 *(TTestUserId *)value);
574       }
575       printf ("}, ");
576       g_hash_table_unref (user_map);
577 
578       printf ("{");
579       for (i = 0; i < xtructs->len; ++i) {
580         xtruct_in = g_ptr_array_index (xtructs, i);
581         g_object_get (xtruct_in,
582                       "string_thing", &string_thing,
583                       "byte_thing",   &byte_thing,
584                       "i32_thing",    &i32_thing,
585                       "i64_thing",    &i64_thing,
586                       NULL);
587 
588         printf ("{\"%s\", %d, %d, %" PRId64 "}, ",
589                 string_thing,
590                 byte_thing,
591                 i32_thing,
592                 i64_thing);
593         if (string_thing != NULL) {
594           g_free (string_thing);
595         }
596       }
597       printf ("}");
598       g_ptr_array_unref (xtructs);
599 
600       printf ("}, ");
601     }
602     printf ("}, ");
603   }
604   printf ("}\n");
605 
606   return TRUE;
607 }
608 
609 gboolean
thrift_test_handler_test_multi(TTestThriftTestIf * iface,TTestXtruct ** _return,const gint8 arg0,const gint32 arg1,const gint64 arg2,const GHashTable * arg3,const TTestNumberz arg4,const TTestUserId arg5,GError ** error)610 thrift_test_handler_test_multi (TTestThriftTestIf   *iface,
611                                 TTestXtruct        **_return,
612                                 const gint8          arg0,
613                                 const gint32         arg1,
614                                 const gint64         arg2,
615                                 const GHashTable    *arg3,
616                                 const TTestNumberz   arg4,
617                                 const TTestUserId    arg5,
618                                 GError             **error)
619 {
620   THRIFT_UNUSED_VAR (iface);
621   THRIFT_UNUSED_VAR (error);
622   THRIFT_UNUSED_VAR (arg3);
623   THRIFT_UNUSED_VAR (arg4);
624   THRIFT_UNUSED_VAR (arg5);
625 
626   printf ("testMulti()\n");
627 
628   g_object_set (*_return,
629                 "string_thing", "Hello2",
630                 "byte_thing",    arg0,
631                 "i32_thing",     arg1,
632                 "i64_thing",     arg2,
633                 NULL);
634 
635   return TRUE;
636 }
637 
638 gboolean
thrift_test_handler_test_exception(TTestThriftTestIf * iface,const gchar * arg,TTestXception ** err1,GError ** error)639 thrift_test_handler_test_exception (TTestThriftTestIf  *iface,
640                                     const gchar        *arg,
641                                     TTestXception     **err1,
642                                     GError            **error)
643 {
644   THRIFT_UNUSED_VAR (iface);
645 
646   TTestXtruct *xtruct;
647   gboolean result;
648 
649   printf ("testException(%s)\n", arg);
650 
651   /* Unlike argument objects, exception objects are not pre-created */
652   g_assert (*err1 == NULL);
653 
654   if (strncmp (arg, "Xception", 9) == 0) {
655     /* "Throw" a custom exception: Set the corresponding exception
656        argument, set *error to NULL and return FALSE */
657     *err1 = g_object_new (T_TEST_TYPE_XCEPTION,
658                           "errorCode", 1001,
659                           "message",   arg,
660                           NULL);
661     *error = NULL;
662     result = FALSE;
663   }
664   else if (strncmp (arg, "TException", 11) == 0) {
665     /* "Throw" a generic TException (ThriftApplicationException): Set
666        all exception arguments to NULL, set *error and return FALSE */
667     *err1 = NULL;
668     g_set_error (error,
669                  thrift_application_exception_error_quark (),
670                  THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN,
671                  "Default TException.");
672     result = FALSE;
673   }
674   else {
675     *err1 = NULL;
676     *error = NULL;
677 
678     /* This code is duplicated from the C++ test suite, though it
679        appears to serve no purpose */
680     xtruct = g_object_new (T_TEST_TYPE_XTRUCT,
681                            "string_thing", arg,
682                            NULL);
683     g_object_unref (xtruct);
684 
685     result = TRUE;
686   }
687 
688   return result;
689 }
690 
691 gboolean
thrift_test_handler_test_multi_exception(TTestThriftTestIf * iface,TTestXtruct ** _return,const gchar * arg0,const gchar * arg1,TTestXception ** err1,TTestXception2 ** err2,GError ** error)692 thrift_test_handler_test_multi_exception (TTestThriftTestIf  *iface,
693                                           TTestXtruct       **_return,
694                                           const gchar        *arg0,
695                                           const gchar        *arg1,
696                                           TTestXception     **err1,
697                                           TTestXception2    **err2,
698                                           GError            **error)
699 {
700   THRIFT_UNUSED_VAR (iface);
701   THRIFT_UNUSED_VAR (error);
702 
703   TTestXtruct *struct_thing;
704   gboolean result;
705 
706   printf ("testMultiException(%s, %s)\n", arg0, arg1);
707 
708   g_assert (*err1 == NULL);
709   g_assert (*err2 == NULL);
710 
711   if (strncmp (arg0, "Xception", 8) == 0 && strlen(arg0) == 8) {
712     *err1 = g_object_new (T_TEST_TYPE_XCEPTION,
713                           "errorCode", 1001,
714                           "message",  "This is an Xception",
715                           NULL);
716     result = FALSE;
717   }
718   else if (strncmp (arg0, "Xception2", 9) == 0) {
719     *err2 = g_object_new (T_TEST_TYPE_XCEPTION2,
720                           "errorCode", 2002,
721                           NULL);
722 
723     g_object_get (*err2,
724                   "struct_thing", &struct_thing,
725                   NULL);
726     g_object_set (struct_thing,
727                   "string_thing", "This is an Xception2",
728                   NULL);
729     g_object_set (*err2,
730                   "struct_thing", struct_thing,
731                   NULL);
732     g_object_unref (struct_thing);
733 
734     result = FALSE;
735   }
736   else {
737     g_object_set (*_return,
738                   "string_thing", arg1,
739                   NULL);
740     result = TRUE;
741   }
742 
743   return result;
744 }
745 
746 gboolean
thrift_test_handler_test_oneway(TTestThriftTestIf * iface,const gint32 secondsToSleep,GError ** error)747 thrift_test_handler_test_oneway (TTestThriftTestIf  *iface,
748                                  const gint32        secondsToSleep,
749                                  GError            **error)
750 {
751   THRIFT_UNUSED_VAR (iface);
752   THRIFT_UNUSED_VAR (error);
753 
754   printf ("testOneway(%d): Sleeping...\n", secondsToSleep);
755   sleep (secondsToSleep);
756   printf ("testOneway(%d): done sleeping!\n", secondsToSleep);
757 
758   return TRUE;
759 }
760 
761 static void
thrift_test_handler_init(ThriftTestHandler * self)762 thrift_test_handler_init (ThriftTestHandler *self)
763 {
764   THRIFT_UNUSED_VAR (self);
765 }
766 
767 static void
thrift_test_handler_class_init(ThriftTestHandlerClass * klass)768 thrift_test_handler_class_init (ThriftTestHandlerClass *klass)
769 {
770   TTestThriftTestHandlerClass *base_class =
771     T_TEST_THRIFT_TEST_HANDLER_CLASS (klass);
772 
773   base_class->test_void =
774     klass->test_void =
775     thrift_test_handler_test_void;
776   base_class->test_string =
777     klass->test_string =
778     thrift_test_handler_test_string;
779   base_class->test_bool =
780     klass->test_bool =
781     thrift_test_handler_test_bool;
782   base_class->test_byte =
783     klass->test_byte =
784     thrift_test_handler_test_byte;
785   base_class->test_i32 =
786     klass->test_i32 =
787     thrift_test_handler_test_i32;
788   base_class->test_i64 =
789     klass->test_i64 =
790     thrift_test_handler_test_i64;
791   base_class->test_double =
792     klass->test_double =
793     thrift_test_handler_test_double;
794   base_class->test_binary =
795     klass->test_binary =
796     thrift_test_handler_test_binary;
797   base_class->test_struct =
798     klass->test_struct =
799     thrift_test_handler_test_struct;
800   base_class->test_nest =
801     klass->test_nest =
802     thrift_test_handler_test_nest;
803   base_class->test_map =
804     klass->test_map =
805     thrift_test_handler_test_map;
806   base_class->test_string_map =
807     klass->test_string_map =
808     thrift_test_handler_test_string_map;
809   base_class->test_set =
810     klass->test_set =
811     thrift_test_handler_test_set;
812   base_class->test_list =
813     klass->test_list =
814     thrift_test_handler_test_list;
815   base_class->test_enum =
816     klass->test_enum =
817     thrift_test_handler_test_enum;
818   base_class->test_typedef =
819     klass->test_typedef =
820     thrift_test_handler_test_typedef;
821   base_class->test_map_map =
822     klass->test_map_map =
823     thrift_test_handler_test_map_map;
824   base_class->test_insanity =
825     klass->test_insanity =
826     thrift_test_handler_test_insanity;
827   base_class->test_multi =
828     klass->test_multi =
829     thrift_test_handler_test_multi;
830   base_class->test_exception =
831     klass->test_exception =
832     thrift_test_handler_test_exception;
833   base_class->test_multi_exception =
834     klass->test_multi_exception =
835     thrift_test_handler_test_multi_exception;
836   base_class->test_oneway =
837     klass->test_oneway =
838     thrift_test_handler_test_oneway;
839 }
840