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 <stdio.h>
21 #include <glib-object.h>
22
23 #include <thrift/c_glib/protocol/thrift_binary_protocol.h>
24 #include <thrift/c_glib/transport/thrift_buffered_transport.h>
25 #include <thrift/c_glib/transport/thrift_socket.h>
26
27 #include "gen-c_glib/calculator.h"
28
main(void)29 int main (void)
30 {
31 ThriftSocket *socket;
32 ThriftTransport *transport;
33 ThriftProtocol *protocol;
34 CalculatorIf *client;
35
36 GError *error = NULL;
37 InvalidOperation *invalid_operation = NULL;
38
39 Work *work;
40
41 gint32 sum;
42 gint32 diff;
43
44 int exit_status = 0;
45
46 #if (!GLIB_CHECK_VERSION (2, 36, 0))
47 g_type_init ();
48 #endif
49
50 socket = g_object_new (THRIFT_TYPE_SOCKET,
51 "hostname", "localhost",
52 "port", 9090,
53 NULL);
54 transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
55 "transport", socket,
56 NULL);
57 protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
58 "transport", transport,
59 NULL);
60
61 thrift_transport_open (transport, &error);
62
63
64 /* In the C (GLib) implementation of Thrift, service methods on the
65 server are accessed via a generated client class that implements
66 the service interface. In this tutorial, we access a Calculator
67 service through an instance of CalculatorClient, which implements
68 CalculatorIf. */
69 client = g_object_new (TYPE_CALCULATOR_CLIENT,
70 "input_protocol", protocol,
71 "output_protocol", protocol,
72 NULL);
73
74 /* Each of the client methods requires at least two parameters: A
75 pointer to the client-interface implementation (the client
76 object), and a handle to a GError structure to receive
77 information about any error that occurs.
78
79 On success, client methods return TRUE. A return value of FALSE
80 indicates an error occurred and the error parameter has been
81 set. */
82 if (!error && calculator_if_ping (client, &error)) {
83 puts ("ping()");
84 }
85
86 /* Service methods that return a value do so by passing the result
87 back via an output parameter (here, "sum"). */
88 if (!error && calculator_if_add (client, &sum, 1, 1, &error)) {
89 printf ("1+1=%d\n", sum);
90 }
91
92 /* Thrift structs are implemented as GObjects, with each of the
93 struct's members exposed as an object property. */
94 work = g_object_new (TYPE_WORK, NULL);
95
96 if (!error) {
97 g_object_set (work,
98 "num1", 1,
99 "num2", 0,
100 "op", OPERATION_DIVIDE,
101 NULL);
102
103 /* Exceptions are passed back from service methods in a manner
104 similar to return values. */
105 if (calculator_if_calculate (client,
106 NULL,
107 1,
108 work,
109 &invalid_operation,
110 &error)) {
111 puts ("Whoa? We can divide by zero!");
112 }
113 else {
114 if (invalid_operation) {
115 gchar *why;
116
117 /* Like structs, exceptions are implemented as objects with
118 properties. */
119 g_object_get (invalid_operation, "why", &why, NULL);
120
121 printf ("InvalidOperation: %s\n", why);
122
123 if (why != NULL)
124 g_free (why);
125 g_object_unref (invalid_operation);
126 invalid_operation = NULL;
127 }
128
129 g_clear_error (&error);
130 }
131 }
132
133 if (!error) {
134 /* Struct objects can be reused across method invocations. */
135 g_object_set (work,
136 "num1", 15,
137 "num2", 10,
138 "op", OPERATION_SUBTRACT,
139 NULL);
140
141 if (calculator_if_calculate (client,
142 &diff,
143 1,
144 work,
145 &invalid_operation,
146 &error)) {
147 printf ("15-10=%d\n", diff);
148 }
149 }
150
151 g_object_unref (work);
152
153 if (!error) {
154 SharedStruct *shared_struct;
155 gchar *value;
156
157 shared_struct = g_object_new (TYPE_SHARED_STRUCT, NULL);
158
159 /* As defined in the Thrift file, the Calculator service extends
160 the SharedService service. Correspondingly, in the generated
161 code CalculatorIf inherits from SharedServiceIf, and the parent
162 service's methods are accessible through a simple cast. */
163 if (shared_service_client_get_struct (SHARED_SERVICE_IF (client),
164 &shared_struct,
165 1,
166 &error)) {
167 g_object_get (shared_struct, "value", &value, NULL);
168 printf ("Check log: %s\n", value);
169 g_free (value);
170 }
171
172 g_object_unref (shared_struct);
173 }
174
175 if (error) {
176 printf ("ERROR: %s\n", error->message);
177 g_clear_error (&error);
178
179 exit_status = 1;
180 }
181
182 thrift_transport_close (transport, NULL);
183
184 g_object_unref (client);
185 g_object_unref (protocol);
186 g_object_unref (transport);
187 g_object_unref (socket);
188
189 return exit_status;
190 }
191