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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
24 #include <thrift/c_glib/thrift.h>
25 #include <thrift/c_glib/thrift_application_exception.h>
27 #include "thrift_test_handler.h"
29 /* A handler that implements the TTestThriftTestIf interface */
31 G_DEFINE_TYPE (ThriftTestHandler
,
33 T_TEST_TYPE_THRIFT_TEST_HANDLER
)
36 thrift_test_handler_test_void (TTestThriftTestIf
*iface
,
39 THRIFT_UNUSED_VAR (iface
);
40 THRIFT_UNUSED_VAR (error
);
42 printf ("testVoid()\n");
48 thrift_test_handler_test_string (TTestThriftTestIf
*iface
,
53 THRIFT_UNUSED_VAR (iface
);
54 THRIFT_UNUSED_VAR (error
);
56 printf ("testString(\"%s\")\n", thing
);
57 *_return
= g_strdup (thing
);
63 thrift_test_handler_test_bool (TTestThriftTestIf
*iface
,
68 THRIFT_UNUSED_VAR (iface
);
69 THRIFT_UNUSED_VAR (error
);
71 printf ("testBool(%s)\n", thing
? "true" : "false");
78 thrift_test_handler_test_byte (TTestThriftTestIf
*iface
,
83 THRIFT_UNUSED_VAR (iface
);
84 THRIFT_UNUSED_VAR (error
);
86 printf ("testByte(%d)\n", (gint
)thing
);
93 thrift_test_handler_test_i32 (TTestThriftTestIf
*iface
,
98 THRIFT_UNUSED_VAR (iface
);
99 THRIFT_UNUSED_VAR (error
);
101 printf ("testI32(%d)\n", thing
);
108 thrift_test_handler_test_i64 (TTestThriftTestIf
*iface
,
113 THRIFT_UNUSED_VAR (iface
);
114 THRIFT_UNUSED_VAR (error
);
116 printf ("testI64(%" PRId64
")\n", thing
);
123 thrift_test_handler_test_double (TTestThriftTestIf
*iface
,
128 THRIFT_UNUSED_VAR (iface
);
129 THRIFT_UNUSED_VAR (error
);
131 printf ("testDouble(%f)\n", thing
);
138 thrift_test_handler_test_binary (TTestThriftTestIf
*iface
,
139 GByteArray
** _return
,
140 const GByteArray
* thing
,
143 THRIFT_UNUSED_VAR (iface
);
144 THRIFT_UNUSED_VAR (error
);
146 printf ("testBinary()\n"); // TODO: hex output
147 g_byte_array_ref((GByteArray
*)thing
);
148 *_return
= (GByteArray
*)thing
;
154 thrift_test_handler_test_struct (TTestThriftTestIf
*iface
,
155 TTestXtruct
**_return
,
156 const TTestXtruct
*thing
,
159 gchar
*string_thing
= NULL
;
164 THRIFT_UNUSED_VAR (iface
);
165 THRIFT_UNUSED_VAR (error
);
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
,
174 printf ("testStruct({\"%s\", %d, %d, %" PRId64
"})\n",
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
,
187 if (string_thing
!= NULL
)
188 g_free (string_thing
);
194 thrift_test_handler_test_nest (TTestThriftTestIf
*iface
,
195 TTestXtruct2
**_return
,
196 const TTestXtruct2
*thing
,
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
;
205 THRIFT_UNUSED_VAR (iface
);
206 THRIFT_UNUSED_VAR (error
);
208 g_object_get ((TTestXtruct2
*)thing
,
209 "byte_thing", &byte_thing
,
210 "struct_thing", &struct_thing
,
211 "i32_thing", &i32_thing
,
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
,
220 printf ("testNest({%d, {\"%s\", %d, %d, %" PRId64
"}, %d})\n",
228 g_object_set (*_return
,
229 "byte_thing", byte_thing
,
230 "struct_thing", struct_thing
,
231 "i32_thing", i32_thing
,
234 if (inner_string_thing
!= NULL
)
235 g_free (inner_string_thing
);
236 g_object_unref (struct_thing
);
242 thrift_test_handler_test_map (TTestThriftTestIf
*iface
,
243 GHashTable
**_return
,
244 const GHashTable
*thing
,
247 GHashTableIter hash_table_iter
;
250 gboolean first
= TRUE
;
252 THRIFT_UNUSED_VAR (iface
);
253 THRIFT_UNUSED_VAR (error
);
255 printf ("testMap({");
256 g_hash_table_iter_init (&hash_table_iter
, (GHashTable
*)thing
);
257 while (g_hash_table_iter_next (&hash_table_iter
,
268 printf ("%d => %d", *(gint32
*)key
, *(gint32
*)value
);
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
);
282 thrift_test_handler_test_string_map (TTestThriftTestIf
*iface
,
283 GHashTable
**_return
,
284 const GHashTable
*thing
,
287 GHashTableIter hash_table_iter
;
290 gboolean first
= TRUE
;
292 THRIFT_UNUSED_VAR (iface
);
293 THRIFT_UNUSED_VAR (error
);
295 printf ("testStringMap({");
296 g_hash_table_iter_init (&hash_table_iter
, (GHashTable
*)thing
);
297 while (g_hash_table_iter_next (&hash_table_iter
,
308 printf ("%s => %s", (gchar
*)key
, (gchar
*)value
);
310 new_key
= g_strdup ((gchar
*)key
);
311 new_value
= g_strdup ((gchar
*)value
);
312 g_hash_table_insert (*_return
, new_key
, new_value
);
320 thrift_test_handler_test_set (TTestThriftTestIf
*iface
,
321 GHashTable
**_return
,
322 const GHashTable
*thing
,
325 GHashTableIter hash_table_iter
;
327 gboolean first
= TRUE
;
329 THRIFT_UNUSED_VAR (iface
);
330 THRIFT_UNUSED_VAR (error
);
332 printf ("testSet({");
333 g_hash_table_iter_init (&hash_table_iter
, (GHashTable
*)thing
);
334 while (g_hash_table_iter_next (&hash_table_iter
,
344 printf ("%d", *(gint32
*)key
);
346 new_key
= g_malloc (sizeof *new_key
);
347 *new_key
= *(gint32
*)key
;
348 g_hash_table_insert (*_return
, new_key
, NULL
);
356 thrift_test_handler_test_list (TTestThriftTestIf
*iface
,
362 gboolean first
= TRUE
;
364 THRIFT_UNUSED_VAR (iface
);
365 THRIFT_UNUSED_VAR (error
);
367 printf ("testList({");
368 for (i
= 0; i
< thing
->len
; i
+= 1) {
377 value
= g_array_index (thing
, gint32
, i
);
378 printf ("%d", value
);
380 new_value
= g_malloc (sizeof *new_value
);
382 g_array_append_val (*_return
, *new_value
);
390 thrift_test_handler_test_enum (TTestThriftTestIf
*iface
,
391 TTestNumberz
*_return
,
392 const TTestNumberz thing
,
395 THRIFT_UNUSED_VAR (iface
);
396 THRIFT_UNUSED_VAR (error
);
398 printf ("testEnum(%d)\n", thing
);
405 thrift_test_handler_test_typedef (TTestThriftTestIf
*iface
,
406 TTestUserId
*_return
,
407 const TTestUserId thing
,
410 THRIFT_UNUSED_VAR (iface
);
411 THRIFT_UNUSED_VAR (error
);
413 printf ("testTypedef(%" PRId64
")\n", thing
);
420 thrift_test_handler_test_map_map (TTestThriftTestIf
*iface
,
421 GHashTable
**_return
,
425 GHashTable
*positive
;
426 GHashTable
*negative
;
431 THRIFT_UNUSED_VAR (iface
);
432 THRIFT_UNUSED_VAR (error
);
434 printf ("testMapMap(%d)\n", hello
);
436 positive
= g_hash_table_new_full (g_int_hash
,
440 negative
= g_hash_table_new_full (g_int_hash
,
445 for (i
= 1; i
< 5; i
+= 1) {
446 key
= g_malloc (sizeof *key
);
447 value
= g_malloc (sizeof *value
);
450 g_hash_table_insert (positive
, key
, value
);
452 key
= g_malloc (sizeof *key
);
453 value
= g_malloc (sizeof *value
);
456 g_hash_table_insert (negative
, key
, value
);
459 key
= g_malloc (sizeof *key
);
461 g_hash_table_insert (*_return
, key
, positive
);
463 key
= g_malloc (sizeof *key
);
465 g_hash_table_insert (*_return
, key
, negative
);
471 thrift_test_handler_test_insanity (TTestThriftTestIf
*iface
,
472 GHashTable
**_return
,
473 const TTestInsanity
*argument
,
476 TTestXtruct
*xtruct_in
;
478 gchar
*string_thing
= NULL
;
485 TTestInsanity
*looney
;
487 GHashTable
*user_map
;
488 GHashTable
*first_map
;
489 GHashTable
*second_map
;
491 GHashTableIter hash_table_iter
;
492 GHashTableIter inner_hash_table_iter
;
493 GHashTableIter user_map_iter
;
498 TTestUserId
*user_id
;
502 THRIFT_UNUSED_VAR (iface
);
503 THRIFT_UNUSED_VAR (error
);
505 printf ("testInsanity()\n");
507 first_map
= g_hash_table_new_full (g_direct_hash
,
511 second_map
= g_hash_table_new_full (g_direct_hash
,
516 g_hash_table_insert (first_map
,
517 GINT_TO_POINTER (T_TEST_NUMBERZ_TWO
),
519 g_hash_table_insert (first_map
,
520 GINT_TO_POINTER (T_TEST_NUMBERZ_THREE
),
523 /* Increment argument's ref count by two because first_map now holds
524 two references to it and the caller is not aware we have made any
525 additional references to argument. (That is, caller owns argument
526 and will unref it explicitly in addition to unref-ing *_return.)
528 We do this instead of creating a copy of argument in order to mimic
529 the C++ implementation (and since, frankly, the world needs less
530 argument, not more). */
531 g_object_ref ((gpointer
)argument
);
532 g_object_ref ((gpointer
)argument
);
534 looney
= g_object_new (T_TEST_TYPE_INSANITY
, NULL
);
535 g_hash_table_insert (second_map
,
536 GINT_TO_POINTER (T_TEST_NUMBERZ_SIX
),
539 user_id
= g_malloc (sizeof *user_id
);
541 g_hash_table_insert (*_return
, user_id
, first_map
);
543 user_id
= g_malloc (sizeof *user_id
);
545 g_hash_table_insert (*_return
, user_id
, second_map
);
549 g_hash_table_iter_init (&hash_table_iter
, *_return
);
550 while (g_hash_table_iter_next (&hash_table_iter
,
553 printf ("%" PRId64
" => {", *(TTestUserId
*)key
);
555 g_hash_table_iter_init (&inner_hash_table_iter
,
556 (GHashTable
*)value
);
557 while (g_hash_table_iter_next (&inner_hash_table_iter
,
560 printf ("%d => {", (TTestNumberz
)key
);
562 g_object_get ((TTestInsanity
*)value
,
563 "userMap", &user_map
,
568 g_hash_table_iter_init (&user_map_iter
, user_map
);
569 while (g_hash_table_iter_next (&user_map_iter
,
572 printf ("%d => %" PRId64
", ",
574 *(TTestUserId
*)value
);
577 g_hash_table_unref (user_map
);
580 for (i
= 0; i
< xtructs
->len
; ++i
) {
581 xtruct_in
= g_ptr_array_index (xtructs
, i
);
582 g_object_get (xtruct_in
,
583 "string_thing", &string_thing
,
584 "byte_thing", &byte_thing
,
585 "i32_thing", &i32_thing
,
586 "i64_thing", &i64_thing
,
589 printf ("{\"%s\", %d, %d, %" PRId64
"}, ",
596 g_ptr_array_unref (xtructs
);
608 thrift_test_handler_test_multi (TTestThriftTestIf
*iface
,
609 TTestXtruct
**_return
,
613 const GHashTable
*arg3
,
614 const TTestNumberz arg4
,
615 const TTestUserId arg5
,
618 THRIFT_UNUSED_VAR (iface
);
619 THRIFT_UNUSED_VAR (error
);
620 THRIFT_UNUSED_VAR (arg3
);
621 THRIFT_UNUSED_VAR (arg4
);
622 THRIFT_UNUSED_VAR (arg5
);
624 printf ("testMulti()\n");
626 g_object_set (*_return
,
627 "string_thing", g_strdup ("Hello2"),
637 thrift_test_handler_test_exception (TTestThriftTestIf
*iface
,
639 TTestXception
**err1
,
642 THRIFT_UNUSED_VAR (iface
);
647 printf ("testException(%s)\n", arg
);
649 /* Unlike argument objects, exception objects are not pre-created */
650 g_assert (*err1
== NULL
);
652 if (strncmp (arg
, "Xception", 9) == 0) {
653 /* "Throw" a custom exception: Set the corresponding exception
654 argument, set *error to NULL and return FALSE */
655 *err1
= g_object_new (T_TEST_TYPE_XCEPTION
,
657 "message", g_strdup (arg
),
662 else if (strncmp (arg
, "TException", 11) == 0) {
663 /* "Throw" a generic TException (ThriftApplicationException): Set
664 all exception arguments to NULL, set *error and return FALSE */
667 thrift_application_exception_error_quark (),
668 THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN
,
669 "Default TException.");
676 /* This code is duplicated from the C++ test suite, though it
677 appears to serve no purpose */
678 xtruct
= g_object_new (T_TEST_TYPE_XTRUCT
,
679 "string_thing", g_strdup (arg
),
681 g_object_unref (xtruct
);
690 thrift_test_handler_test_multi_exception (TTestThriftTestIf
*iface
,
691 TTestXtruct
**_return
,
694 TTestXception
**err1
,
695 TTestXception2
**err2
,
698 THRIFT_UNUSED_VAR (iface
);
699 THRIFT_UNUSED_VAR (error
);
701 TTestXtruct
*struct_thing
;
704 printf ("testMultiException(%s, %s)\n", arg0
, arg1
);
706 g_assert (*err1
== NULL
);
707 g_assert (*err2
== NULL
);
709 if (strncmp (arg0
, "Xception", 8) == 0 && strlen(arg0
) == 8) {
710 *err1
= g_object_new (T_TEST_TYPE_XCEPTION
,
712 "message", g_strdup ("This is an Xception"),
716 else if (strncmp (arg0
, "Xception2", 9) == 0) {
717 *err2
= g_object_new (T_TEST_TYPE_XCEPTION2
,
722 "struct_thing", &struct_thing
,
724 g_object_set (struct_thing
,
725 "string_thing", g_strdup ("This is an Xception2"),
728 "struct_thing", struct_thing
,
730 g_object_unref (struct_thing
);
735 g_object_set (*_return
,
736 "string_thing", g_strdup (arg1
),
745 thrift_test_handler_test_oneway (TTestThriftTestIf
*iface
,
746 const gint32 secondsToSleep
,
749 THRIFT_UNUSED_VAR (iface
);
750 THRIFT_UNUSED_VAR (error
);
752 printf ("testOneway(%d): Sleeping...\n", secondsToSleep
);
753 sleep (secondsToSleep
);
754 printf ("testOneway(%d): done sleeping!\n", secondsToSleep
);
760 thrift_test_handler_init (ThriftTestHandler
*self
)
762 THRIFT_UNUSED_VAR (self
);
766 thrift_test_handler_class_init (ThriftTestHandlerClass
*klass
)
768 TTestThriftTestHandlerClass
*base_class
=
769 T_TEST_THRIFT_TEST_HANDLER_CLASS (klass
);
771 base_class
->test_void
=
773 thrift_test_handler_test_void
;
774 base_class
->test_string
=
776 thrift_test_handler_test_string
;
777 base_class
->test_bool
=
779 thrift_test_handler_test_bool
;
780 base_class
->test_byte
=
782 thrift_test_handler_test_byte
;
783 base_class
->test_i32
=
785 thrift_test_handler_test_i32
;
786 base_class
->test_i64
=
788 thrift_test_handler_test_i64
;
789 base_class
->test_double
=
791 thrift_test_handler_test_double
;
792 base_class
->test_binary
=
794 thrift_test_handler_test_binary
;
795 base_class
->test_struct
=
797 thrift_test_handler_test_struct
;
798 base_class
->test_nest
=
800 thrift_test_handler_test_nest
;
801 base_class
->test_map
=
803 thrift_test_handler_test_map
;
804 base_class
->test_string_map
=
805 klass
->test_string_map
=
806 thrift_test_handler_test_string_map
;
807 base_class
->test_set
=
809 thrift_test_handler_test_set
;
810 base_class
->test_list
=
812 thrift_test_handler_test_list
;
813 base_class
->test_enum
=
815 thrift_test_handler_test_enum
;
816 base_class
->test_typedef
=
817 klass
->test_typedef
=
818 thrift_test_handler_test_typedef
;
819 base_class
->test_map_map
=
820 klass
->test_map_map
=
821 thrift_test_handler_test_map_map
;
822 base_class
->test_insanity
=
823 klass
->test_insanity
=
824 thrift_test_handler_test_insanity
;
825 base_class
->test_multi
=
827 thrift_test_handler_test_multi
;
828 base_class
->test_exception
=
829 klass
->test_exception
=
830 thrift_test_handler_test_exception
;
831 base_class
->test_multi_exception
=
832 klass
->test_multi_exception
=
833 thrift_test_handler_test_multi_exception
;
834 base_class
->test_oneway
=
836 thrift_test_handler_test_oneway
;