/* * 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 #include #include #include #include #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; }