blob: 986d5174c575f319f86d9670e71480a8ab3e77a5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <stdio.h>
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include "gen-c_glib/calculator.h"
int main (void)
{
ThriftSocket *socket;
ThriftTransport *transport;
ThriftProtocol *protocol;
CalculatorIf *client;
GError *error = NULL;
InvalidOperation *invalid_operation = NULL;
Work *work;
gint32 sum;
gint32 diff;
int exit_status = 0;
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init ();
#endif
socket = g_object_new (THRIFT_TYPE_SOCKET,
"hostname", "localhost",
"port", 9090,
NULL);
transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", socket,
NULL);
protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
"transport", transport,
NULL);
thrift_transport_open (transport, &error);
/* In the C (GLib) implementation of Thrift, service methods on the
server are accessed via a generated client class that implements
the service interface. In this tutorial, we access a Calculator
service through an instance of CalculatorClient, which implements
CalculatorIf. */
client = g_object_new (TYPE_CALCULATOR_CLIENT,
"input_protocol", protocol,
"output_protocol", protocol,
NULL);
/* Each of the client methods requires at least two parameters: A
pointer to the client-interface implementation (the client
object), and a handle to a GError structure to receive
information about any error that occurs.
On success, client methods return TRUE. A return value of FALSE
indicates an error occurred and the error parameter has been
set. */
if (!error && calculator_if_ping (client, &error)) {
puts ("ping()");
}
/* Service methods that return a value do so by passing the result
back via an output parameter (here, "sum"). */
if (!error && calculator_if_add (client, &sum, 1, 1, &error)) {
printf ("1+1=%d\n", sum);
}
/* Thrift structs are implemented as GObjects, with each of the
struct's members exposed as an object property. */
work = g_object_new (TYPE_WORK, NULL);
if (!error) {
g_object_set (work,
"num1", 1,
"num2", 0,
"op", OPERATION_DIVIDE,
NULL);
/* Exceptions are passed back from service methods in a manner
similar to return values. */
if (calculator_if_calculate (client,
NULL,
1,
work,
&invalid_operation,
&error)) {
puts ("Whoa? We can divide by zero!");
}
else {
if (invalid_operation) {
gchar *why;
/* Like structs, exceptions are implemented as objects with
properties. */
g_object_get (invalid_operation, "why", &why, NULL);
printf ("InvalidOperation: %s\n", why);
if (why != NULL)
g_free (why);
g_object_unref (invalid_operation);
invalid_operation = NULL;
}
g_clear_error (&error);
}
}
if (!error) {
/* Struct objects can be reused across method invocations. */
g_object_set (work,
"num1", 15,
"num2", 10,
"op", OPERATION_SUBTRACT,
NULL);
if (calculator_if_calculate (client,
&diff,
1,
work,
&invalid_operation,
&error)) {
printf ("15-10=%d\n", diff);
}
}
g_object_unref (work);
if (!error) {
SharedStruct *shared_struct;
gchar *value;
shared_struct = g_object_new (TYPE_SHARED_STRUCT, NULL);
/* As defined in the Thrift file, the Calculator service extends
the SharedService service. Correspondingly, in the generated
code CalculatorIf inherits from SharedServiceIf, and the parent
service's methods are accessible through a simple cast. */
if (shared_service_client_get_struct (SHARED_SERVICE_IF (client),
&shared_struct,
1,
&error)) {
g_object_get (shared_struct, "value", &value, NULL);
printf ("Check log: %s\n", value);
g_free (value);
}
g_object_unref (shared_struct);
}
if (error) {
printf ("ERROR: %s\n", error->message);
g_clear_error (&error);
exit_status = 1;
}
thrift_transport_close (transport, NULL);
g_object_unref (client);
g_object_unref (protocol);
g_object_unref (transport);
g_object_unref (socket);
return exit_status;
}