Moving from govendor to dep, updated dependencies (#48)

* Moving from govendor to dep.

* Making the pull request template more friendly.

* Fixing akward space in PR template.

* goimports run on whole project using ` goimports -w $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./gen-go/*")`

source of command: https://gist.github.com/bgentry/fd1ffef7dbde01857f66
This commit is contained in:
Renan DelValle 2018-01-07 13:13:47 -08:00 committed by GitHub
parent 9631aa3aab
commit 8d445c1c77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2186 changed files with 400410 additions and 352 deletions

View file

@ -0,0 +1,72 @@
#
# 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.
#
# Find required packages
find_package(GLIB REQUIRED COMPONENTS gobject)
include_directories(${GLIB_INCLUDE_DIRS})
include_directories(src)
# SYSLIBS contains libraries that need to be linked to all lib targets
set(SYSLIBS ${GLIB_LIBRARIES} ${GLIB_GOBJECT_LIBRARIES})
# Create the thrift C glib library
set(thrift_c_glib_SOURCES
src/thrift/c_glib/thrift.c
src/thrift/c_glib/thrift_struct.c
src/thrift/c_glib/thrift_application_exception.c
src/thrift/c_glib/processor/thrift_processor.c
src/thrift/c_glib/processor/thrift_dispatch_processor.c
src/thrift/c_glib/protocol/thrift_protocol.c
src/thrift/c_glib/protocol/thrift_protocol_factory.c
src/thrift/c_glib/protocol/thrift_binary_protocol.c
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c
src/thrift/c_glib/protocol/thrift_compact_protocol.c
src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c
src/thrift/c_glib/transport/thrift_transport.c
src/thrift/c_glib/transport/thrift_transport_factory.c
src/thrift/c_glib/transport/thrift_buffered_transport_factory.c
src/thrift/c_glib/transport/thrift_framed_transport_factory.c
src/thrift/c_glib/transport/thrift_socket.c
src/thrift/c_glib/transport/thrift_server_transport.c
src/thrift/c_glib/transport/thrift_server_socket.c
src/thrift/c_glib/transport/thrift_buffered_transport.c
src/thrift/c_glib/transport/thrift_fd_transport.c
src/thrift/c_glib/transport/thrift_framed_transport.c
src/thrift/c_glib/transport/thrift_memory_buffer.c
src/thrift/c_glib/server/thrift_server.c
src/thrift/c_glib/server/thrift_simple_server.c
)
# Contains the thrift specific ADD_LIBRARY_THRIFT and TARGET_LINK_LIBRARIES_THRIFT
include(ThriftMacros)
ADD_LIBRARY_THRIFT(thrift_c_glib ${thrift_c_glib_SOURCES})
TARGET_LINK_LIBRARIES_THRIFT(thrift_c_glib ${SYSLIBS})
# Install the headers
install(DIRECTORY "src/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}"
FILES_MATCHING PATTERN "*.h")
# Copy config.h file
install(DIRECTORY "${CMAKE_BINARY_DIR}/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}"
FILES_MATCHING PATTERN "*.h")
if(BUILD_TESTING)
add_subdirectory(test)
endif()

105
vendor/git.apache.org/thrift.git/lib/c_glib/Makefile.am generated vendored Executable file
View file

@ -0,0 +1,105 @@
#
# 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.
#
AUTOMAKE_OPTIONS = serial-tests
SUBDIRS = . test
pkgconfigdir = $(libdir)/pkgconfig
lib_LTLIBRARIES = libthrift_c_glib.la
pkgconfig_DATA = thrift_c_glib.pc
AM_CPPFLAGS = -Isrc -I src/thrift/c_glib
AM_CFLAGS = -Wall -Wextra -pedantic
# Define the source files for the module
libthrift_c_glib_la_SOURCES = src/thrift/c_glib/thrift.c \
src/thrift/c_glib/thrift_struct.c \
src/thrift/c_glib/thrift_application_exception.c \
src/thrift/c_glib/processor/thrift_processor.c \
src/thrift/c_glib/processor/thrift_dispatch_processor.c \
src/thrift/c_glib/protocol/thrift_protocol.c \
src/thrift/c_glib/protocol/thrift_protocol_factory.c \
src/thrift/c_glib/protocol/thrift_binary_protocol.c \
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c \
src/thrift/c_glib/protocol/thrift_compact_protocol.c \
src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c \
src/thrift/c_glib/transport/thrift_transport.c \
src/thrift/c_glib/transport/thrift_transport_factory.c \
src/thrift/c_glib/transport/thrift_buffered_transport_factory.c \
src/thrift/c_glib/transport/thrift_framed_transport_factory.c \
src/thrift/c_glib/transport/thrift_socket.c \
src/thrift/c_glib/transport/thrift_server_transport.c \
src/thrift/c_glib/transport/thrift_server_socket.c \
src/thrift/c_glib/transport/thrift_buffered_transport.c \
src/thrift/c_glib/transport/thrift_fd_transport.c \
src/thrift/c_glib/transport/thrift_framed_transport.c \
src/thrift/c_glib/transport/thrift_memory_buffer.c \
src/thrift/c_glib/server/thrift_server.c \
src/thrift/c_glib/server/thrift_simple_server.c
libthrift_c_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
include_thriftdir = $(includedir)/thrift/c_glib
include_thrift_HEADERS = \
$(top_builddir)/config.h \
src/thrift/c_glib/thrift.h \
src/thrift/c_glib/thrift_application_exception.h \
src/thrift/c_glib/thrift_struct.h
include_protocoldir = $(include_thriftdir)/protocol
include_protocol_HEADERS = src/thrift/c_glib/protocol/thrift_protocol.h \
src/thrift/c_glib/protocol/thrift_protocol_factory.h \
src/thrift/c_glib/protocol/thrift_binary_protocol.h \
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h \
src/thrift/c_glib/protocol/thrift_compact_protocol.h \
src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h
include_transportdir = $(include_thriftdir)/transport
include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \
src/thrift/c_glib/transport/thrift_fd_transport.h \
src/thrift/c_glib/transport/thrift_framed_transport.h \
src/thrift/c_glib/transport/thrift_memory_buffer.h \
src/thrift/c_glib/transport/thrift_server_socket.h \
src/thrift/c_glib/transport/thrift_server_transport.h \
src/thrift/c_glib/transport/thrift_socket.h \
src/thrift/c_glib/transport/thrift_transport.h \
src/thrift/c_glib/transport/thrift_transport_factory.h \
src/thrift/c_glib/transport/thrift_buffered_transport_factory.h \
src/thrift/c_glib/transport/thrift_framed_transport_factory.h
include_serverdir = $(include_thriftdir)/server
include_server_HEADERS = src/thrift/c_glib/server/thrift_server.h \
src/thrift/c_glib/server/thrift_simple_server.h
include_processordir = $(include_thriftdir)/processor
include_processor_HEADERS = src/thrift/c_glib/processor/thrift_processor.h \
src/thrift/c_glib/processor/thrift_dispatch_processor.h
EXTRA_DIST = \
CMakeLists.txt \
coding_standards.md \
README.md \
test/glib.suppress \
thrift_c_glib.pc.in
CLEANFILES = \
*.gcno \
*.gcda

34
vendor/git.apache.org/thrift.git/lib/c_glib/README.md generated vendored Normal file
View file

@ -0,0 +1,34 @@
Thrift C Software Library
License
=======
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.
Using Thrift with C
===================
The Thrift C libraries are built using the GNU tools. Follow the instructions
in the top-level README in order to generate the Makefiles.
Dependencies
============
GLib
http://www.gtk.org/

View file

@ -0,0 +1,5 @@
## C Glib Coding Standards
Please follow:
* [Thrift General Coding Standards](/doc/coding_standards.md)
* [GNOME C Coding Style](https://help.gnome.org/users/programming-guidelines/stable/c-coding-style.html.en)

View file

@ -0,0 +1,143 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/thrift_application_exception.h>
#include <thrift/c_glib/processor/thrift_dispatch_processor.h>
G_DEFINE_ABSTRACT_TYPE (ThriftDispatchProcessor,
thrift_dispatch_processor,
THRIFT_TYPE_PROCESSOR)
gboolean
thrift_dispatch_processor_process (ThriftProcessor *processor,
ThriftProtocol *in,
ThriftProtocol *out,
GError **error)
{
gchar *fname;
ThriftMessageType mtype;
gint32 seqid;
ThriftDispatchProcessor *dispatch_processor =
THRIFT_DISPATCH_PROCESSOR (processor);
/* Read the start of the message, which we expect to be a method call */
if (thrift_protocol_read_message_begin (in,
&fname,
&mtype,
&seqid,
error) < 0) {
g_warning ("error reading start of message: %s",
(error != NULL) ? (*error)->message : "(null)");
return FALSE;
}
else if (mtype != T_CALL && mtype != T_ONEWAY) {
g_warning ("received invalid message type %d from client", mtype);
return FALSE;
}
/* Dispatch the method call */
return THRIFT_DISPATCH_PROCESSOR_GET_CLASS (dispatch_processor)
->dispatch_call (dispatch_processor,
in,
out,
fname,
seqid,
error);
}
static gboolean
thrift_dispatch_processor_real_dispatch_call (ThriftDispatchProcessor *self,
ThriftProtocol *in,
ThriftProtocol *out,
gchar *fname,
gint32 seqid,
GError **error)
{
ThriftTransport *transport;
ThriftApplicationException *xception;
gchar *message;
gint32 result;
gboolean dispatch_result = FALSE;
THRIFT_UNUSED_VAR (self);
/* By default, return an application exception to the client indicating the
method name is not recognized. */
if ((thrift_protocol_skip (in, T_STRUCT, error) < 0) ||
(thrift_protocol_read_message_end (in, error) < 0))
return FALSE;
g_object_get (in, "transport", &transport, NULL);
result = thrift_transport_read_end (transport, error);
g_object_unref (transport);
if (result < 0)
return FALSE;
if (thrift_protocol_write_message_begin (out,
fname,
T_EXCEPTION,
seqid,
error) < 0)
return FALSE;
message = g_strconcat ("Invalid method name: '", fname, "'", NULL);
g_free (fname);
xception =
g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION,
"type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD,
"message", message,
NULL);
g_free (message);
result = thrift_struct_write (THRIFT_STRUCT (xception),
out,
error);
g_object_unref (xception);
if ((result < 0) ||
(thrift_protocol_write_message_end (out, error) < 0))
return FALSE;
g_object_get (out, "transport", &transport, NULL);
dispatch_result =
((thrift_transport_write_end (transport, error) >= 0) &&
(thrift_transport_flush (transport, error) >= 0));
g_object_unref (transport);
return dispatch_result;
}
static void
thrift_dispatch_processor_init (ThriftDispatchProcessor *self)
{
THRIFT_UNUSED_VAR (self);
}
static void
thrift_dispatch_processor_class_init (ThriftDispatchProcessorClass *klass)
{
ThriftProcessorClass *processor_class =
THRIFT_PROCESSOR_CLASS (klass);
/* Implement ThriftProcessor's process method */
processor_class->process = thrift_dispatch_processor_process;
/* Provide a default implement for dispatch_call, which returns an exception
to the client indicating the method name was not recognized */
klass->dispatch_call = thrift_dispatch_processor_real_dispatch_call;
}

View file

@ -0,0 +1,95 @@
/*
* 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.
*/
#ifndef _THRIFT_DISPATCH_PROCESSOR_H
#define _THRIFT_DISPATCH_PROCESSOR_H
#include <glib-object.h>
#include <thrift/c_glib/processor/thrift_processor.h>
G_BEGIN_DECLS
/*! \file thrift_dispatch_processor.h
* \brief Parses a method-call message header and invokes a function
* to dispatch the call by function name.
*
* ThriftDispatchProcessor is an abstract helper class that parses the
* header of a method-call message and invokes a member function,
* dispatch_call, with the method's name.
*
* Subclasses must implement dispatch_call to dispatch the method call
* to the implementing function.
*/
/* Type macros */
#define THRIFT_TYPE_DISPATCH_PROCESSOR (thrift_dispatch_processor_get_type ())
#define THRIFT_DISPATCH_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_DISPATCH_PROCESSOR, ThriftDispatchProcessor))
#define THRIFT_IS_DISPATCH_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_DISPATCH_PROCESSOR))
#define THRIFT_DISPATCH_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_DISPATCH_PROCESSOR, ThriftDispatchProcessorClass))
#define THRIFT_IS_DISPATCH_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_DISPATCH_PROCESSOR))
#define THRIFT_DISPATCH_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_DISPATCH_PROCESSOR, ThriftDispatchProcessorClass))
/*!
* Thrift Dispatch Processor object
*/
struct _ThriftDispatchProcessor
{
ThriftProcessor parent;
};
typedef struct _ThriftDispatchProcessor ThriftDispatchProcessor;
/*!
* Thrift Dispatch Processor class
*/
struct _ThriftDispatchProcessorClass
{
ThriftProcessorClass parent;
/* public */
gboolean (*process) (ThriftProcessor *processor,
ThriftProtocol *in,
ThriftProtocol *out,
GError **error);
/* protected */
gboolean (*dispatch_call) (ThriftDispatchProcessor *self,
ThriftProtocol *in,
ThriftProtocol *out,
gchar *fname,
gint32 seqid,
GError **error);
};
typedef struct _ThriftDispatchProcessorClass ThriftDispatchProcessorClass;
/* Used by THRIFT_TYPE_DISPATCH_PROCESSOR */
GType thrift_dispatch_processor_get_type (void);
/*!
* Processes a request.
* \public \memberof ThriftDispatchProcessorClass
*/
gboolean thrift_dispatch_processor_process (ThriftProcessor *processor,
ThriftProtocol *in,
ThriftProtocol *out,
GError **error);
G_END_DECLS
#endif /* _THRIFT_DISPATCH_PROCESSOR_H */

View file

@ -0,0 +1,45 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/processor/thrift_processor.h>
G_DEFINE_ABSTRACT_TYPE(ThriftProcessor, thrift_processor, G_TYPE_OBJECT)
gboolean
thrift_processor_process (ThriftProcessor *processor, ThriftProtocol *in,
ThriftProtocol *out, GError **error)
{
return
THRIFT_PROCESSOR_GET_CLASS (processor)->process (processor, in, out, error);
}
/* class initializer for ThriftProcessor */
static void
thrift_processor_class_init (ThriftProcessorClass *cls)
{
/* set these as virtual methods to be implemented by a subclass */
cls->process = thrift_processor_process;
}
static void
thrift_processor_init (ThriftProcessor *processor)
{
THRIFT_UNUSED_VAR (processor);
}

View file

@ -0,0 +1,76 @@
/*
* 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.
*/
#ifndef _THRIFT_PROCESSOR_H
#define _THRIFT_PROCESSOR_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
G_BEGIN_DECLS
/*! \file thrift_processor.h
* \brief Abstract class for Thrift processors.
*/
/* type macros */
#define THRIFT_TYPE_PROCESSOR (thrift_processor_get_type ())
#define THRIFT_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROCESSOR, ThriftProcessor))
#define THRIFT_IS_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROCESSOR))
#define THRIFT_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROCESSOR, ThriftProcessorClass))
#define THRIFT_IS_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROCESSOR))
#define THRIFT_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROCESSOR, ThriftProcessorClass))
/*!
* Thrift Processorobject
*/
struct _ThriftProcessor
{
GObject parent;
};
typedef struct _ThriftProcessor ThriftProcessor;
/*!
* Thrift Processor class
*/
struct _ThriftProcessorClass
{
GObjectClass parent;
/* vtable */
gboolean (*process) (ThriftProcessor *processor, ThriftProtocol *in,
ThriftProtocol *out, GError **error);
};
typedef struct _ThriftProcessorClass ThriftProcessorClass;
/* used by THRIFT_TYPE_PROCESSOR */
GType thrift_processor_get_type (void);
/*!
* Processes the request.
* \public \memberof ThriftProcessorClass
*/
gboolean thrift_processor_process (ThriftProcessor *processor,
ThriftProtocol *in, ThriftProtocol *out,
GError **error);
G_END_DECLS
#endif /* _THRIFT_PROCESSOR_H */

View file

@ -0,0 +1,904 @@
/*
* 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 <string.h>
#include <stdio.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
G_DEFINE_TYPE(ThriftBinaryProtocol, thrift_binary_protocol, THRIFT_TYPE_PROTOCOL)
static guint64
thrift_bitwise_cast_guint64 (gdouble v)
{
union {
gdouble from;
guint64 to;
} u;
u.from = v;
return u.to;
}
static gdouble
thrift_bitwise_cast_gdouble (guint64 v)
{
union {
guint64 from;
gdouble to;
} u;
u.from = v;
return u.to;
}
gint32
thrift_binary_protocol_write_message_begin (ThriftProtocol *protocol,
const gchar *name, const ThriftMessageType message_type,
const gint32 seqid, GError **error)
{
gint32 version = (THRIFT_BINARY_PROTOCOL_VERSION_1)
| ((gint32) message_type);
gint32 ret;
gint32 xfer = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_write_i32 (protocol, version, error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_write_string (protocol, name, error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_write_i32 (protocol, seqid, error)) < 0)
{
return -1;
}
xfer += ret;
return xfer;
}
gint32
thrift_binary_protocol_write_message_end (ThriftProtocol *protocol,
GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_struct_begin (ThriftProtocol *protocol,
const gchar *name,
GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (name);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_struct_end (ThriftProtocol *protocol,
GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_field_begin (ThriftProtocol *protocol,
const gchar *name,
const ThriftType field_type,
const gint16 field_id,
GError **error)
{
gint32 ret;
gint32 xfer = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
THRIFT_UNUSED_VAR (name);
if ((ret = thrift_protocol_write_byte (protocol, (gint8) field_type,
error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_write_i16 (protocol, field_id, error)) < 0)
{
return -1;
}
xfer += ret;
return xfer;
}
gint32
thrift_binary_protocol_write_field_end (ThriftProtocol *protocol,
GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_field_stop (ThriftProtocol *protocol,
GError **error)
{
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
return thrift_protocol_write_byte (protocol, (gint8) T_STOP, error);
}
gint32
thrift_binary_protocol_write_map_begin (ThriftProtocol *protocol,
const ThriftType key_type,
const ThriftType value_type,
const guint32 size,
GError **error)
{
gint32 ret;
gint32 xfer = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_write_byte (protocol, (gint8) key_type,
error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_write_byte (protocol, (gint8) value_type,
error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_write_i32 (protocol, (gint32) size, error)) < 0)
{
return -1;
}
xfer += ret;
return xfer;
}
gint32
thrift_binary_protocol_write_map_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_list_begin (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size,
GError **error)
{
gint32 ret;
gint32 xfer = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_write_byte (protocol, (gint8) element_type,
error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_write_i32 (protocol, (gint32) size, error)) < 0)
{
return -1;
}
xfer += ret;
return xfer;
}
gint32
thrift_binary_protocol_write_list_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_set_begin (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size,
GError **error)
{
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
return thrift_protocol_write_list_begin (protocol, element_type,
size, error);
}
gint32
thrift_binary_protocol_write_set_end (ThriftProtocol *protocol, GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_write_bool (ThriftProtocol *protocol,
const gboolean value, GError **error)
{
guint8 tmp;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
tmp = value ? 1 : 0;
return thrift_protocol_write_byte (protocol, tmp, error);
}
gint32
thrift_binary_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
GError **error)
{
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if (thrift_transport_write (protocol->transport,
(const gpointer) &value, 1, error))
{
return 1;
} else {
return -1;
}
}
gint32
thrift_binary_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
GError **error)
{
gint16 net;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
net = g_htons (value);
if (thrift_transport_write (protocol->transport,
(const gpointer) &net, 2, error))
{
return 2;
} else {
return -1;
}
}
gint32
thrift_binary_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
GError **error)
{
gint32 net;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
net = g_htonl (value);
if (thrift_transport_write (protocol->transport,
(const gpointer) &net, 4, error))
{
return 4;
} else {
return -1;
}
}
gint32
thrift_binary_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
GError **error)
{
gint64 net;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
net = GUINT64_TO_BE (value);
if (thrift_transport_write (protocol->transport,
(const gpointer) &net, 8, error))
{
return 8;
} else {
return -1;
}
}
gint32
thrift_binary_protocol_write_double (ThriftProtocol *protocol,
const gdouble value, GError **error)
{
guint64 bits;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
bits = GUINT64_FROM_BE (thrift_bitwise_cast_guint64 (value));
if (thrift_transport_write (protocol->transport,
(const gpointer) &bits, 8, error))
{
return 8;
} else {
return -1;
}
}
gint32
thrift_binary_protocol_write_string (ThriftProtocol *protocol,
const gchar *str, GError **error)
{
guint32 len;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
len = str != NULL ? strlen (str) : 0;
/* write the string length + 1 which includes the null terminator */
return thrift_protocol_write_binary (protocol, (const gpointer) str,
len, error);
}
gint32
thrift_binary_protocol_write_binary (ThriftProtocol *protocol,
const gpointer buf,
const guint32 len, GError **error)
{
gint32 ret;
gint32 xfer = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_write_i32 (protocol, len, error)) < 0)
{
return -1;
}
xfer += ret;
if (len > 0)
{
if (thrift_transport_write (protocol->transport,
(const gpointer) buf, len, error) == FALSE)
{
return -1;
}
xfer += len;
}
return xfer;
}
gint32
thrift_binary_protocol_read_message_begin (ThriftProtocol *protocol,
gchar **name,
ThriftMessageType *message_type,
gint32 *seqid, GError **error)
{
gint32 ret;
gint32 xfer = 0;
gint32 sz;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_read_i32 (protocol, &sz, error)) < 0)
{
return -1;
}
xfer += ret;
if (sz < 0)
{
/* check for version */
guint32 version = sz & THRIFT_BINARY_PROTOCOL_VERSION_MASK;
if (version != THRIFT_BINARY_PROTOCOL_VERSION_1)
{
g_set_error (error, THRIFT_PROTOCOL_ERROR,
THRIFT_PROTOCOL_ERROR_BAD_VERSION,
"expected version %d, got %d",
THRIFT_BINARY_PROTOCOL_VERSION_1, version);
return -1;
}
*message_type = (ThriftMessageType) (sz & 0x000000ff);
if ((ret = thrift_protocol_read_string (protocol, name, error)) < 0)
{
return -1;
}
xfer += ret;
if ((ret = thrift_protocol_read_i32 (protocol, seqid, error)) < 0)
{
return -1;
}
xfer += ret;
}
return xfer;
}
gint32
thrift_binary_protocol_read_message_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_read_struct_begin (ThriftProtocol *protocol,
gchar **name,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
*name = NULL;
return 0;
}
gint32
thrift_binary_protocol_read_struct_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_read_field_begin (ThriftProtocol *protocol,
gchar **name,
ThriftType *field_type,
gint16 *field_id,
GError **error)
{
gint32 ret;
gint32 xfer = 0;
gint8 type;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
THRIFT_UNUSED_VAR (name);
if ((ret = thrift_protocol_read_byte (protocol, &type, error)) < 0)
{
return -1;
}
xfer += ret;
*field_type = (ThriftType) type;
if (*field_type == T_STOP)
{
*field_id = 0;
return xfer;
}
if ((ret = thrift_protocol_read_i16 (protocol, field_id, error)) < 0)
{
return -1;
}
xfer += ret;
return xfer;
}
gint32
thrift_binary_protocol_read_field_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_read_map_begin (ThriftProtocol *protocol,
ThriftType *key_type,
ThriftType *value_type,
guint32 *size,
GError **error)
{
gint32 ret;
gint32 xfer = 0;
gint8 k, v;
gint32 sizei;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_read_byte (protocol, &k, error)) < 0)
{
return -1;
}
xfer += ret;
*key_type = (ThriftType) k;
if ((ret = thrift_protocol_read_byte (protocol, &v, error)) < 0)
{
return -1;
}
xfer += ret;
*value_type = (ThriftType) v;
if ((ret = thrift_protocol_read_i32 (protocol, &sizei, error)) <0)
{
return -1;
}
xfer += ret;
if (sizei < 0)
{
g_set_error (error, THRIFT_PROTOCOL_ERROR,
THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
"got negative size of %d", sizei);
return -1;
}
*size = (guint32) sizei;
return xfer;
}
gint32
thrift_binary_protocol_read_map_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_read_list_begin (ThriftProtocol *protocol,
ThriftType *element_type,
guint32 *size, GError **error)
{
gint32 ret;
gint32 xfer = 0;
gint8 e;
gint32 sizei;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret = thrift_protocol_read_byte (protocol, &e, error)) < 0)
{
return -1;
}
xfer += ret;
*element_type = (ThriftType) e;
if ((ret = thrift_protocol_read_i32 (protocol, &sizei, error)) < 0)
{
return -1;
}
xfer += ret;
if (sizei < 0)
{
g_set_error (error, THRIFT_PROTOCOL_ERROR,
THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
"got negative size of %d", sizei);
return -1;
}
*size = (guint32) sizei;
return xfer;
}
gint32
thrift_binary_protocol_read_list_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_read_set_begin (ThriftProtocol *protocol,
ThriftType *element_type,
guint32 *size, GError **error)
{
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
return thrift_protocol_read_list_begin (protocol, element_type, size, error);
}
gint32
thrift_binary_protocol_read_set_end (ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_binary_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
GError **error)
{
gint32 ret;
gpointer b[1];
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret =
thrift_transport_read_all (protocol->transport,
b, 1, error)) < 0)
{
return -1;
}
*value = *(gint8 *) b != 0;
return ret;
}
gint32
thrift_binary_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
GError **error)
{
gint32 ret;
gpointer b[1];
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret =
thrift_transport_read_all (protocol->transport,
b, 1, error)) < 0)
{
return -1;
}
*value = *(gint8 *) b;
return ret;
}
gint32
thrift_binary_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
GError **error)
{
gint32 ret;
union
{
gint8 byte_array[2];
gint16 int16;
} b;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret =
thrift_transport_read_all (protocol->transport,
b.byte_array, 2, error)) < 0)
{
return -1;
}
*value = g_ntohs (b.int16);
return ret;
}
gint32
thrift_binary_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
GError **error)
{
gint32 ret;
union
{
gint8 byte_array[4];
gint32 int32;
} b;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret =
thrift_transport_read_all (protocol->transport,
b.byte_array, 4, error)) < 0)
{
return -1;
}
*value = g_ntohl (b.int32);
return ret;
}
gint32
thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
GError **error)
{
gint32 ret;
union
{
gint8 byte_array[8];
gint64 int64;
} b;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret =
thrift_transport_read_all (protocol->transport,
b.byte_array, 8, error)) < 0)
{
return -1;
}
*value = GUINT64_FROM_BE (b.int64);
return ret;
}
gint32
thrift_binary_protocol_read_double (ThriftProtocol *protocol,
gdouble *value, GError **error)
{
gint32 ret;
union
{
gint8 byte_array[8];
guint64 uint64;
} b;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
if ((ret =
thrift_transport_read_all (protocol->transport,
b.byte_array, 8, error)) < 0)
{
return -1;
}
*value = thrift_bitwise_cast_gdouble (GUINT64_FROM_BE (b.uint64));
return ret;
}
gint32
thrift_binary_protocol_read_string (ThriftProtocol *protocol,
gchar **str, GError **error)
{
guint32 len;
gint32 ret;
gint32 xfer = 0;
gint32 read_len = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
/* read the length into read_len */
if ((ret =
thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
{
return -1;
}
xfer += ret;
if (read_len > 0)
{
/* allocate the memory for the string */
len = (guint32) read_len + 1; /* space for null terminator */
*str = g_new0 (gchar, len);
if ((ret =
thrift_transport_read_all (protocol->transport,
*str, read_len, error)) < 0)
{
g_free (*str);
*str = NULL;
len = 0;
return -1;
}
xfer += ret;
} else {
*str = NULL;
}
return xfer;
}
gint32
thrift_binary_protocol_read_binary (ThriftProtocol *protocol,
gpointer *buf, guint32 *len,
GError **error)
{
gint32 ret;
gint32 xfer = 0;
gint32 read_len = 0;
g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
/* read the length into read_len */
if ((ret =
thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
{
return -1;
}
xfer += ret;
if (read_len > 0)
{
/* allocate the memory as an array of unsigned char for binary data */
*len = (guint32) read_len;
*buf = g_new (guchar, *len);
if ((ret =
thrift_transport_read_all (protocol->transport,
*buf, *len, error)) < 0)
{
g_free (*buf);
*buf = NULL;
*len = 0;
return -1;
}
xfer += ret;
} else {
*len = (guint32) read_len;
*buf = NULL;
}
return xfer;
}
static void
thrift_binary_protocol_init (ThriftBinaryProtocol *protocol)
{
THRIFT_UNUSED_VAR (protocol);
}
/* initialize the class */
static void
thrift_binary_protocol_class_init (ThriftBinaryProtocolClass *klass)
{
ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
cls->write_message_begin = thrift_binary_protocol_write_message_begin;
cls->write_message_end = thrift_binary_protocol_write_message_end;
cls->write_struct_begin = thrift_binary_protocol_write_struct_begin;
cls->write_struct_end = thrift_binary_protocol_write_struct_end;
cls->write_field_begin = thrift_binary_protocol_write_field_begin;
cls->write_field_end = thrift_binary_protocol_write_field_end;
cls->write_field_stop = thrift_binary_protocol_write_field_stop;
cls->write_map_begin = thrift_binary_protocol_write_map_begin;
cls->write_map_end = thrift_binary_protocol_write_map_end;
cls->write_list_begin = thrift_binary_protocol_write_list_begin;
cls->write_list_end = thrift_binary_protocol_write_list_end;
cls->write_set_begin = thrift_binary_protocol_write_set_begin;
cls->write_set_end = thrift_binary_protocol_write_set_end;
cls->write_bool = thrift_binary_protocol_write_bool;
cls->write_byte = thrift_binary_protocol_write_byte;
cls->write_i16 = thrift_binary_protocol_write_i16;
cls->write_i32 = thrift_binary_protocol_write_i32;
cls->write_i64 = thrift_binary_protocol_write_i64;
cls->write_double = thrift_binary_protocol_write_double;
cls->write_string = thrift_binary_protocol_write_string;
cls->write_binary = thrift_binary_protocol_write_binary;
cls->read_message_begin = thrift_binary_protocol_read_message_begin;
cls->read_message_end = thrift_binary_protocol_read_message_end;
cls->read_struct_begin = thrift_binary_protocol_read_struct_begin;
cls->read_struct_end = thrift_binary_protocol_read_struct_end;
cls->read_field_begin = thrift_binary_protocol_read_field_begin;
cls->read_field_end = thrift_binary_protocol_read_field_end;
cls->read_map_begin = thrift_binary_protocol_read_map_begin;
cls->read_map_end = thrift_binary_protocol_read_map_end;
cls->read_list_begin = thrift_binary_protocol_read_list_begin;
cls->read_list_end = thrift_binary_protocol_read_list_end;
cls->read_set_begin = thrift_binary_protocol_read_set_begin;
cls->read_set_end = thrift_binary_protocol_read_set_end;
cls->read_bool = thrift_binary_protocol_read_bool;
cls->read_byte = thrift_binary_protocol_read_byte;
cls->read_i16 = thrift_binary_protocol_read_i16;
cls->read_i32 = thrift_binary_protocol_read_i32;
cls->read_i64 = thrift_binary_protocol_read_i64;
cls->read_double = thrift_binary_protocol_read_double;
cls->read_string = thrift_binary_protocol_read_string;
cls->read_binary = thrift_binary_protocol_read_binary;
}

View file

@ -0,0 +1,72 @@
/*
* 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.
*/
#ifndef _THRIFT_BINARY_PROTOCOL_H
#define _THRIFT_BINARY_PROTOCOL_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_binary_protocol.h
* \brief Binary protocol implementation of a Thrift protocol. Implements the
* ThriftProtocol interface.
*/
/* type macros */
#define THRIFT_TYPE_BINARY_PROTOCOL (thrift_binary_protocol_get_type ())
#define THRIFT_BINARY_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BINARY_PROTOCOL, ThriftBinaryProtocol))
#define THRIFT_IS_BINARY_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BINARY_PROTOCOL))
#define THRIFT_BINARY_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BINARY_PROTOCOL, ThriftBinaryProtocolClass))
#define THRIFT_IS_BINARY_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BINARY_PROTOCOL))
#define THRIFT_BINARY_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BINARY_PROTOCOL, ThriftBinaryProtocolClass))
/* version numbers */
#define THRIFT_BINARY_PROTOCOL_VERSION_1 0x80010000
#define THRIFT_BINARY_PROTOCOL_VERSION_MASK 0xffff0000
typedef struct _ThriftBinaryProtocol ThriftBinaryProtocol;
/*!
* Thrift Binary Protocol instance.
*/
struct _ThriftBinaryProtocol
{
ThriftProtocol parent;
};
typedef struct _ThriftBinaryProtocolClass ThriftBinaryProtocolClass;
/*!
* Thrift Binary Protocol class.
*/
struct _ThriftBinaryProtocolClass
{
ThriftProtocolClass parent;
};
/* used by THRIFT_TYPE_BINARY_PROTOCOL */
GType thrift_binary_protocol_get_type (void);
G_END_DECLS
#endif /* _THRIFT_BINARY_PROTOCOL_H */

View file

@ -0,0 +1,50 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
G_DEFINE_TYPE(ThriftBinaryProtocolFactory, thrift_binary_protocol_factory, THRIFT_TYPE_PROTOCOL_FACTORY)
ThriftProtocol *
thrift_binary_protocol_factory_get_protocol (ThriftProtocolFactory *factory,
ThriftTransport *transport)
{
ThriftBinaryProtocol *tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
"transport", transport, NULL);
THRIFT_UNUSED_VAR (factory);
return THRIFT_PROTOCOL (tb);
}
static void
thrift_binary_protocol_factory_class_init (ThriftBinaryProtocolFactoryClass *cls)
{
ThriftProtocolFactoryClass *protocol_factory_class = THRIFT_PROTOCOL_FACTORY_CLASS (cls);
protocol_factory_class->get_protocol = thrift_binary_protocol_factory_get_protocol;
}
static void
thrift_binary_protocol_factory_init (ThriftBinaryProtocolFactory *factory)
{
THRIFT_UNUSED_VAR (factory);
}

View file

@ -0,0 +1,56 @@
/*
* 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.
*/
#ifndef _THRIFT_BINARY_PROTOCOL_FACTORY_H
#define _THRIFT_BINARY_PROTOCOL_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
G_BEGIN_DECLS
/* type macros */
#define THRIFT_TYPE_BINARY_PROTOCOL_FACTORY (thrift_binary_protocol_factory_get_type ())
#define THRIFT_BINARY_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, ThriftBinaryProtocolFactory))
#define THRIFT_IS_BINARY_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY))
#define THRIFT_BINARY_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, ThriftBinaryProtocolFactoryClass))
#define THRIFT_IS_BINARY_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY))
#define THRIFT_BINARY_PROTOCOL_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, ThriftBinaryProtocolFactoryClass))
typedef struct _ThriftBinaryProtocolFactory ThriftBinaryProtocolFactory;
struct _ThriftBinaryProtocolFactory
{
ThriftProtocolFactory parent;
};
typedef struct _ThriftBinaryProtocolFactoryClass ThriftBinaryProtocolFactoryClass;
struct _ThriftBinaryProtocolFactoryClass
{
ThriftProtocolFactoryClass parent;
};
/* used by THRIFT_TYPE_BINARY_PROTOCOL_FACTORY */
GType thrift_binary_protocol_factory_get_type (void);
G_END_DECLS
#endif /* _THRIFT_BINARY_PROTOCOL_FACTORY_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,107 @@
/*
* 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.
*/
#ifndef _THRIFT_COMPACT_PROTOCOL_H
#define _THRIFT_COMPACT_PROTOCOL_H
#include <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_compact_protocol.h
* \brief Compact protocol implementation of a Thrift protocol. Implements the
* ThriftProtocol interface.
*/
/* type macros */
#define THRIFT_TYPE_COMPACT_PROTOCOL (thrift_compact_protocol_get_type ())
#define THRIFT_COMPACT_PROTOCOL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_COMPACT_PROTOCOL, \
ThriftCompactProtocol))
#define THRIFT_IS_COMPACT_PROTOCOL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_COMPACT_PROTOCOL))
#define THRIFT_COMPACT_PROTOCOL_CLASS(c) \
(G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_COMPACT_PROTOCOL, \
ThriftCompactProtocolClass))
#define THRIFT_IS_COMPACT_PROTOCOL_CLASS(c) \
(G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_COMPACT_PROTOCOL))
#define THRIFT_COMPACT_PROTOCOL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_COMPACT_PROTOCOL, \
ThriftCompactProtocolClass))
typedef struct _ThriftCompactProtocol ThriftCompactProtocol;
/*!
* Thrift Compact Protocol instance.
*/
struct _ThriftCompactProtocol
{
ThriftProtocol parent;
/* protected */
gint32 string_limit;
gint32 container_limit;
/* private */
/**
* (Writing) If we encounter a boolean field begin, save the TField here
* so it can have the value incorporated.
*/
const gchar* _bool_field_name;
ThriftType _bool_field_type;
gint16 _bool_field_id;
/**
* (Reading) If we read a field header, and it's a boolean field, save
* the boolean value here so that read_bool can use it.
*/
gboolean _has_bool_value;
gboolean _bool_value;
/**
* Used to keep track of the last field for the current and previous structs,
* so we can do the delta stuff.
*/
GQueue _last_field;
gint16 _last_field_id;
};
typedef struct _ThriftCompactProtocolClass ThriftCompactProtocolClass;
/*!
* Thrift Compact Protocol class.
*/
struct _ThriftCompactProtocolClass
{
ThriftProtocolClass parent;
};
/* used by THRIFT_TYPE_COMPACT_PROTOCOL */
GType thrift_compact_protocol_get_type (void);
G_END_DECLS
#endif /* _THRIFT_COMPACT_PROTOCOL_H */

View file

@ -0,0 +1,140 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_compact_protocol.h>
#include <thrift/c_glib/protocol/thrift_compact_protocol_factory.h>
/* object properties */
enum _ThriftCompactProtocolFactoryProperties
{
PROP_0,
PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT,
PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT
};
G_DEFINE_TYPE (ThriftCompactProtocolFactory, thrift_compact_protocol_factory,
THRIFT_TYPE_PROTOCOL_FACTORY)
ThriftProtocol *
thrift_compact_protocol_factory_get_protocol (ThriftProtocolFactory *factory,
ThriftTransport *transport)
{
ThriftCompactProtocolFactory *tcf;
ThriftCompactProtocol *tc;
tcf = THRIFT_COMPACT_PROTOCOL_FACTORY (factory);
tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL,
"transport", transport,
"string_limit", tcf->string_limit,
"container_limit", tcf->container_limit,
NULL);
return THRIFT_PROTOCOL (tc);
}
/* property accessor */
void
thrift_compact_protocol_factory_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftCompactProtocolFactory *tcf;
THRIFT_UNUSED_VAR (pspec);
tcf = THRIFT_COMPACT_PROTOCOL_FACTORY (object);
switch (property_id) {
case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT:
g_value_set_int (value, tcf->string_limit);
break;
case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT:
g_value_set_int (value, tcf->container_limit);
break;
}
}
/* property mutator */
void
thrift_compact_protocol_factory_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec
*pspec)
{
ThriftCompactProtocolFactory *tcf;
THRIFT_UNUSED_VAR (pspec);
tcf = THRIFT_COMPACT_PROTOCOL_FACTORY (object);
switch (property_id) {
case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT:
tcf->string_limit = g_value_get_int (value);
break;
case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT:
tcf->container_limit = g_value_get_int (value);
break;
}
}
static void
thrift_compact_protocol_factory_class_init (ThriftCompactProtocolFactoryClass
*klass)
{
ThriftProtocolFactoryClass *cls;
GObjectClass *gobject_class;
GParamSpec *param_spec;
cls = THRIFT_PROTOCOL_FACTORY_CLASS (klass);
gobject_class = G_OBJECT_CLASS (klass);
param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_compact_protocol_factory_get_property;
gobject_class->set_property = thrift_compact_protocol_factory_set_property;
param_spec = g_param_spec_int ("string_limit",
"Max allowed string size",
"Set the max string limit",
0, /* min */
G_MAXINT32, /* max */
0, /* default value */
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT,
param_spec);
param_spec = g_param_spec_int ("container_limit",
"Max allowed container size",
"Set the max container limit",
0, /* min */
G_MAXINT32, /* max */
0, /* default value */
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT, param_spec);
cls->get_protocol = thrift_compact_protocol_factory_get_protocol;
}
static void
thrift_compact_protocol_factory_init (ThriftCompactProtocolFactory *factory)
{
THRIFT_UNUSED_VAR (factory);
}

View file

@ -0,0 +1,70 @@
/*
* 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.
*/
#ifndef _THRIFT_COMPACT_PROTOCOL_FACTORY_H
#define _THRIFT_COMPACT_PROTOCOL_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
G_BEGIN_DECLS
/* type macros */
#define THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY \
(thrift_compact_protocol_factory_get_type ())
#define THRIFT_COMPACT_PROTOCOL_FACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY, \
ThriftCompactProtocolFactory))
#define THRIFT_IS_COMPACT_PROTOCOL_FACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY))
#define THRIFT_COMPACT_PROTOCOL_FACTORY_CLASS(c) \
(G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY, \
ThriftCompactProtocolFactoryClass))
#define THRIFT_IS_COMPACT_PROTOCOL_FACTORY_CLASS(c) \
(G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY))
#define THRIFT_COMPACT_PROTOCOL_FACTORY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY, \
ThriftCompactProtocolFactoryClass))
typedef struct _ThriftCompactProtocolFactory ThriftCompactProtocolFactory;
struct _ThriftCompactProtocolFactory
{
ThriftProtocolFactory parent;
/* protected */
gint32 string_limit;
gint32 container_limit;
};
typedef struct _ThriftCompactProtocolFactoryClass
ThriftCompactProtocolFactoryClass;
struct _ThriftCompactProtocolFactoryClass
{
ThriftProtocolFactoryClass parent;
};
/* used by THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY */
GType thrift_compact_protocol_factory_get_type (void);
G_END_DECLS
#endif /* _THRIFT_COMPACT_PROTOCOL_FACTORY_H */

View file

@ -0,0 +1,605 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_transport.h>
/* define the GError domain string */
#define THRIFT_PROTOCOL_ERROR_DOMAIN "thrift-protocol-error-quark"
/* object properties */
enum _ThriftProtocolProperties
{
PROP_0,
PROP_THRIFT_PROTOCOL_TRANSPORT
};
G_DEFINE_ABSTRACT_TYPE(ThriftProtocol, thrift_protocol, G_TYPE_OBJECT)
void
thrift_protocol_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftProtocol *protocol = THRIFT_PROTOCOL (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_PROTOCOL_TRANSPORT:
g_value_set_object (value, protocol->transport);
break;
}
}
void
thrift_protocol_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftProtocol *protocol = THRIFT_PROTOCOL (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_PROTOCOL_TRANSPORT:
protocol->transport = g_value_get_object (value);
break;
}
}
gint32
thrift_protocol_write_message_begin (ThriftProtocol *protocol,
const gchar *name,
const ThriftMessageType message_type,
const gint32 seqid, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_message_begin
(protocol, name,
message_type, seqid,
error);
}
gint32
thrift_protocol_write_message_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_message_end (protocol,
error);
}
gint32
thrift_protocol_write_struct_begin (ThriftProtocol *protocol, const gchar *name,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_struct_begin (protocol,
name, error);
}
gint32
thrift_protocol_write_struct_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_struct_end (protocol,
error);
}
gint32
thrift_protocol_write_field_begin (ThriftProtocol *protocol,
const gchar *name,
const ThriftType field_type,
const gint16 field_id,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_begin (protocol,
name, field_type,
field_id, error);
}
gint32
thrift_protocol_write_field_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_end (protocol,
error);
}
gint32
thrift_protocol_write_field_stop (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_stop (protocol,
error);
}
gint32
thrift_protocol_write_map_begin (ThriftProtocol *protocol,
const ThriftType key_type,
const ThriftType value_type,
const guint32 size, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_map_begin (protocol,
key_type, value_type,
size, error);
}
gint32
thrift_protocol_write_map_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_map_end (protocol,
error);
}
gint32
thrift_protocol_write_list_begin (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_list_begin (protocol,
element_type, size,
error);
}
gint32
thrift_protocol_write_list_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_list_end (protocol,
error);
}
gint32
thrift_protocol_write_set_begin (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_set_begin (protocol,
element_type, size,
error);
}
gint32
thrift_protocol_write_set_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_set_end (protocol,
error);
}
gint32
thrift_protocol_write_bool (ThriftProtocol *protocol,
const gboolean value, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_bool (protocol, value,
error);
}
gint32
thrift_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_byte (protocol, value,
error);
}
gint32
thrift_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i16 (protocol, value,
error);
}
gint32
thrift_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i32 (protocol, value,
error);
}
gint32
thrift_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i64 (protocol, value,
error);
}
gint32
thrift_protocol_write_double (ThriftProtocol *protocol,
const gdouble value, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_double (protocol,
value, error);
}
gint32
thrift_protocol_write_string (ThriftProtocol *protocol,
const gchar *str, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_string (protocol, str,
error);
}
gint32
thrift_protocol_write_binary (ThriftProtocol *protocol, const gpointer buf,
const guint32 len, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_binary (protocol, buf,
len, error);
}
gint32
thrift_protocol_read_message_begin (ThriftProtocol *protocol,
gchar **name,
ThriftMessageType *message_type,
gint32 *seqid, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_message_begin (protocol,
name, message_type,
seqid, error);
}
gint32
thrift_protocol_read_message_end (ThriftProtocol *protocol,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_message_end (protocol,
error);
}
gint32
thrift_protocol_read_struct_begin (ThriftProtocol *protocol,
gchar **name,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_struct_begin (protocol,
name,
error);
}
gint32
thrift_protocol_read_struct_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_struct_end (protocol,
error);
}
gint32
thrift_protocol_read_field_begin (ThriftProtocol *protocol,
gchar **name,
ThriftType *field_type,
gint16 *field_id,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_field_begin (protocol,
name,
field_type,
field_id,
error);
}
gint32
thrift_protocol_read_field_end (ThriftProtocol *protocol,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_field_end (protocol,
error);
}
gint32
thrift_protocol_read_map_begin (ThriftProtocol *protocol,
ThriftType *key_type,
ThriftType *value_type, guint32 *size,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_map_begin (protocol,
key_type,
value_type,
size,
error);
}
gint32
thrift_protocol_read_map_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_map_end (protocol,
error);
}
gint32
thrift_protocol_read_list_begin (ThriftProtocol *protocol,
ThriftType *element_type,
guint32 *size, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_list_begin (protocol,
element_type,
size, error);
}
gint32
thrift_protocol_read_list_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_list_end (protocol,
error);
}
gint32
thrift_protocol_read_set_begin (ThriftProtocol *protocol,
ThriftType *element_type,
guint32 *size, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_set_begin (protocol,
element_type,
size, error);
}
gint32
thrift_protocol_read_set_end (ThriftProtocol *protocol, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_set_end (protocol,
error);
}
gint32
thrift_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_bool (protocol, value,
error);
}
gint32
thrift_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_byte (protocol, value,
error);
}
gint32
thrift_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i16 (protocol, value,
error);
}
gint32
thrift_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i32 (protocol, value,
error);
}
gint32
thrift_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i64 (protocol, value,
error);
}
gint32
thrift_protocol_read_double (ThriftProtocol *protocol,
gdouble *value, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_double (protocol, value,
error);
}
gint32
thrift_protocol_read_string (ThriftProtocol *protocol,
gchar **str, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_string (protocol, str,
error);
}
gint32
thrift_protocol_read_binary (ThriftProtocol *protocol, gpointer *buf,
guint32 *len, GError **error)
{
return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_binary (protocol, buf,
len, error);
}
gint32
thrift_protocol_skip (ThriftProtocol *protocol, ThriftType type, GError **error)
{
switch (type)
{
case T_BOOL:
{
gboolean boolv;
return thrift_protocol_read_bool (protocol, &boolv, error);
}
case T_BYTE:
{
gint8 bytev;
return thrift_protocol_read_byte (protocol, &bytev, error);
}
case T_I16:
{
gint16 i16;
return thrift_protocol_read_i16 (protocol, &i16, error);
}
case T_I32:
{
gint32 i32;
return thrift_protocol_read_i32 (protocol, &i32, error);
}
case T_I64:
{
gint64 i64;
return thrift_protocol_read_i64 (protocol, &i64, error);
}
case T_DOUBLE:
{
gdouble dub;
return thrift_protocol_read_double (protocol, &dub, error);
}
case T_STRING:
{
gpointer data;
guint32 len;
gint32 ret = thrift_protocol_read_binary (protocol, &data, &len, error);
g_free (data);
return ret;
}
case T_STRUCT:
{
guint32 result = 0;
gchar *name;
gint16 fid;
ThriftType ftype;
result += thrift_protocol_read_struct_begin (protocol, &name, error);
while (1)
{
result += thrift_protocol_read_field_begin (protocol, &name, &ftype,
&fid, error);
if (ftype == T_STOP)
{
break;
}
result += thrift_protocol_skip (protocol, ftype, error);
result += thrift_protocol_read_field_end (protocol, error);
}
result += thrift_protocol_read_struct_end (protocol, error);
return result;
}
case T_SET:
{
guint32 result = 0;
ThriftType elem_type;
guint32 i, size;
result += thrift_protocol_read_set_begin (protocol, &elem_type, &size,
error);
for (i = 0; i < size; i++)
{
result += thrift_protocol_skip (protocol, elem_type, error);
}
result += thrift_protocol_read_set_end (protocol, error);
return result;
}
case T_MAP:
{
guint32 result = 0;
ThriftType elem_type;
ThriftType key_type;
guint32 i, size;
result += thrift_protocol_read_map_begin (protocol, &key_type, &elem_type, &size,
error);
for (i = 0; i < size; i++)
{
result += thrift_protocol_skip (protocol, key_type, error);
result += thrift_protocol_skip (protocol, elem_type, error);
}
result += thrift_protocol_read_map_end (protocol, error);
return result;
}
case T_LIST:
{
guint32 result = 0;
ThriftType elem_type;
guint32 i, size;
result += thrift_protocol_read_list_begin (protocol, &elem_type, &size,
error);
for (i = 0; i < size; i++)
{
result += thrift_protocol_skip (protocol, elem_type, error);
}
result += thrift_protocol_read_list_end (protocol, error);
return result;
}
default:
return 0;
}
}
/* define the GError domain for Thrift protocols */
GQuark
thrift_protocol_error_quark (void)
{
return g_quark_from_static_string (THRIFT_PROTOCOL_ERROR_DOMAIN);
}
static void
thrift_protocol_init (ThriftProtocol *protocol)
{
protocol->transport = NULL;
}
static void
thrift_protocol_class_init (ThriftProtocolClass *cls)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
gobject_class->get_property = thrift_protocol_get_property;
gobject_class->set_property = thrift_protocol_set_property;
g_object_class_install_property (gobject_class,
PROP_THRIFT_PROTOCOL_TRANSPORT,
g_param_spec_object ("transport", "Transport", "Thrift Transport",
THRIFT_TYPE_TRANSPORT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
cls->write_message_begin = thrift_protocol_write_message_begin;
cls->write_message_end = thrift_protocol_write_message_end;
cls->write_struct_begin = thrift_protocol_write_struct_begin;
cls->write_struct_end = thrift_protocol_write_struct_end;
cls->write_field_begin = thrift_protocol_write_field_begin;
cls->write_field_end = thrift_protocol_write_field_end;
cls->write_field_stop = thrift_protocol_write_field_stop;
cls->write_map_begin = thrift_protocol_write_map_begin;
cls->write_map_end = thrift_protocol_write_map_end;
cls->write_list_begin = thrift_protocol_write_list_begin;
cls->write_list_end = thrift_protocol_write_list_end;
cls->write_set_begin = thrift_protocol_write_set_begin;
cls->write_set_end = thrift_protocol_write_set_end;
cls->write_bool = thrift_protocol_write_bool;
cls->write_byte = thrift_protocol_write_byte;
cls->write_i16 = thrift_protocol_write_i16;
cls->write_i32 = thrift_protocol_write_i32;
cls->write_i64 = thrift_protocol_write_i64;
cls->write_double = thrift_protocol_write_double;
cls->write_string = thrift_protocol_write_string;
cls->write_binary = thrift_protocol_write_binary;
cls->read_message_begin = thrift_protocol_read_message_begin;
cls->read_message_end = thrift_protocol_read_message_end;
cls->read_struct_begin = thrift_protocol_read_struct_begin;
cls->read_struct_end = thrift_protocol_read_struct_end;
cls->read_field_begin = thrift_protocol_read_field_begin;
cls->read_field_end = thrift_protocol_read_field_end;
cls->read_map_begin = thrift_protocol_read_map_begin;
cls->read_map_end = thrift_protocol_read_map_end;
cls->read_list_begin = thrift_protocol_read_list_begin;
cls->read_set_begin = thrift_protocol_read_set_begin;
cls->read_set_end = thrift_protocol_read_set_end;
cls->read_bool = thrift_protocol_read_bool;
cls->read_byte = thrift_protocol_read_byte;
cls->read_i16 = thrift_protocol_read_i16;
cls->read_i32 = thrift_protocol_read_i32;
cls->read_i64 = thrift_protocol_read_i64;
cls->read_double = thrift_protocol_read_double;
cls->read_string = thrift_protocol_read_string;
cls->read_binary = thrift_protocol_read_binary;
}

View file

@ -0,0 +1,341 @@
/*
* 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.
*/
#ifndef _THRIFT_PROTOCOL_H
#define _THRIFT_PROTOCOL_H
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_protocol.h
* \brief Abstract class for Thrift protocol implementations.
*/
/**
* Enumerated definition of the types that the Thrift protocol supports.
* Take special note of the T_END type which is used specifically to mark
* the end of a sequence of fields.
*/
typedef enum {
T_STOP = 0,
T_VOID = 1,
T_BOOL = 2,
T_BYTE = 3,
T_I08 = 3,
T_I16 = 6,
T_I32 = 8,
T_U64 = 9,
T_I64 = 10,
T_DOUBLE = 4,
T_STRING = 11,
T_UTF7 = 11,
T_STRUCT = 12,
T_MAP = 13,
T_SET = 14,
T_LIST = 15,
T_UTF8 = 16,
T_UTF16 = 17
} ThriftType;
/**
* Enumerated definition of the message types that the Thrift protocol
* supports.
*/
typedef enum {
T_CALL = 1,
T_REPLY = 2,
T_EXCEPTION = 3,
T_ONEWAY = 4
} ThriftMessageType;
/* type macros */
#define THRIFT_TYPE_PROTOCOL (thrift_protocol_get_type ())
#define THRIFT_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL, ThriftProtocol))
#define THRIFT_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL))
#define THRIFT_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL, ThriftProtocolClass))
#define THRIFT_IS_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL))
#define THRIFT_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL, ThriftProtocolClass))
typedef struct _ThriftProtocol ThriftProtocol;
/*!
* Thrift Protocol object
*/
struct _ThriftProtocol
{
GObject parent;
/* protected */
ThriftTransport *transport;
};
typedef struct _ThriftProtocolClass ThriftProtocolClass;
/*!
* Thrift Protocol class
*/
struct _ThriftProtocolClass
{
GObjectClass parent;
gint32 (*write_message_begin) (ThriftProtocol *protocol, const gchar *name,
const ThriftMessageType message_type,
const gint32 seqid, GError **error);
gint32 (*write_message_end) (ThriftProtocol *protocol, GError **error);
gint32 (*write_struct_begin) (ThriftProtocol *protocol, const gchar *name,
GError **error);
gint32 (*write_struct_end) (ThriftProtocol *protocol, GError **error);
gint32 (*write_field_begin) (ThriftProtocol *protocol, const gchar *name,
const ThriftType field_type,
const gint16 field_id, GError **error);
gint32 (*write_field_end) (ThriftProtocol *protocol, GError **error);
gint32 (*write_field_stop) (ThriftProtocol *protocol, GError **error);
gint32 (*write_map_begin) (ThriftProtocol *protocol,
const ThriftType key_type,
const ThriftType value_type,
const guint32 size, GError **error);
gint32 (*write_map_end) (ThriftProtocol *protocol, GError **error);
gint32 (*write_list_begin) (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size, GError **error);
gint32 (*write_list_end) (ThriftProtocol *protocol, GError **error);
gint32 (*write_set_begin) (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size, GError **error);
gint32 (*write_set_end) (ThriftProtocol *protocol, GError **error);
gint32 (*write_bool) (ThriftProtocol *protocol, const gboolean value,
GError **error);
gint32 (*write_byte) (ThriftProtocol *protocol, const gint8 value,
GError **error);
gint32 (*write_i16) (ThriftProtocol *protocol, const gint16 value,
GError **error);
gint32 (*write_i32) (ThriftProtocol *protocol, const gint32 value,
GError **error);
gint32 (*write_i64) (ThriftProtocol *protocol, const gint64 value,
GError **error);
gint32 (*write_double) (ThriftProtocol *protocol, const gdouble value,
GError **error);
gint32 (*write_string) (ThriftProtocol *protocol, const gchar *str,
GError **error);
gint32 (*write_binary) (ThriftProtocol *protocol, const gpointer buf,
const guint32 len, GError **error);
gint32 (*read_message_begin) (ThriftProtocol *thrift_protocol, gchar **name,
ThriftMessageType *message_type,
gint32 *seqid, GError **error);
gint32 (*read_message_end) (ThriftProtocol *protocol, GError **error);
gint32 (*read_struct_begin) (ThriftProtocol *protocol, gchar **name,
GError **error);
gint32 (*read_struct_end) (ThriftProtocol *protocol, GError **error);
gint32 (*read_field_begin) (ThriftProtocol *protocol, gchar **name,
ThriftType *field_type, gint16 *field_id,
GError **error);
gint32 (*read_field_end) (ThriftProtocol *protocol, GError **error);
gint32 (*read_map_begin) (ThriftProtocol *protocol, ThriftType *key_type,
ThriftType *value_type, guint32 *size,
GError **error);
gint32 (*read_map_end) (ThriftProtocol *protocol, GError **error);
gint32 (*read_list_begin) (ThriftProtocol *protocol, ThriftType *element_type,
guint32 *size, GError **error);
gint32 (*read_list_end) (ThriftProtocol *protocol, GError **error);
gint32 (*read_set_begin) (ThriftProtocol *protocol, ThriftType *element_type,
guint32 *size, GError **error);
gint32 (*read_set_end) (ThriftProtocol *protocol, GError **error);
gint32 (*read_bool) (ThriftProtocol *protocol, gboolean *value,
GError **error);
gint32 (*read_byte) (ThriftProtocol *protocol, gint8 *value, GError **error);
gint32 (*read_i16) (ThriftProtocol *protocol, gint16 *value, GError **error);
gint32 (*read_i32) (ThriftProtocol *protocol, gint32 *value, GError **error);
gint32 (*read_i64) (ThriftProtocol *protocol, gint64 *value, GError **error);
gint32 (*read_double) (ThriftProtocol *protocol, gdouble *value,
GError **error);
gint32 (*read_string) (ThriftProtocol *protocol, gchar **str, GError **error);
gint32 (*read_binary) (ThriftProtocol *protocol, gpointer *buf,
guint32 *len, GError **error);
};
/* used by THRIFT_TYPE_PROTOCOL */
GType thrift_protocol_get_type (void);
/* virtual public methods */
gint32 thrift_protocol_write_message_begin (ThriftProtocol *protocol,
const gchar *name, const ThriftMessageType message_type,
const gint32 seqid, GError **error);
gint32 thrift_protocol_write_message_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_write_struct_begin (ThriftProtocol *protocol,
const gchar *name,
GError **error);
gint32 thrift_protocol_write_struct_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_write_field_begin (ThriftProtocol *protocol,
const gchar *name,
const ThriftType field_type,
const gint16 field_id,
GError **error);
gint32 thrift_protocol_write_field_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_write_field_stop (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_write_map_begin (ThriftProtocol *protocol,
const ThriftType key_type,
const ThriftType value_type,
const guint32 size, GError **error);
gint32 thrift_protocol_write_map_end (ThriftProtocol *protocol, GError **error);
gint32 thrift_protocol_write_list_begin (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size, GError **error);
gint32 thrift_protocol_write_list_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_write_set_begin (ThriftProtocol *protocol,
const ThriftType element_type,
const guint32 size, GError **error);
gint32 thrift_protocol_write_set_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_write_bool (ThriftProtocol *protocol,
const gboolean value, GError **error);
gint32 thrift_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
GError **error);
gint32 thrift_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
GError **error);
gint32 thrift_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
GError **error);
gint32 thrift_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
GError **error);
gint32 thrift_protocol_write_double (ThriftProtocol *protocol,
const gdouble value, GError **error);
gint32 thrift_protocol_write_string (ThriftProtocol *protocol,
const gchar *str, GError **error);
gint32 thrift_protocol_write_binary (ThriftProtocol *protocol,
const gpointer buf,
const guint32 len, GError **error);
gint32 thrift_protocol_read_message_begin (ThriftProtocol *thrift_protocol,
gchar **name,
ThriftMessageType *message_type,
gint32 *seqid, GError **error);
gint32 thrift_protocol_read_message_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_read_struct_begin (ThriftProtocol *protocol,
gchar **name,
GError **error);
gint32 thrift_protocol_read_struct_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_read_field_begin (ThriftProtocol *protocol,
gchar **name,
ThriftType *field_type,
gint16 *field_id,
GError **error);
gint32 thrift_protocol_read_field_end (ThriftProtocol *protocol,
GError **error);
gint32 thrift_protocol_read_map_begin (ThriftProtocol *protocol,
ThriftType *key_type,
ThriftType *value_type, guint32 *size,
GError **error);
gint32 thrift_protocol_read_map_end (ThriftProtocol *protocol, GError **error);
gint32 thrift_protocol_read_list_begin (ThriftProtocol *protocol,
ThriftType *element_type,
guint32 *size, GError **error);
gint32 thrift_protocol_read_list_end (ThriftProtocol *protocol, GError **error);
gint32 thrift_protocol_read_set_begin (ThriftProtocol *protocol,
ThriftType *element_type,
guint32 *size, GError **error);
gint32 thrift_protocol_read_set_end (ThriftProtocol *protocol, GError **error);
gint32 thrift_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
GError **error);
gint32 thrift_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
GError **error);
gint32 thrift_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
GError **error);
gint32 thrift_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
GError **error);
gint32 thrift_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
GError **error);
gint32 thrift_protocol_read_double (ThriftProtocol *protocol,
gdouble *value, GError **error);
gint32 thrift_protocol_read_string (ThriftProtocol *protocol,
gchar **str, GError **error);
gint32 thrift_protocol_read_binary (ThriftProtocol *protocol,
gpointer *buf, guint32 *len,
GError **error);
gint32 thrift_protocol_skip (ThriftProtocol *protocol, ThriftType type,
GError **error);
/* define error types */
typedef enum
{
THRIFT_PROTOCOL_ERROR_UNKNOWN,
THRIFT_PROTOCOL_ERROR_INVALID_DATA,
THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
THRIFT_PROTOCOL_ERROR_BAD_VERSION,
THRIFT_PROTOCOL_ERROR_NOT_IMPLEMENTED,
THRIFT_PROTOCOL_ERROR_DEPTH_LIMIT
} ThriftProtocolError;
/* define an error domain for GError to use */
GQuark thrift_protocol_error_quark (void);
#define THRIFT_PROTOCOL_ERROR (thrift_protocol_error_quark ())
G_END_DECLS
#endif /* _THRIFT_PROTOCOL_H */

View file

@ -0,0 +1,43 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
G_DEFINE_ABSTRACT_TYPE(ThriftProtocolFactory, thrift_protocol_factory, G_TYPE_OBJECT)
ThriftProtocol *
thrift_protocol_factory_get_protocol(ThriftProtocolFactory *factory,
ThriftTransport *transport)
{
return THRIFT_PROTOCOL_FACTORY_GET_CLASS (factory)->get_protocol (factory,
transport);
}
static void
thrift_protocol_factory_init (ThriftProtocolFactory *factory)
{
THRIFT_UNUSED_VAR (factory);
}
static void
thrift_protocol_factory_class_init (ThriftProtocolFactoryClass *cls)
{
cls->get_protocol = thrift_protocol_factory_get_protocol;
}

View file

@ -0,0 +1,73 @@
/*
* 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.
*/
#ifndef _THRIFT_PROTOCOL_FACTORY_H
#define _THRIFT_PROTOCOL_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
G_BEGIN_DECLS
/*! \file thrift_protocol_factory.h
* \brief Abstract class for Thrift protocol factory implementations.
*/
/* type macros */
#define THRIFT_TYPE_PROTOCOL_FACTORY (thrift_protocol_factory_get_type ())
#define THRIFT_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL_FACTORY, ThriftProtocolFactory))
#define THRIFT_IS_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL_FACTORY))
#define THRIFT_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL_FACTORY, ThriftProtocolFactoryClass))
#define THRIFT_IS_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL_FACTORY))
#define THRIFT_PROTOCOL_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL_FACTORY, ThriftProtocolFactoryClass))
typedef struct _ThriftProtocolFactory ThriftProtocolFactory;
/*!
* Thrift Protocol Factory object
*/
struct _ThriftProtocolFactory
{
GObject parent;
};
typedef struct _ThriftProtocolFactoryClass ThriftProtocolFactoryClass;
/*!
* Thrift Protocol Factory class
*/
struct _ThriftProtocolFactoryClass
{
GObjectClass parent;
ThriftProtocol *(*get_protocol) (ThriftProtocolFactory *factory,
ThriftTransport *transport);
};
/* used by THRIFT_TYPE_PROTOCOL_FACTORY */
GType thrift_protocol_factory_get_type (void);
/* virtual public methods */
ThriftProtocol *thrift_protocol_factory_get_protocol(ThriftProtocolFactory *factory, ThriftTransport *transport);
G_END_DECLS
#endif /* _THRIFT_PROTOCOL_FACTORY_H */

View file

@ -0,0 +1,174 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include "thrift_server.h"
/* object properties */
enum _ThriftServerProperties
{
PROP_0,
PROP_THRIFT_SERVER_PROCESSOR,
PROP_THRIFT_SERVER_SERVER_TRANSPORT,
PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY,
PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY,
PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY,
PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY
};
G_DEFINE_ABSTRACT_TYPE(ThriftServer, thrift_server, G_TYPE_OBJECT)
void
thrift_server_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftServer *server = THRIFT_SERVER (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_SERVER_PROCESSOR:
g_value_set_object (value, server->processor);
break;
case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
g_value_set_object (value, server->server_transport);
break;
case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
g_value_set_object (value, server->input_transport_factory);
break;
case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
g_value_set_object (value, server->output_transport_factory);
break;
case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
g_value_set_object (value, server->input_protocol_factory);
break;
case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
g_value_set_object (value, server->output_protocol_factory);
break;
}
}
void
thrift_server_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftServer *server = THRIFT_SERVER (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_SERVER_PROCESSOR:
server->processor = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
server->server_transport = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
server->input_transport_factory = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
server->output_transport_factory = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
server->input_protocol_factory = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
server->output_protocol_factory = g_value_get_object (value);
break;
}
}
gboolean
thrift_server_serve (ThriftServer *server, GError **error)
{
return THRIFT_SERVER_GET_CLASS (server)->serve (server, error);
}
void
thrift_server_stop (ThriftServer *server)
{
THRIFT_SERVER_GET_CLASS (server)->stop (server);
}
/* instance initializer for Thrift Server */
static void
thrift_server_init (ThriftServer *server)
{
server->processor = NULL;
server->server_transport = NULL;
server->input_transport_factory = NULL;
server->output_transport_factory = NULL;
server->input_protocol_factory = NULL;
server->output_protocol_factory = NULL;
}
/* class initializer for ThriftServer
* TODO: implement ServerEventHandler as a GClosure
*/
static void
thrift_server_class_init (ThriftServerClass *cls)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
gobject_class->get_property = thrift_server_get_property;
gobject_class->set_property = thrift_server_set_property;
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_PROCESSOR,
g_param_spec_object ("processor", "Processor", "Thrift Processor",
THRIFT_TYPE_PROCESSOR,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_SERVER_TRANSPORT,
g_param_spec_object ("server_transport", "Server Transport",
"Thrift Server Transport",
THRIFT_TYPE_SERVER_TRANSPORT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY,
g_param_spec_object ("input_transport_factory", "Input Transport Factory",
"Thrift Server Input Transport Factory",
THRIFT_TYPE_TRANSPORT_FACTORY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY,
g_param_spec_object ("output_transport_factory",
"Output Transport Factory",
"Thrift Server Output Transport Factory",
THRIFT_TYPE_TRANSPORT_FACTORY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY,
g_param_spec_object ("input_protocol_factory", "Input Protocol Factory",
"Thrift Server Input Protocol Factory",
THRIFT_TYPE_PROTOCOL_FACTORY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY,
g_param_spec_object ("output_protocol_factory", "Output Protocol Factory",
"Thrift Server Output Protocol Factory",
THRIFT_TYPE_PROTOCOL_FACTORY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* set these as virtual methods to be implemented by a subclass */
cls->serve = thrift_server_serve;
cls->stop = thrift_server_stop;
}

View file

@ -0,0 +1,93 @@
/*
* 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.
*/
#ifndef _THRIFT_SERVER_H
#define _THRIFT_SERVER_H
#include <glib-object.h>
#include <thrift/c_glib/processor/thrift_processor.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
G_BEGIN_DECLS
/*! \file thrift_server.h
* \brief Abstract class for Thrift servers.
*/
/* type macros */
#define THRIFT_TYPE_SERVER (thrift_server_get_type ())
#define THRIFT_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SERVER, ThriftServer))
#define THRIFT_IS_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SERVER))
#define THRIFT_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SERVER, ThriftServerClass))
#define THRIFT_IS_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SERVER))
#define THRIFT_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SERVER, ThriftServerClass))
typedef struct _ThriftServer ThriftServer;
/*!
* Thrift Server object
*/
struct _ThriftServer
{
GObject parent;
/* protected */
ThriftProcessor *processor;
ThriftServerTransport *server_transport;
ThriftTransportFactory *input_transport_factory;
ThriftTransportFactory *output_transport_factory;
ThriftProtocolFactory *input_protocol_factory;
ThriftProtocolFactory *output_protocol_factory;
};
typedef struct _ThriftServerClass ThriftServerClass;
/*!
* Thrift Server class
*/
struct _ThriftServerClass
{
GObjectClass parent;
/* vtable */
gboolean (*serve) (ThriftServer *server, GError **error);
void (*stop) (ThriftServer *server);
};
/* used by THRIFT_TYPE_SERVER */
GType thrift_server_get_type (void);
/*!
* Processes the request.
* \public \memberof ThriftServerClass
*/
gboolean thrift_server_serve (ThriftServer *server, GError **error);
/*!
* Stop handling requests.
*/
void thrift_server_stop (ThriftServer *server);
G_END_DECLS
#endif /* _THRIFT_SERVER_H */

View file

@ -0,0 +1,138 @@
/*
* 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 <thrift/c_glib/server/thrift_simple_server.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
G_DEFINE_TYPE(ThriftSimpleServer, thrift_simple_server, THRIFT_TYPE_SERVER)
gboolean
thrift_simple_server_serve (ThriftServer *server, GError **error)
{
ThriftTransport *t = NULL;
ThriftTransport *input_transport = NULL, *output_transport = NULL;
ThriftProtocol *input_protocol = NULL, *output_protocol = NULL;
ThriftSimpleServer *tss = THRIFT_SIMPLE_SERVER(server);
GError *process_error = NULL;
g_return_val_if_fail (THRIFT_IS_SIMPLE_SERVER (server), FALSE);
if (thrift_server_transport_listen (server->server_transport, error)) {
tss->running = TRUE;
while (tss->running == TRUE)
{
t = thrift_server_transport_accept (server->server_transport,
error);
if (t != NULL && tss->running) {
input_transport =
THRIFT_TRANSPORT_FACTORY_GET_CLASS (server->input_transport_factory)
->get_transport (server->input_transport_factory, t);
output_transport =
THRIFT_TRANSPORT_FACTORY_GET_CLASS (server->output_transport_factory)
->get_transport (server->output_transport_factory, t);
input_protocol =
THRIFT_PROTOCOL_FACTORY_GET_CLASS (server->input_protocol_factory)
->get_protocol (server->input_protocol_factory, input_transport);
output_protocol =
THRIFT_PROTOCOL_FACTORY_GET_CLASS (server->output_protocol_factory)
->get_protocol (server->output_protocol_factory, output_transport);
while (THRIFT_PROCESSOR_GET_CLASS (server->processor)
->process (server->processor,
input_protocol,
output_protocol,
&process_error) &&
thrift_transport_peek (input_transport, &process_error))
{
}
if (process_error != NULL)
{
g_message ("thrift_simple_server_serve: %s", process_error->message);
g_clear_error (&process_error);
/* Note we do not propagate processing errors to the caller as they
* normally are transient and not fatal to the server */
}
/* TODO: handle exceptions */
THRIFT_TRANSPORT_GET_CLASS (input_transport)->close (input_transport,
NULL);
THRIFT_TRANSPORT_GET_CLASS (output_transport)->close (output_transport,
NULL);
}
}
/* attempt to shutdown */
THRIFT_SERVER_TRANSPORT_GET_CLASS (server->server_transport)
->close (server->server_transport, NULL);
}
/* Since this method is designed to run forever, it can only ever return on
* error */
return FALSE;
}
void
thrift_simple_server_stop (ThriftServer *server)
{
g_return_if_fail (THRIFT_IS_SIMPLE_SERVER (server));
(THRIFT_SIMPLE_SERVER (server))->running = FALSE;
}
static void
thrift_simple_server_init (ThriftSimpleServer *tss)
{
ThriftServer *server = THRIFT_SERVER(tss);
tss->running = FALSE;
if (server->input_transport_factory == NULL)
{
server->input_transport_factory =
g_object_new (THRIFT_TYPE_TRANSPORT_FACTORY, NULL);
}
if (server->output_transport_factory == NULL)
{
server->output_transport_factory =
g_object_new (THRIFT_TYPE_TRANSPORT_FACTORY, NULL);
}
if (server->input_protocol_factory == NULL)
{
server->input_protocol_factory =
g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL);
}
if (server->output_protocol_factory == NULL)
{
server->output_protocol_factory =
g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL);
}
}
/* initialize the class */
static void
thrift_simple_server_class_init (ThriftSimpleServerClass *class)
{
ThriftServerClass *cls = THRIFT_SERVER_CLASS(class);
cls->serve = thrift_simple_server_serve;
cls->stop = thrift_simple_server_stop;
}

View file

@ -0,0 +1,70 @@
/*
* 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.
*/
#ifndef _THRIFT_SIMPLE_SERVER_H
#define _THRIFT_SIMPLE_SERVER_H
#include <glib-object.h>
#include <thrift/c_glib/server/thrift_server.h>
G_BEGIN_DECLS
/*! \file thrift_simple_server.h
* \brief A simple Thrift server, single-threaded.
*/
/* type macros */
#define THRIFT_TYPE_SIMPLE_SERVER (thrift_simple_server_get_type ())
#define THRIFT_SIMPLE_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SIMPLE_SERVER, ThriftSimpleServer))
#define THRIFT_IS_SIMPLE_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SIMPLE_SERVER))
#define THRIFT_SIMPLE_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c) THRIFT_TYPE_SIMPLE_SERVER, ThriftSimpleServerClass))
#define THRIFT_IS_SIMPLE_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SIMPLE_SERVER))
#define THRIFT_SIMPLE_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SIMPLE_SERVER, ThriftSimpleServerClass))
typedef struct _ThriftSimpleServer ThriftSimpleServer;
/**
* Thrift Simple Server instance.
*/
struct _ThriftSimpleServer
{
ThriftServer parent;
/* private */
volatile gboolean running;
};
typedef struct _ThriftSimpleServerClass ThriftSimpleServerClass;
/**
* Thrift Simple Server class.
*/
struct _ThriftSimpleServerClass
{
ThriftServerClass parent;
};
/* used by THRIFT_TYPE_SIMPLE_SERVER */
GType thrift_simple_server_get_type (void);
G_END_DECLS
#endif /* _THRIFT_SIMPLE_SERVER_H */

View file

@ -0,0 +1,101 @@
/*
* 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 <thrift/c_glib/thrift.h>
/**
* GHashTable callback to add keys to a GList.
*/
void
thrift_hash_table_get_keys (gpointer key, gpointer value, gpointer user_data)
{
GList **list = (GList **) user_data;
THRIFT_UNUSED_VAR (value);
*list = g_list_append (*list, key);
}
void thrift_safe_hash_table_destroy(GHashTable* hash_table)
{
if (hash_table)
{
g_hash_table_destroy(hash_table);
}
}
guint thrift_boolean_hash(gconstpointer v)
{
const gboolean* p = v;
return p && *p ? 1 : 0;
}
gboolean thrift_boolean_equal(gconstpointer a, gconstpointer b)
{
if (a == b) {
return TRUE;
}
if (!a || !b) {
return FALSE;
}
const gboolean* pa = a;
const gboolean* pb = b;
return *pa == *pb;
}
guint thrift_int8_hash(gconstpointer v)
{
const gint8* p = v;
return p ? *p : 0;
}
gboolean thrift_int8_equal(gconstpointer a, gconstpointer b)
{
if (a == b) {
return TRUE;
}
if (!a || !b) {
return FALSE;
}
const gint8* pa = a;
const gint8* pb = b;
return *pa == *pb;
}
guint thrift_int16_hash(gconstpointer v)
{
const gint16* p = v;
return p ? *p : 0;
}
gboolean thrift_int16_equal(gconstpointer a, gconstpointer b)
{
if (a == b) {
return TRUE;
}
if (!a || !b) {
return FALSE;
}
const gint16* pa = a;
const gint16* pb = b;
return *pa == *pb;
}
void
thrift_string_free (gpointer str)
{
GByteArray* ptr = str;
g_byte_array_unref(ptr);
}

View file

@ -0,0 +1,49 @@
/*
* 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.
*/
#ifndef _THRIFT_H
#define _THRIFT_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <glib.h>
/* this macro is called to satisfy -Wall hardcore compilation */
#ifndef THRIFT_UNUSED_VAR
# define THRIFT_UNUSED_VAR(x) ((void) x)
#endif
void thrift_hash_table_get_keys (gpointer key, gpointer value,
gpointer user_data);
void thrift_safe_hash_table_destroy(GHashTable* hash_table);
guint thrift_boolean_hash(gconstpointer v);
gboolean thrift_boolean_equal(gconstpointer a, gconstpointer b);
guint thrift_int8_hash(gconstpointer v);
gboolean thrift_int8_equal(gconstpointer a, gconstpointer b);
guint thrift_int16_hash(gconstpointer v);
gboolean thrift_int16_equal(gconstpointer a, gconstpointer b);
void thrift_string_free (gpointer str);
#endif /* #ifndef _THRIFT_THRIFT_H */

View file

@ -0,0 +1,277 @@
/*
* 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 "thrift_application_exception.h"
#include <thrift/c_glib/protocol/thrift_protocol.h>
/* object properties */
enum _ThriftApplicationExceptionProperties
{
PROP_0,
PROP_THRIFT_APPLICATION_EXCEPTION_TYPE,
PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE
};
G_DEFINE_TYPE(ThriftApplicationException, thrift_application_exception, THRIFT_TYPE_STRUCT)
gint32
thrift_application_exception_read (ThriftStruct *object,
ThriftProtocol *protocol, GError **error)
{
gint32 ret;
gint32 xfer = 0;
gchar *name;
ThriftType ftype;
gint16 fid;
ThriftApplicationException *this = THRIFT_APPLICATION_EXCEPTION (object);
/* read the struct begin marker */
if ((ret = thrift_protocol_read_struct_begin (protocol, &name, error)) < 0)
{
if (name) g_free (name);
return -1;
}
xfer += ret;
if (name) g_free (name);
while (1)
{
if ((ret = thrift_protocol_read_field_begin (protocol, &name, &ftype,
&fid, error)) < 0)
{
if (name) g_free (name);
return -1;
}
xfer += ret;
if (name) g_free (name);
/* break if we get a STOP field */
if (ftype == T_STOP)
{
break;
}
switch (fid)
{
case 1:
if (ftype == T_STRING)
{
if ((ret = thrift_protocol_read_string (protocol, &this->message,
error)) < 0)
return -1;
xfer += ret;
this->__isset_message = TRUE;
} else {
if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)
return -1;
xfer += ret;
}
break;
case 2:
if (ftype == T_I32)
{
if ((ret = thrift_protocol_read_i32 (protocol, &this->type,
error)) < 0)
return -1;
xfer += ret;
this->__isset_type = TRUE;
} else {
if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)
return -1;
xfer += ret;
}
break;
default:
if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)
return -1;
xfer += ret;
break;
}
if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0)
return -1;
xfer += ret;
}
if ((ret = thrift_protocol_read_struct_end (protocol, error)) < 0)
return -1;
xfer += ret;
return xfer;
}
gint32
thrift_application_exception_write (ThriftStruct *object,
ThriftProtocol *protocol, GError **error)
{
gint32 ret;
gint32 xfer = 0;
ThriftApplicationException *this = THRIFT_APPLICATION_EXCEPTION (object);
if ((ret = thrift_protocol_write_struct_begin (protocol,
"TApplicationException",
error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_field_begin (protocol, "message",
T_STRING, 1, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_string (protocol, this->message, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_field_begin (protocol, "type",
T_I32, 2, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_i32 (protocol, this->type, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0)
return -1;
xfer += ret;
if ((ret = thrift_protocol_write_struct_end (protocol, error)) < 0)
return -1;
xfer += ret;
return xfer;
}
/* GError domain */
#define THRIFT_APPLICATION_EXCEPTION_ERROR_DOMAIN "thrift-application-exception-error-quark"
GQuark
thrift_application_exception_error_quark (void)
{
return g_quark_from_static_string (THRIFT_APPLICATION_EXCEPTION_ERROR_DOMAIN);
}
static void
thrift_application_exception_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object);
switch (property_id)
{
case PROP_THRIFT_APPLICATION_EXCEPTION_TYPE:
g_value_set_int (value, tae->type);
break;
case PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE:
g_value_set_string (value, tae->message);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
thrift_application_exception_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object);
switch (property_id)
{
case PROP_THRIFT_APPLICATION_EXCEPTION_TYPE:
tae->type = g_value_get_int (value);
tae->__isset_type = TRUE;
break;
case PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE:
if (tae->message != NULL)
g_free (tae->message);
tae->message = g_value_dup_string (value);
tae->__isset_message = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
void
thrift_application_exception_init (ThriftApplicationException *object)
{
object->type = 0;
object->__isset_type = FALSE;
object->message = NULL;
object->__isset_message = FALSE;
}
void
thrift_application_exception_finalize (GObject *object)
{
ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object);
if (tae->__isset_message) {
g_free(tae->message);
}
}
void
thrift_application_exception_class_init (ThriftApplicationExceptionClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
ThriftStructClass *cls = THRIFT_STRUCT_CLASS(class);
GParamSpec *param_spec;
cls->read = thrift_application_exception_read;
cls->write = thrift_application_exception_write;
gobject_class->finalize = thrift_application_exception_finalize;
gobject_class->get_property = thrift_application_exception_get_property;
gobject_class->set_property = thrift_application_exception_set_property;
param_spec = g_param_spec_int ("type",
"Exception type",
"The type of the exception, one of the "
"values defined by the "
"ThriftApplicationExceptionError "
"enumeration.",
0,
THRIFT_APPLICATION_EXCEPTION_ERROR_N - 1,
0,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_APPLICATION_EXCEPTION_TYPE,
param_spec);
param_spec = g_param_spec_string ("message",
"Exception message",
"A string describing the exception that "
"occurred.",
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE,
param_spec);
}

View file

@ -0,0 +1,86 @@
/*
* 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.
*/
#ifndef _THRIFT_APPLICATION_EXCEPTION_H
#define _THRIFT_APPLICATION_EXCEPTION_H
#include <glib-object.h>
#include "thrift_struct.h"
G_BEGIN_DECLS
/*! \file thrift_application_exception.h
* \brief C Implementation of a TApplicationException.
*/
/* type macros */
#define THRIFT_TYPE_APPLICATION_EXCEPTION (thrift_application_exception_get_type ())
#define THRIFT_APPLICATION_EXCEPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_APPLICATION_EXCEPTION, ThriftApplicationException))
#define THRIFT_IS_APPLICATION_EXCEPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_APPLICATION_EXCEPTION))
#define THRIFT_APPLICATION_EXCEPTION_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_APPLICATION_EXCEPTION, ThriftApplicationExceptionClass))
#define THRIFT_IS_APPLICATION_EXCEPTION_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_APPLICATION_EXCEPTION))
#define THRIFT_APPLICATION_EXCEPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_APPLICATION_EXCEPTION, ThriftApplicationExceptionClass))
typedef struct _ThriftApplicationException ThriftApplicationException;
struct _ThriftApplicationException
{
ThriftStruct parent;
/* private */
gint32 type;
gboolean __isset_type;
gchar *message;
gboolean __isset_message;
};
typedef struct _ThriftApplicationExceptionClass ThriftApplicationExceptionClass;
struct _ThriftApplicationExceptionClass
{
ThriftStructClass parent;
};
GType thrift_application_exception_get_type (void);
/* gerror codes */
typedef enum
{
THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN,
THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD,
THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE,
THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME,
THRIFT_APPLICATION_EXCEPTION_ERROR_BAD_SEQUENCE_ID,
THRIFT_APPLICATION_EXCEPTION_ERROR_MISSING_RESULT,
THRIFT_APPLICATION_EXCEPTION_ERROR_INTERNAL_ERROR,
THRIFT_APPLICATION_EXCEPTION_ERROR_PROTOCOL_ERROR,
THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_TRANSFORM,
THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_PROTOCOL,
THRIFT_APPLICATION_EXCEPTION_ERROR_UNSUPPORTED_CLIENT_TYPE,
THRIFT_APPLICATION_EXCEPTION_ERROR_N
} ThriftApplicationExceptionError;
/* define error domain for GError */
GQuark thrift_application_exception_error_quark (void);
#define THRIFT_APPLICATION_EXCEPTION_ERROR (thrift_application_exception_error_quark ())
G_END_DECLS
#endif /* _THRIFT_APPLICATION_EXCEPTION_H */

View file

@ -0,0 +1,52 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include "thrift_struct.h"
G_DEFINE_ABSTRACT_TYPE(ThriftStruct, thrift_struct, G_TYPE_OBJECT)
gint32
thrift_struct_read (ThriftStruct *object, ThriftProtocol *protocol,
GError **error)
{
g_return_val_if_fail (THRIFT_IS_STRUCT (object), -1);
return THRIFT_STRUCT_GET_CLASS (object)->read (object, protocol, error);
}
gint32
thrift_struct_write (ThriftStruct *object, ThriftProtocol *protocol,
GError **error)
{
g_return_val_if_fail (THRIFT_IS_STRUCT (object), -1);
return THRIFT_STRUCT_GET_CLASS (object)->write (object, protocol, error);
}
static void
thrift_struct_class_init (ThriftStructClass *cls)
{
cls->read = thrift_struct_read;
cls->write = thrift_struct_write;
}
static void
thrift_struct_init (ThriftStruct *structure)
{
THRIFT_UNUSED_VAR (structure);
}

View file

@ -0,0 +1,68 @@
/*
* 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.
*/
#ifndef THRIFT_STRUCT_H
#define THRIFT_STRUCT_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
G_BEGIN_DECLS
#define THRIFT_TYPE_STRUCT (thrift_struct_get_type ())
#define THRIFT_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_STRUCT, ThriftStruct))
#define THRIFT_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_STRUCT, ThriftStructClass))
#define THRIFT_IS_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_STRUCT))
#define THRIFT_IS_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_STRUCT))
#define THRIFT_STRUCT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_STRUCT, ThriftStructClass))
typedef struct _ThriftStruct ThriftStruct;
/* struct */
struct _ThriftStruct
{
GObject parent;
/* private */
};
typedef struct _ThriftStructClass ThriftStructClass;
struct _ThriftStructClass
{
GObjectClass parent;
/* public */
gint32 (*read) (ThriftStruct *object, ThriftProtocol *protocol,
GError **error);
gint32 (*write) (ThriftStruct *object, ThriftProtocol *protocol,
GError **error);
};
GType thrift_struct_get_type (void);
gint32 thrift_struct_read (ThriftStruct *object, ThriftProtocol *protocol,
GError **error);
gint32 thrift_struct_write (ThriftStruct *object, ThriftProtocol *protocol,
GError **error);
G_END_DECLS
#endif

View file

@ -0,0 +1,391 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
/* object properties */
enum _ThriftBufferedTransportProperties
{
PROP_0,
PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT,
PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE,
PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE
};
G_DEFINE_TYPE(ThriftBufferedTransport, thrift_buffered_transport, THRIFT_TYPE_TRANSPORT)
/* implements thrift_transport_is_open */
gboolean
thrift_buffered_transport_is_open (ThriftTransport *transport)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
return THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport);
}
/* overrides thrift_transport_peek */
gboolean
thrift_buffered_transport_peek (ThriftTransport *transport, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
return (t->r_buf->len > 0) || thrift_transport_peek (t->transport, error);
}
/* implements thrift_transport_open */
gboolean
thrift_buffered_transport_open (ThriftTransport *transport, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
return THRIFT_TRANSPORT_GET_CLASS (t->transport)->open (t->transport, error);
}
/* implements thrift_transport_close */
gboolean
thrift_buffered_transport_close (ThriftTransport *transport, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error);
}
/* the actual read is "slow" because it calls the underlying transport */
gint32
thrift_buffered_transport_read_slow (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
gint ret = 0;
guint32 want = len;
guint32 got = 0;
guchar *tmpdata = g_alloca (len);
guint32 have = t->r_buf->len;
/* we shouldn't hit this unless the buffer doesn't have enough to read */
assert (t->r_buf->len < want);
/* first copy what we have in our buffer. */
if (have > 0)
{
memcpy (buf, t->r_buf, t->r_buf->len);
want -= t->r_buf->len;
t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len);
}
/* if the buffer is still smaller than what we want to read, then just
* read it directly. otherwise, fill the buffer and then give out
* enough to satisfy the read. */
if (t->r_buf_size < want)
{
if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
tmpdata,
want,
error)) < 0) {
return ret;
}
got += ret;
/* copy the data starting from where we left off */
memcpy ((guint8 *)buf + have, tmpdata, got);
return got + have;
} else {
guint32 give;
if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
tmpdata,
want,
error)) < 0) {
return ret;
}
got += ret;
t->r_buf = g_byte_array_append (t->r_buf, tmpdata, got);
/* hand over what we have up to what the caller wants */
give = want < t->r_buf->len ? want : t->r_buf->len;
memcpy ((guint8 *)buf + len - want, t->r_buf->data, give);
t->r_buf = g_byte_array_remove_range (t->r_buf, 0, give);
want -= give;
return (len - want);
}
}
/* implements thrift_transport_read */
gint32
thrift_buffered_transport_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
/* if we have enough buffer data to fulfill the read, just use
* a memcpy */
if (len <= t->r_buf->len)
{
memcpy (buf, t->r_buf->data, len);
g_byte_array_remove_range (t->r_buf, 0, len);
return len;
}
return thrift_buffered_transport_read_slow (transport, buf, len, error);
}
/* implements thrift_transport_read_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_buffered_transport_read_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
gboolean
thrift_buffered_transport_write_slow (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
guint32 have_bytes = t->w_buf->len;
guint32 space = t->w_buf_size - t->w_buf->len;
/* we need two syscalls because the buffered data plus the buffer itself
* is too big. */
if ((have_bytes + len >= 2*t->w_buf_size) || (have_bytes == 0))
{
if (have_bytes > 0)
{
if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
t->w_buf->data,
have_bytes,
error)) {
return FALSE;
}
t->w_buf = g_byte_array_remove_range (t->w_buf, 0, have_bytes);
}
if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
buf, len, error)) {
return FALSE;
}
return TRUE;
}
t->w_buf = g_byte_array_append (t->w_buf, buf, space);
if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
t->w_buf->data,
t->w_buf->len,
error)) {
return FALSE;
}
t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len);
t->w_buf = g_byte_array_append (t->w_buf, (guint8 *)buf + space, len-space);
return TRUE;
}
/* implements thrift_transport_write */
gboolean
thrift_buffered_transport_write (ThriftTransport *transport,
const gpointer buf,
const guint32 len, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
/* the length of the current buffer plus the length of the data being read */
if (t->w_buf->len + len <= t->w_buf_size)
{
t->w_buf = g_byte_array_append (t->w_buf, buf, len);
return len;
}
return thrift_buffered_transport_write_slow (transport, buf, len, error);
}
/* implements thrift_transport_write_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_buffered_transport_write_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_flush */
gboolean
thrift_buffered_transport_flush (ThriftTransport *transport, GError **error)
{
ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
if (t->w_buf != NULL && t->w_buf->len > 0)
{
/* write the buffer and then empty it */
if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
t->w_buf->data,
t->w_buf->len,
error)) {
return FALSE;
}
t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len);
}
THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush (t->transport,
error);
return TRUE;
}
/* initializes the instance */
static void
thrift_buffered_transport_init (ThriftBufferedTransport *transport)
{
transport->transport = NULL;
transport->r_buf = g_byte_array_new ();
transport->w_buf = g_byte_array_new ();
}
/* destructor */
static void
thrift_buffered_transport_finalize (GObject *object)
{
ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object);
if (transport->r_buf != NULL)
{
g_byte_array_free (transport->r_buf, TRUE);
}
transport->r_buf = NULL;
if (transport->w_buf != NULL)
{
g_byte_array_free (transport->w_buf, TRUE);
}
transport->w_buf = NULL;
}
/* property accessor */
void
thrift_buffered_transport_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT:
g_value_set_object (value, transport->transport);
break;
case PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE:
g_value_set_uint (value, transport->r_buf_size);
break;
case PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE:
g_value_set_uint (value, transport->w_buf_size);
break;
}
}
/* property mutator */
void
thrift_buffered_transport_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT:
transport->transport = g_value_get_object (value);
break;
case PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE:
transport->r_buf_size = g_value_get_uint (value);
break;
case PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE:
transport->w_buf_size = g_value_get_uint (value);
break;
}
}
/* initializes the class */
static void
thrift_buffered_transport_class_init (ThriftBufferedTransportClass *cls)
{
ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
GParamSpec *param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_buffered_transport_get_property;
gobject_class->set_property = thrift_buffered_transport_set_property;
param_spec = g_param_spec_object ("transport", "transport (construct)",
"Thrift transport",
THRIFT_TYPE_TRANSPORT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (gobject_class,
PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT,
param_spec);
param_spec = g_param_spec_uint ("r_buf_size",
"read buffer size (construct)",
"Set the read buffer size",
0, /* min */
1048576, /* max, 1024*1024 */
512, /* default value */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE,
param_spec);
param_spec = g_param_spec_uint ("w_buf_size",
"write buffer size (construct)",
"Set the write buffer size",
0, /* min */
1048576, /* max, 1024*1024 */
512, /* default value */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE,
param_spec);
gobject_class->finalize = thrift_buffered_transport_finalize;
ttc->is_open = thrift_buffered_transport_is_open;
ttc->peek = thrift_buffered_transport_peek;
ttc->open = thrift_buffered_transport_open;
ttc->close = thrift_buffered_transport_close;
ttc->read = thrift_buffered_transport_read;
ttc->read_end = thrift_buffered_transport_read_end;
ttc->write = thrift_buffered_transport_write;
ttc->write_end = thrift_buffered_transport_write_end;
ttc->flush = thrift_buffered_transport_flush;
}

View file

@ -0,0 +1,77 @@
/*
* 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.
*/
#ifndef _THRIFT_BUFFERED_TRANSPORT_H
#define _THRIFT_BUFFERED_TRANSPORT_H
#include <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_buffered_transport.h
* \brief Implementation of a Thrift buffered transport. Subclasses
* the ThriftTransport class.
*/
/* type macros */
#define THRIFT_TYPE_BUFFERED_TRANSPORT (thrift_buffered_transport_get_type ())
#define THRIFT_BUFFERED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransport))
#define THRIFT_IS_BUFFERED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT))
#define THRIFT_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransportClass))
#define THRIFT_IS_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BUFFERED_TRANSPORT)
#define THRIFT_BUFFERED_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransportClass))
typedef struct _ThriftBufferedTransport ThriftBufferedTransport;
/*!
* ThriftBufferedTransport instance.
*/
struct _ThriftBufferedTransport
{
ThriftTransport parent;
/* protected */
ThriftTransport *transport;
/* private */
GByteArray *r_buf;
GByteArray *w_buf;
guint32 r_buf_size;
guint32 w_buf_size;
};
typedef struct _ThriftBufferedTransportClass ThriftBufferedTransportClass;
/*!
* ThriftBufferedTransport class.
*/
struct _ThriftBufferedTransportClass
{
ThriftTransportClass parent;
};
/* used by THRIFT_TYPE_BUFFERED_TRANSPORT */
GType thrift_buffered_transport_get_type (void);
G_END_DECLS
#endif

View file

@ -0,0 +1,55 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
G_DEFINE_TYPE (ThriftBufferedTransportFactory,
thrift_buffered_transport_factory,
THRIFT_TYPE_TRANSPORT_FACTORY)
/* Wraps a transport with a ThriftBufferedTransport. */
ThriftTransport *
thrift_buffered_transport_factory_get_transport (ThriftTransportFactory *factory,
ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (factory);
return THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", transport,
NULL));
}
static void
thrift_buffered_transport_factory_init (ThriftBufferedTransportFactory *self)
{
THRIFT_UNUSED_VAR (self);
}
static void
thrift_buffered_transport_factory_class_init (ThriftBufferedTransportFactoryClass *klass)
{
ThriftTransportFactoryClass *base_class =
THRIFT_TRANSPORT_FACTORY_CLASS (klass);
base_class->get_transport =
klass->get_transport =
thrift_buffered_transport_factory_get_transport;
}

View file

@ -0,0 +1,86 @@
/*
* 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.
*/
#ifndef _THRIFT_BUFFERED_TRANSPORT_FACTORY_H
#define _THRIFT_BUFFERED_TRANSPORT_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
G_BEGIN_DECLS
/*! \file thrift_buffered_transport_factory.h
* \brief Wraps a transport with a ThriftBufferedTransport.
*/
/* type macros */
#define THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY \
(thrift_buffered_transport_factory_get_type ())
#define THRIFT_BUFFERED_TRANSPORT_FACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, \
ThriftBufferedTransportFactory))
#define THRIFT_IS_BUFFERED_TRANSPORT_FACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY))
#define THRIFT_BUFFERED_TRANSPORT_FACTORY_CLASS(c) \
(G_TYPE_CHECK_CLASS_CAST ((c), \
THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, \
ThriftBufferedTransportFactoryClass))
#define THRIFT_IS_BUFFERED_TRANSPORT_FACTORY_CLASS(c) \
(G_TYPE_CHECK_CLASS_TYPE ((c), \
THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY))
#define THRIFT_BUFFERED_TRANSPORT_FACTORY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, \
ThriftBufferedTransportFactoryClass))
typedef struct _ThriftBufferedTransportFactory ThriftBufferedTransportFactory;
/* Thrift Buffered-Transport Factory instance */
struct _ThriftBufferedTransportFactory
{
ThriftTransportFactory parent;
};
typedef struct _ThriftBufferedTransportFactoryClass ThriftBufferedTransportFactoryClass;
/* Thrift Buffered-Transport Factory class */
struct _ThriftBufferedTransportFactoryClass
{
ThriftTransportFactoryClass parent;
/* vtable */
ThriftTransport *(*get_transport) (ThriftTransportFactory *factory,
ThriftTransport *transport);
};
/* used by THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY */
GType thrift_buffered_transport_factory_get_type (void);
/* virtual public methods */
ThriftTransport *
thrift_buffered_transport_factory_get_transport (ThriftTransportFactory *factory,
ThriftTransport *transport);
G_END_DECLS
#endif /* _THRIFT_BUFFERED_TRANSPORT_FACTORY_H */

View file

@ -0,0 +1,265 @@
/*
* 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 <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_fd_transport.h>
/* object properties */
enum _ThriftFDTransportProperties
{
PROP_0,
PROP_THRIFT_FD_TRANSPORT_FD
};
G_DEFINE_TYPE (ThriftFDTransport, thrift_fd_transport, THRIFT_TYPE_TRANSPORT)
/* implements thrift_transport_is_open */
gboolean
thrift_fd_transport_is_open (ThriftTransport *transport)
{
ThriftFDTransport *t;
t = THRIFT_FD_TRANSPORT (transport);
return t->fd >= 0 && ! (fcntl (t->fd, F_GETFL) == -1 && errno == EBADF);
}
/* implements thrift_transport_open */
gboolean
thrift_fd_transport_open (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (error);
return thrift_fd_transport_is_open (transport);
}
/* implements thrift_transport_close */
gboolean
thrift_fd_transport_close (ThriftTransport *transport, GError **error)
{
ThriftFDTransport *t;
t = THRIFT_FD_TRANSPORT (transport);
#if GLIB_CHECK_VERSION (2, 36, 0)
return g_close (t->fd, error);
#else
if (close (t->fd) == 0) {
g_clear_error (error);
return TRUE;
} else {
g_set_error (error,
THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_CLOSE,
strerror (errno));
return FALSE;
}
#endif
}
/* implements thrift_transport_read */
gint32
thrift_fd_transport_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftFDTransport *t;
ssize_t n;
t = THRIFT_FD_TRANSPORT (transport);
n = read (t->fd, (guint8 *) buf, len);
if (n == -1) {
g_set_error (error,
THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_RECEIVE,
"Failed to read from fd: %s",
strerror (errno));
return -1;
}
return n;
}
/* implements thrift_transport_read_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_fd_transport_read_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_write */
gboolean
thrift_fd_transport_write (ThriftTransport *transport,
const gpointer buf,
const guint32 len, GError **error)
{
ThriftFDTransport *t;
guint8 *_buf;
guint32 _len;
ssize_t n;
t = THRIFT_FD_TRANSPORT (transport);
_buf = (guint8 *) buf;
_len = len;
while (_len > 0) {
n = write (t->fd, _buf, _len);
if (n == -1) {
g_set_error (error,
THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_SEND,
"Failed to write from fd: %s",
strerror (errno));
return FALSE;
} else {
_buf += n;
_len -= n;
}
}
return TRUE;
}
/* implements thrift_transport_write_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_fd_transport_write_end (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_flush */
gboolean
thrift_fd_transport_flush (ThriftTransport *transport, GError **error)
{
ThriftFDTransport *t;
t = THRIFT_FD_TRANSPORT (transport);
if (fsync (t->fd) == -1) {
g_set_error (error,
THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_UNKNOWN,
"Failed to flush fd: %s",
strerror (errno));
return FALSE;
} else {
return TRUE;
}
}
/* initializes the instance */
static void
thrift_fd_transport_init (ThriftFDTransport *transport)
{
transport->fd = -1;
}
/* destructor */
static void
thrift_fd_transport_finalize (GObject *object)
{
THRIFT_UNUSED_VAR (object);
}
/* property accessor */
void
thrift_fd_transport_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftFDTransport *t;
THRIFT_UNUSED_VAR (pspec);
t = THRIFT_FD_TRANSPORT (object);
switch (property_id) {
case PROP_THRIFT_FD_TRANSPORT_FD:
g_value_set_int (value, t->fd);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* property mutator */
void
thrift_fd_transport_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftFDTransport *t;
THRIFT_UNUSED_VAR (pspec);
t = THRIFT_FD_TRANSPORT (object);
switch (property_id) {
case PROP_THRIFT_FD_TRANSPORT_FD:
t->fd = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* initializes the class */
static void
thrift_fd_transport_class_init (ThriftFDTransportClass *cls)
{
ThriftTransportClass *ttc;
GObjectClass *gobject_class;
GParamSpec *param_spec;
ttc = THRIFT_TRANSPORT_CLASS (cls);
gobject_class = G_OBJECT_CLASS (cls);
param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_fd_transport_get_property;
gobject_class->set_property = thrift_fd_transport_set_property;
param_spec = g_param_spec_int ("fd",
"file descriptor (construct)",
"Set the file descriptor",
INT_MIN, /* min */
INT_MAX, /* max, 1024*1024 */
-1, /* default value */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_FD_TRANSPORT_FD,
param_spec);
gobject_class->finalize = thrift_fd_transport_finalize;
ttc->is_open = thrift_fd_transport_is_open;
ttc->open = thrift_fd_transport_open;
ttc->close = thrift_fd_transport_close;
ttc->read = thrift_fd_transport_read;
ttc->read_end = thrift_fd_transport_read_end;
ttc->write = thrift_fd_transport_write;
ttc->write_end = thrift_fd_transport_write_end;
ttc->flush = thrift_fd_transport_flush;
}

View file

@ -0,0 +1,74 @@
/*
* 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.
*/
#ifndef _THRIFT_FD_TRANSPORT_H
#define _THRIFT_FD_TRANSPORT_H
#include <glib-object.h>
#include "thrift_transport.h"
G_BEGIN_DECLS
/*! \file thrift_fd_transport.h
* \brief Class for Thrift file descriptor transports.
*/
/* type macros */
#define THRIFT_TYPE_FD_TRANSPORT (thrift_fd_transport_get_type ())
#define THRIFT_FD_TRANSPORT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_FD_TRANSPORT, \
ThriftFDTransport))
#define THRIFT_IS_FD_TRANSPORT(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_FD_TRANSPORT))
#define THRIFT_FD_TRANSPORT_CLASS(c) \
(G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_FD_TRANSPORT, \
ThriftFDTransportClass))
#define THRIFT_IS_FD_TRANSPORT_CLASS(c) \
(G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_FD_TRANSPORT))
#define THRIFT_FD_TRANSPORT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_FD_TRANSPORT, \
ThriftFDTransportClass))
typedef struct _ThriftFDTransport ThriftFDTransport;
struct _ThriftFDTransport
{
ThriftTransport parent;
/* protected */
gint fd;
};
typedef struct _ThriftFDTransportClass ThriftFDTransportClass;
/*!
* Thrift Transport class
*/
struct _ThriftFDTransportClass
{
ThriftTransportClass parent;
};
/* used by THRIFT_TYPE_FD_TRANSPORT */
GType thrift_fd_transport_get_type (void);
G_END_DECLS
#endif /* _THRIFT_FD_TRANSPORT_H */

View file

@ -0,0 +1,384 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_framed_transport.h>
/* object properties */
enum _ThriftFramedTransportProperties
{
PROP_0,
PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT,
PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE,
PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE
};
G_DEFINE_TYPE(ThriftFramedTransport, thrift_framed_transport, THRIFT_TYPE_TRANSPORT)
/* implements thrift_transport_is_open */
gboolean
thrift_framed_transport_is_open (ThriftTransport *transport)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
return THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport);
}
/* overrides thrift_transport_peek */
gboolean
thrift_framed_transport_peek (ThriftTransport *transport, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
return (t->r_buf->len > 0) || thrift_transport_peek (t->transport, error);
}
/* implements thrift_transport_open */
gboolean
thrift_framed_transport_open (ThriftTransport *transport, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
return THRIFT_TRANSPORT_GET_CLASS (t->transport)->open (t->transport, error);
}
/* implements thrift_transport_close */
gboolean
thrift_framed_transport_close (ThriftTransport *transport, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error);
}
/* reads a frame and puts it into the buffer */
gboolean
thrift_framed_transport_read_frame (ThriftTransport *transport,
GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
guint32 sz;
gint32 bytes;
gboolean result = FALSE;
/* read the size */
if (thrift_transport_read (t->transport,
&sz,
sizeof (sz),
error) == sizeof (sz))
{
guchar *tmpdata;
sz = ntohl (sz);
/* create a buffer to hold the data and read that much data */
tmpdata = g_alloca (sz);
bytes = thrift_transport_read (t->transport, tmpdata, sz, error);
if (bytes > 0 && (error == NULL || *error == NULL))
{
/* add the data to the buffer */
g_byte_array_append (t->r_buf, tmpdata, bytes);
result = TRUE;
}
}
return result;
}
/* the actual read is "slow" because it calls the underlying transport */
gint32
thrift_framed_transport_read_slow (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
guint32 want = len;
guint32 have = t->r_buf->len;
gint32 result = -1;
/* we shouldn't hit this unless the buffer doesn't have enough to read */
assert (t->r_buf->len < want);
/* first copy what we have in our buffer, if there is anything left */
if (have > 0)
{
memcpy (buf, t->r_buf, t->r_buf->len);
want -= t->r_buf->len;
t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len);
}
/* read a frame of input and buffer it */
if (thrift_framed_transport_read_frame (transport, error) == TRUE)
{
/* hand over what we have up to what the caller wants */
guint32 give = want < t->r_buf->len ? want : t->r_buf->len;
/* copy the data into the buffer */
memcpy ((guint8 *)buf + len - want, t->r_buf->data, give);
t->r_buf = g_byte_array_remove_range (t->r_buf, 0, give);
want -= give;
result = len - want;
}
return result;
}
/* implements thrift_transport_read */
gint32
thrift_framed_transport_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
/* if we have enough buffer data to fulfill the read, just use
* a memcpy from the buffer */
if (len <= t->r_buf->len)
{
memcpy (buf, t->r_buf->data, len);
g_byte_array_remove_range (t->r_buf, 0, len);
return len;
}
return thrift_framed_transport_read_slow (transport, buf, len, error);
}
/* implements thrift_transport_read_end
* called when read is complete. nothing to do on our end. */
gboolean
thrift_framed_transport_read_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
gboolean
thrift_framed_transport_write_slow (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
THRIFT_UNUSED_VAR (error);
/* append the data to the buffer and we're done */
g_byte_array_append (t->w_buf, buf, len);
return TRUE;
}
/* implements thrift_transport_write */
gboolean
thrift_framed_transport_write (ThriftTransport *transport,
const gpointer buf,
const guint32 len, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
/* the length of the current buffer plus the length of the data being read */
if (t->w_buf->len + len <= t->w_buf_size)
{
t->w_buf = g_byte_array_append (t->w_buf, buf, len);
return TRUE;
}
return thrift_framed_transport_write_slow (transport, buf, len, error);
}
/* implements thrift_transport_write_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_framed_transport_write_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_flush */
gboolean
thrift_framed_transport_flush (ThriftTransport *transport, GError **error)
{
ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
gint32 sz_hbo, sz_nbo;
guchar *tmpdata;
/* get the size of the frame in host and network byte order */
sz_hbo = t->w_buf->len + sizeof(sz_nbo);
sz_nbo = (gint32) htonl ((guint32) t->w_buf->len);
/* copy the size of the frame and then the frame itself */
tmpdata = g_alloca (sz_hbo);
memcpy (tmpdata, (guint8 *) &sz_nbo, sizeof (sz_nbo));
if (t->w_buf->len > 0)
{
memcpy (tmpdata + sizeof (sz_nbo), t->w_buf->data, t->w_buf->len);
t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len);
}
/* write the buffer and then empty it */
THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
tmpdata, sz_hbo,
error);
THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush (t->transport,
error);
return TRUE;
}
/* initializes the instance */
static void
thrift_framed_transport_init (ThriftFramedTransport *transport)
{
transport->transport = NULL;
transport->r_buf = g_byte_array_new ();
transport->w_buf = g_byte_array_new ();
}
/* destructor */
static void
thrift_framed_transport_finalize (GObject *object)
{
ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object);
if (transport->r_buf != NULL)
{
g_byte_array_free (transport->r_buf, TRUE);
}
transport->r_buf = NULL;
if (transport->w_buf != NULL)
{
g_byte_array_free (transport->w_buf, TRUE);
}
transport->w_buf = NULL;
}
/* property accessor */
void
thrift_framed_transport_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT:
g_value_set_object (value, transport->transport);
break;
case PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE:
g_value_set_uint (value, transport->r_buf_size);
break;
case PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE:
g_value_set_uint (value, transport->w_buf_size);
break;
}
}
/* property mutator */
void
thrift_framed_transport_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT:
transport->transport = g_value_get_object (value);
break;
case PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE:
transport->r_buf_size = g_value_get_uint (value);
break;
case PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE:
transport->w_buf_size = g_value_get_uint (value);
break;
}
}
/* initializes the class */
static void
thrift_framed_transport_class_init (ThriftFramedTransportClass *cls)
{
ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
GParamSpec *param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_framed_transport_get_property;
gobject_class->set_property = thrift_framed_transport_set_property;
param_spec = g_param_spec_object ("transport", "transport (construct)",
"Thrift transport",
THRIFT_TYPE_TRANSPORT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (gobject_class,
PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT,
param_spec);
param_spec = g_param_spec_uint ("r_buf_size",
"read buffer size (construct)",
"Set the read buffer size",
0, /* min */
1048576, /* max, 1024*1024 */
512, /* default value */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE,
param_spec);
param_spec = g_param_spec_uint ("w_buf_size",
"write buffer size (construct)",
"Set the write buffer size",
0, /* min */
1048576, /* max, 1024*1024 */
512, /* default value */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE,
param_spec);
gobject_class->finalize = thrift_framed_transport_finalize;
ttc->is_open = thrift_framed_transport_is_open;
ttc->peek = thrift_framed_transport_peek;
ttc->open = thrift_framed_transport_open;
ttc->close = thrift_framed_transport_close;
ttc->read = thrift_framed_transport_read;
ttc->read_end = thrift_framed_transport_read_end;
ttc->write = thrift_framed_transport_write;
ttc->write_end = thrift_framed_transport_write_end;
ttc->flush = thrift_framed_transport_flush;
}

View file

@ -0,0 +1,77 @@
/*
* 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.
*/
#ifndef _THRIFT_FRAMED_TRANSPORT_H
#define _THRIFT_FRAMED_TRANSPORT_H
#include <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_framed_transport.h
* \brief Implementation of a Thrift framed transport. Subclasses
* the ThriftTransport class.
*/
/* type macros */
#define THRIFT_TYPE_FRAMED_TRANSPORT (thrift_framed_transport_get_type ())
#define THRIFT_FRAMED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransport))
#define THRIFT_IS_FRAMED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_FRAMED_TRANSPORT))
#define THRIFT_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransportClass))
#define THRIFT_IS_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_FRAMED_TRANSPORT)
#define THRIFT_FRAMED_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransportClass))
typedef struct _ThriftFramedTransport ThriftFramedTransport;
/*!
* ThriftFramedTransport instance.
*/
struct _ThriftFramedTransport
{
ThriftTransport parent;
/* protected */
ThriftTransport *transport;
/* private */
GByteArray *r_buf;
GByteArray *w_buf;
guint32 r_buf_size;
guint32 w_buf_size;
};
typedef struct _ThriftFramedTransportClass ThriftFramedTransportClass;
/*!
* ThriftFramedTransport class.
*/
struct _ThriftFramedTransportClass
{
ThriftTransportClass parent;
};
/* used by THRIFT_TYPE_FRAMED_TRANSPORT */
GType thrift_framed_transport_get_type (void);
G_END_DECLS
#endif

View file

@ -0,0 +1,55 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_framed_transport.h>
#include <thrift/c_glib/transport/thrift_framed_transport_factory.h>
G_DEFINE_TYPE (ThriftFramedTransportFactory,
thrift_framed_transport_factory,
THRIFT_TYPE_TRANSPORT_FACTORY)
/* Wraps a transport with a ThriftFramedTransport. */
ThriftTransport *
thrift_framed_transport_factory_get_transport (ThriftTransportFactory *factory,
ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (factory);
return THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
"transport", transport,
NULL));
}
static void
thrift_framed_transport_factory_init (ThriftFramedTransportFactory *self)
{
THRIFT_UNUSED_VAR (self);
}
static void
thrift_framed_transport_factory_class_init (ThriftFramedTransportFactoryClass *klass)
{
ThriftTransportFactoryClass *base_class =
THRIFT_TRANSPORT_FACTORY_CLASS (klass);
base_class->get_transport =
klass->get_transport =
thrift_framed_transport_factory_get_transport;
}

View file

@ -0,0 +1,86 @@
/*
* 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.
*/
#ifndef _THRIFT_FRAMED_TRANSPORT_FACTORY_H
#define _THRIFT_FRAMED_TRANSPORT_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
G_BEGIN_DECLS
/*! \file thrift_framed_transport_factory.h
* \brief Wraps a transport with a ThriftFramedTransport.
*/
/* type macros */
#define THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY \
(thrift_framed_transport_factory_get_type ())
#define THRIFT_FRAMED_TRANSPORT_FACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY, \
ThriftFramedTransportFactory))
#define THRIFT_IS_FRAMED_TRANSPORT_FACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY))
#define THRIFT_FRAMED_TRANSPORT_FACTORY_CLASS(c) \
(G_TYPE_CHECK_CLASS_CAST ((c), \
THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY, \
ThriftFramedTransportFactoryClass))
#define THRIFT_IS_FRAMED_TRANSPORT_FACTORY_CLASS(c) \
(G_TYPE_CHECK_CLASS_TYPE ((c), \
THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY))
#define THRIFT_FRAMED_TRANSPORT_FACTORY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY, \
ThriftFramedTransportFactoryClass))
typedef struct _ThriftFramedTransportFactory ThriftFramedTransportFactory;
/* Thrift Framed-Transport Factory instance */
struct _ThriftFramedTransportFactory
{
ThriftTransportFactory parent;
};
typedef struct _ThriftFramedTransportFactoryClass ThriftFramedTransportFactoryClass;
/* Thrift Framed-Transport Factory class */
struct _ThriftFramedTransportFactoryClass
{
ThriftTransportFactoryClass parent;
/* vtable */
ThriftTransport *(*get_transport) (ThriftTransportFactory *factory,
ThriftTransport *transport);
};
/* used by THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY */
GType thrift_framed_transport_factory_get_type (void);
/* virtual public methods */
ThriftTransport *
thrift_framed_transport_factory_get_transport (ThriftTransportFactory *factory,
ThriftTransport *transport);
G_END_DECLS
#endif /* _THRIFT_FRAMED_TRANSPORT_FACTORY_H */

View file

@ -0,0 +1,286 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_memory_buffer.h>
/* object properties */
enum _ThriftMemoryBufferProperties
{
PROP_0,
PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE,
PROP_THRIFT_MEMORY_BUFFER_BUFFER,
PROP_THRIFT_MEMORY_BUFFER_OWNER
};
G_DEFINE_TYPE(ThriftMemoryBuffer, thrift_memory_buffer, THRIFT_TYPE_TRANSPORT)
/* implements thrift_transport_is_open */
gboolean
thrift_memory_buffer_is_open (ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (transport);
return TRUE;
}
/* implements thrift_transport_open */
gboolean
thrift_memory_buffer_open (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_close */
gboolean
thrift_memory_buffer_close (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_read */
gint32
thrift_memory_buffer_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport);
guint32 give = len;
THRIFT_UNUSED_VAR (error);
/* if the requested bytes are more than what we have available,
* just give all that we have the buffer */
if (t->buf->len < len)
{
give = t->buf->len;
}
memcpy (buf, t->buf->data, give);
g_byte_array_remove_range (t->buf, 0, give);
return give;
}
/* implements thrift_transport_read_end
* called when read is complete. nothing to do on our end. */
gboolean
thrift_memory_buffer_read_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_write */
gboolean
thrift_memory_buffer_write (ThriftTransport *transport,
const gpointer buf,
const guint32 len, GError **error)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport);
THRIFT_UNUSED_VAR (error);
/* return an exception if the buffer doesn't have enough space. */
if (len > t->buf_size - t->buf->len)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND,
"unable to write %d bytes to buffer of length %d",
len, t->buf_size);
return FALSE;
} else {
t->buf = g_byte_array_append (t->buf, buf, len);
return TRUE;
}
}
/* implements thrift_transport_write_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_memory_buffer_write_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_flush */
gboolean
thrift_memory_buffer_flush (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* initializes class before constructor properties are set */
static void
thrift_memory_buffer_init (ThriftMemoryBuffer *t)
{
THRIFT_UNUSED_VAR (t);
}
/* destructor */
static void
thrift_memory_buffer_finalize (GObject *object)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
if (t->owner && t->buf != NULL)
{
g_byte_array_unref (t->buf);
}
t->buf = NULL;
}
/* property accessor */
void
thrift_memory_buffer_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE:
g_value_set_uint (value, t->buf_size);
break;
case PROP_THRIFT_MEMORY_BUFFER_BUFFER:
g_value_set_pointer (value, (gpointer) (t->buf));
break;
case PROP_THRIFT_MEMORY_BUFFER_OWNER:
g_value_set_boolean (value, t->owner);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* property mutator */
void
thrift_memory_buffer_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE:
t->buf_size = g_value_get_uint (value);
break;
case PROP_THRIFT_MEMORY_BUFFER_BUFFER:
t->buf = (GByteArray*) g_value_get_pointer (value);
break;
case PROP_THRIFT_MEMORY_BUFFER_OWNER:
t->owner = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* initializes class after constructor properties are set */
static void
thrift_memory_buffer_constructed (GObject *object)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
if (t->buf == NULL) {
t->buf = g_byte_array_new ();
}
G_OBJECT_CLASS (thrift_memory_buffer_parent_class)->constructed (object);
}
/* initializes the class */
static void
thrift_memory_buffer_class_init (ThriftMemoryBufferClass *cls)
{
ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
GParamSpec *param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_memory_buffer_get_property;
gobject_class->set_property = thrift_memory_buffer_set_property;
param_spec = g_param_spec_uint ("buf_size",
"buffer size (construct)",
"Set the read/write buffer size limit",
0, /* min */
G_MAXUINT32, /* max */
G_MAXUINT32, /* default */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE,
param_spec);
param_spec = g_param_spec_pointer ("buf",
"internal buffer (GByteArray)",
"Set the internal buffer (GByteArray)",
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_MEMORY_BUFFER_BUFFER,
param_spec);
param_spec = g_param_spec_boolean ("owner",
"internal buffer memory management policy",
"Set whether internal buffer should be"
" unreferenced when thrift_memory_buffer"
" is finalized",
TRUE,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_MEMORY_BUFFER_OWNER,
param_spec);
gobject_class->constructed = thrift_memory_buffer_constructed;
gobject_class->finalize = thrift_memory_buffer_finalize;
ttc->is_open = thrift_memory_buffer_is_open;
ttc->open = thrift_memory_buffer_open;
ttc->close = thrift_memory_buffer_close;
ttc->read = thrift_memory_buffer_read;
ttc->read_end = thrift_memory_buffer_read_end;
ttc->write = thrift_memory_buffer_write;
ttc->write_end = thrift_memory_buffer_write_end;
ttc->flush = thrift_memory_buffer_flush;
}

View file

@ -0,0 +1,72 @@
/*
* 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.
*/
#ifndef _THRIFT_MEMORY_BUFFER_H
#define _THRIFT_MEMORY_BUFFER_H
#include <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_memory_buffer.h
* \brief Implementation of a Thrift memory buffer transport.
*/
/* type macros */
#define THRIFT_TYPE_MEMORY_BUFFER (thrift_memory_buffer_get_type ())
#define THRIFT_MEMORY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBuffer))
#define THRIFT_IS_MEMORY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MEMORY_BUFFER))
#define THRIFT_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBufferClass))
#define THRIFT_IS_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MEMORY_BUFFER)
#define THRIFT_MEMORY_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBufferClass))
typedef struct _ThriftMemoryBuffer ThriftMemoryBuffer;
/*!
* ThriftMemoryBuffer instance.
*/
struct _ThriftMemoryBuffer
{
ThriftTransport parent;
/* private */
GByteArray *buf;
guint32 buf_size;
gboolean owner;
};
typedef struct _ThriftMemoryBufferClass ThriftMemoryBufferClass;
/*!
* ThriftMemoryBuffer class.
*/
struct _ThriftMemoryBufferClass
{
ThriftTransportClass parent;
};
/* used by THRIFT_TYPE_MEMORY_BUFFER */
GType thrift_memory_buffer_get_type (void);
G_END_DECLS
#endif

View file

@ -0,0 +1,253 @@
/*
* 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 <errno.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
/* object properties */
enum _ThriftServerSocketProperties
{
PROP_0,
PROP_THRIFT_SERVER_SOCKET_PORT,
PROP_THRIFT_SERVER_SOCKET_BACKLOG
};
/* define the GError domain string */
#define THRIFT_SERVER_SOCKET_ERROR_DOMAIN "thrift-server-socket-error-quark"
G_DEFINE_TYPE(ThriftServerSocket, thrift_server_socket, THRIFT_TYPE_SERVER_TRANSPORT)
gboolean
thrift_server_socket_listen (ThriftServerTransport *transport, GError **error)
{
int enabled = 1; /* for setsockopt() */
struct sockaddr_in pin;
ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
/* create a address structure */
memset (&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = INADDR_ANY;
pin.sin_port = htons(tsocket->port);
/* create a socket */
if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_SOCKET,
"failed to create socket - %s", strerror (errno));
return FALSE;
}
if (setsockopt(tsocket->sd, SOL_SOCKET, SO_REUSEADDR, &enabled,
sizeof(enabled)) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT,
"unable to set SO_REUSEADDR - %s", strerror(errno));
return FALSE;
}
/* bind to the socket */
if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_BIND,
"failed to bind to port %d - %s",
tsocket->port, strerror(errno));
return FALSE;
}
if (listen(tsocket->sd, tsocket->backlog) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_LISTEN,
"failed to listen to port %d - %s",
tsocket->port, strerror(errno));
return FALSE;
}
return TRUE;
}
ThriftTransport *
thrift_server_socket_accept (ThriftServerTransport *transport, GError **error)
{
int sd = THRIFT_INVALID_SOCKET;
guint addrlen = 0;
struct sockaddr_in address;
ThriftSocket *socket = NULL;
ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
if ((sd = accept(tsocket->sd, (struct sockaddr *) &address, &addrlen)) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_ACCEPT,
"failed to accept connection - %s",
strerror(errno));
return FALSE;
}
socket = g_object_new (THRIFT_TYPE_SOCKET, NULL);
socket->sd = sd;
return THRIFT_TRANSPORT(socket);
}
gboolean
thrift_server_socket_close (ThriftServerTransport *transport, GError **error)
{
ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
if (close (tsocket->sd) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_CLOSE,
"unable to close socket - %s", strerror(errno));
return FALSE;
}
tsocket->sd = THRIFT_INVALID_SOCKET;
return TRUE;
}
/* define the GError domain for this implementation */
GQuark
thrift_server_socket_error_quark (void)
{
return g_quark_from_static_string(THRIFT_SERVER_SOCKET_ERROR_DOMAIN);
}
/* initializes the instance */
static void
thrift_server_socket_init (ThriftServerSocket *socket)
{
socket->sd = THRIFT_INVALID_SOCKET;
}
/* destructor */
static void
thrift_server_socket_finalize (GObject *object)
{
ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
if (socket->sd != THRIFT_INVALID_SOCKET)
{
close (socket->sd);
}
socket->sd = THRIFT_INVALID_SOCKET;
}
/* property accessor */
void
thrift_server_socket_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
switch (property_id)
{
case PROP_THRIFT_SERVER_SOCKET_PORT:
g_value_set_uint (value, socket->port);
break;
case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
g_value_set_uint (value, socket->backlog);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* property mutator */
void
thrift_server_socket_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
switch (property_id)
{
case PROP_THRIFT_SERVER_SOCKET_PORT:
socket->port = g_value_get_uint (value);
break;
case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
socket->backlog = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* initializes the class */
static void
thrift_server_socket_class_init (ThriftServerSocketClass *cls)
{
ThriftServerTransportClass *tstc = THRIFT_SERVER_TRANSPORT_CLASS (cls);
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
GParamSpec *param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_server_socket_get_property;
gobject_class->set_property = thrift_server_socket_set_property;
param_spec = g_param_spec_uint ("port",
"port (construct)",
"Set the port to listen to",
0, /* min */
65534, /* max */
9090, /* default by convention */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_SOCKET_PORT,
param_spec);
param_spec = g_param_spec_uint ("backlog",
"backlog (construct)",
"Set the accept backlog",
0, /* max */
65534, /* max */
1024, /* default */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_SERVER_SOCKET_BACKLOG,
param_spec);
gobject_class->finalize = thrift_server_socket_finalize;
tstc->listen = thrift_server_socket_listen;
tstc->accept = thrift_server_socket_accept;
tstc->close = thrift_server_socket_close;
}

View file

@ -0,0 +1,90 @@
/*
* 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.
*/
#ifndef _THRIFT_SERVER_SOCKET_H
#define _THRIFT_SERVER_SOCKET_H
#include <glib-object.h>
#include "thrift_server_transport.h"
G_BEGIN_DECLS
/*! \file thrift_server_socket.h
* \brief Socket implementation of a Thrift server transport. Implements the
* ThriftServerTransport class.
*/
/* type macros */
#define THRIFT_TYPE_SERVER_SOCKET (thrift_server_socket_get_type ())
#define THRIFT_SERVER_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SERVER_SOCKET, ThriftServerSocket))
#define THRIFT_IS_SERVER_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SERVER_SOCKET))
#define THRIFT_SERVER_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SERVER_SOCKET, ThriftServerSocketClass))
#define THRIFT_IS_SERVER_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SERVER_SOCKET))
#define THRIFT_SERVER_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SERVER_SOCKET, ThriftServerSocketClass))
typedef struct _ThriftServerSocket ThriftServerSocket;
/*!
* Thrift ServerSocket instance.
*/
struct _ThriftServerSocket
{
ThriftServerTransport parent;
/* private */
gshort port;
gshort backlog;
int sd;
guint8 *buf;
guint32 buf_size;
guint32 buf_len;
};
typedef struct _ThriftServerSocketClass ThriftServerSocketClass;
/*!
* Thrift ServerSocket class.
*/
struct _ThriftServerSocketClass
{
ThriftServerTransportClass parent;
};
/* used by THRIFT_TYPE_SERVER_SOCKET */
GType thrift_server_socket_get_type (void);
/* define error/exception types */
typedef enum
{
THRIFT_SERVER_SOCKET_ERROR_SOCKET,
THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT,
THRIFT_SERVER_SOCKET_ERROR_BIND,
THRIFT_SERVER_SOCKET_ERROR_LISTEN,
THRIFT_SERVER_SOCKET_ERROR_ACCEPT,
THRIFT_SERVER_SOCKET_ERROR_CLOSE
} ThriftServerSocketError;
/* define a error domain for GError to use */
GQuark thrift_server_socket_error_quark (void);
#define THRIFT_SERVER_SOCKET_ERROR (thrift_server_socket_error_quark ())
G_END_DECLS
#endif

View file

@ -0,0 +1,62 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
G_DEFINE_ABSTRACT_TYPE(ThriftServerTransport, thrift_server_transport, G_TYPE_OBJECT)
/* base initializer for the server transport interface */
static void
thrift_server_transport_class_init (ThriftServerTransportClass *c)
{
c->listen = thrift_server_transport_listen;
c->accept = thrift_server_transport_accept;
c->close = thrift_server_transport_close;
}
static void
thrift_server_transport_init (ThriftServerTransport *transport)
{
THRIFT_UNUSED_VAR (transport);
}
gboolean
thrift_server_transport_listen (ThriftServerTransport *transport,
GError **error)
{
return THRIFT_SERVER_TRANSPORT_GET_CLASS (transport)->listen (transport,
error);
}
ThriftTransport *
thrift_server_transport_accept (ThriftServerTransport *transport,
GError **error)
{
return THRIFT_SERVER_TRANSPORT_GET_CLASS (transport)->accept (transport,
error);
}
gboolean
thrift_server_transport_close (ThriftServerTransport *transport, GError **error)
{
return THRIFT_SERVER_TRANSPORT_GET_CLASS (transport)->close (transport,
error);
}

View file

@ -0,0 +1,89 @@
/*
* 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.
*/
#ifndef _THRIFT_SERVER_TRANSPORT_H
#define _THRIFT_SERVER_TRANSPORT_H
#include <glib-object.h>
#include "thrift_transport.h"
G_BEGIN_DECLS
/*! \file thrift_server_transport.h
* \brief Abstract class for Thrift server transports.
*/
/* type macros */
#define THRIFT_TYPE_SERVER_TRANSPORT (thrift_server_transport_get_type ())
#define THRIFT_SERVER_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SERVER_TRANSPORT, ThriftServerTransport))
#define THRIFT_IS_SERVER_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SERVER_TRANSPORT))
#define THRIFT_SERVER_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SERVER_TRANSPORT, ThriftServerTransportClass))
#define THRIFT_IS_SERVER_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SERVER_TRANSPORT))
#define THRIFT_SERVER_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SERVER_TRANSPORT, ThriftServerTransportClass))
typedef struct _ThriftServerTransport ThriftServerTransport;
struct _ThriftServerTransport
{
GObject parent;
};
typedef struct _ThriftServerTransportClass ThriftServerTransportClass;
/*!
* Thrift Transport class
*/
struct _ThriftServerTransportClass
{
GObjectClass parent;
/* vtable */
gboolean (*listen) (ThriftServerTransport *transport, GError **error);
ThriftTransport *(*accept) (ThriftServerTransport *transport, GError **error);
gboolean (*close) (ThriftServerTransport *transport, GError **error);
};
/* used by THRIFT_TYPE_SERVER_TRANSPORT */
GType thrift_server_transport_get_type (void);
/*!
* Listen for new connections.
* \public \memberof ThriftServerTransportClass
*/
gboolean thrift_server_transport_listen (ThriftServerTransport *transport,
GError **error);
/*!
* Accept a connection.
* \public \memberof ThriftServerTransportClass
*/
ThriftTransport *thrift_server_transport_accept
(ThriftServerTransport *transport, GError **error);
/*!
* Close the transport.
* \public \memberof ThriftServerTransportClass
*/
gboolean thrift_server_transport_close (ThriftServerTransport *transport,
GError **error);
G_END_DECLS
#endif /* _THRIFT_SERVER_TRANSPORT_H */

View file

@ -0,0 +1,368 @@
/*
* 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 <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
/* object properties */
enum _ThriftSocketProperties
{
PROP_0,
PROP_THRIFT_SOCKET_HOSTNAME,
PROP_THRIFT_SOCKET_PORT
};
G_DEFINE_TYPE(ThriftSocket, thrift_socket, THRIFT_TYPE_TRANSPORT)
/* implements thrift_transport_is_open */
gboolean
thrift_socket_is_open (ThriftTransport *transport)
{
ThriftSocket *socket = THRIFT_SOCKET (transport);
return socket->sd != THRIFT_INVALID_SOCKET;
}
/* overrides thrift_transport_peek */
gboolean
thrift_socket_peek (ThriftTransport *transport, GError **error)
{
gboolean result = FALSE;
guint8 buf;
int r;
int errno_copy;
ThriftSocket *socket = THRIFT_SOCKET (transport);
if (thrift_socket_is_open (transport))
{
r = recv (socket->sd, &buf, 1, MSG_PEEK);
if (r == -1)
{
errno_copy = errno;
#if defined __FreeBSD__ || defined __MACH__
/* FreeBSD returns -1 and ECONNRESET if the socket was closed by the other
side */
if (errno_copy == ECONNRESET)
{
thrift_socket_close (transport, error);
}
else
{
#endif
g_set_error (error,
THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_SOCKET,
"failed to peek at socket - %s",
strerror (errno_copy));
#if defined __FreeBSD__ || defined __MACH__
}
#endif
}
else if (r > 0)
{
result = TRUE;
}
}
return result;
}
/* implements thrift_transport_open */
gboolean
thrift_socket_open (ThriftTransport *transport, GError **error)
{
struct hostent *hp = NULL;
struct sockaddr_in pin;
int err;
#if defined(HAVE_GETHOSTBYNAME_R)
struct hostent he;
char buf[1024];
#endif
ThriftSocket *tsocket = THRIFT_SOCKET (transport);
g_return_val_if_fail (tsocket->sd == THRIFT_INVALID_SOCKET, FALSE);
/* lookup the destination host */
#if defined(HAVE_GETHOSTBYNAME_R)
if (gethostbyname_r (tsocket->hostname, &he, buf, 1024, &hp, &err) != 0 || hp == NULL)
#else
if ((hp = gethostbyname (tsocket->hostname)) == NULL && (err = h_errno))
#endif
{
/* host lookup failed, bail out with an error */
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_HOST,
"host lookup failed for %s:%d - %s",
tsocket->hostname, tsocket->port,
hstrerror (err));
return FALSE;
}
/* create a socket structure */
memset (&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
pin.sin_port = htons (tsocket->port);
/* create the socket */
if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET,
"failed to create socket for host %s:%d - %s",
tsocket->hostname, tsocket->port,
strerror(errno));
return FALSE;
}
/* open a connection */
if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
"failed to connect to host %s:%d - %s",
tsocket->hostname, tsocket->port, strerror(errno));
return FALSE;
}
return TRUE;
}
/* implements thrift_transport_close */
gboolean
thrift_socket_close (ThriftTransport *transport, GError **error)
{
ThriftSocket *socket = THRIFT_SOCKET (transport);
if (close (socket->sd) == -1)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE,
"unable to close socket - %s",
strerror(errno));
return FALSE;
}
socket->sd = THRIFT_INVALID_SOCKET;
return TRUE;
}
/* implements thrift_transport_read */
gint32
thrift_socket_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
gint ret = 0;
guint got = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
while (got < len)
{
ret = recv (socket->sd, (guint8 *)buf + got, len-got, 0);
if (ret <= 0)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_RECEIVE,
"failed to read %d bytes - %s", len, strerror(errno));
return -1;
}
got += ret;
}
return got;
}
/* implements thrift_transport_read_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_socket_read_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_write */
gboolean
thrift_socket_write (ThriftTransport *transport, const gpointer buf,
const guint32 len, GError **error)
{
gint ret = 0;
guint sent = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET, FALSE);
while (sent < len)
{
ret = send (socket->sd, (guint8 *)buf + sent, len - sent, 0);
if (ret < 0)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR,
THRIFT_TRANSPORT_ERROR_SEND,
"failed to send %d bytes - %s", len, strerror(errno));
return FALSE;
}
sent += ret;
}
return TRUE;
}
/* implements thrift_transport_write_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_socket_write_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_flush
* flush pending data. since we are not buffered, this is a no-op */
gboolean
thrift_socket_flush (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* initializes the instance */
static void
thrift_socket_init (ThriftSocket *socket)
{
socket->sd = THRIFT_INVALID_SOCKET;
}
/* destructor */
static void
thrift_socket_finalize (GObject *object)
{
ThriftSocket *socket = THRIFT_SOCKET (object);
if (socket->hostname != NULL)
{
g_free (socket->hostname);
}
socket->hostname = NULL;
if (socket->sd != THRIFT_INVALID_SOCKET)
{
close (socket->sd);
}
socket->sd = THRIFT_INVALID_SOCKET;
}
/* property accessor */
void
thrift_socket_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftSocket *socket = THRIFT_SOCKET (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_SOCKET_HOSTNAME:
g_value_set_string (value, socket->hostname);
break;
case PROP_THRIFT_SOCKET_PORT:
g_value_set_uint (value, socket->port);
break;
}
}
/* property mutator */
void
thrift_socket_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftSocket *socket = THRIFT_SOCKET (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_SOCKET_HOSTNAME:
socket->hostname = g_strdup (g_value_get_string (value));
break;
case PROP_THRIFT_SOCKET_PORT:
socket->port = g_value_get_uint (value);
break;
}
}
/* initializes the class */
static void
thrift_socket_class_init (ThriftSocketClass *cls)
{
ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
GParamSpec *param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_socket_get_property;
gobject_class->set_property = thrift_socket_set_property;
param_spec = g_param_spec_string ("hostname",
"hostname (construct)",
"Set the hostname of the remote host",
"localhost", /* default value */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_HOSTNAME,
param_spec);
param_spec = g_param_spec_uint ("port",
"port (construct)",
"Set the port of the remote host",
0, /* min */
65534, /* max */
9090, /* default by convention */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PORT,
param_spec);
gobject_class->finalize = thrift_socket_finalize;
ttc->is_open = thrift_socket_is_open;
ttc->peek = thrift_socket_peek;
ttc->open = thrift_socket_open;
ttc->close = thrift_socket_close;
ttc->read = thrift_socket_read;
ttc->read_end = thrift_socket_read_end;
ttc->write = thrift_socket_write;
ttc->write_end = thrift_socket_write_end;
ttc->flush = thrift_socket_flush;
}

View file

@ -0,0 +1,75 @@
/*
* 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.
*/
#ifndef _THRIFT_SOCKET_H
#define _THRIFT_SOCKET_H
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
G_BEGIN_DECLS
/*! \file thrift_socket.h
* \brief Socket implementation of a Thrift transport. Subclasses the
* ThriftTransport class.
*/
/* type macros */
#define THRIFT_TYPE_SOCKET (thrift_socket_get_type ())
#define THRIFT_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SOCKET, ThriftSocket))
#define THRIFT_IS_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SOCKET))
#define THRIFT_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SOCKET, ThriftSocketClass))
#define THRIFT_IS_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SOCKET))
#define THRIFT_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SOCKET, ThriftSocketClass))
typedef struct _ThriftSocket ThriftSocket;
/*!
* Thrift Socket instance.
*/
struct _ThriftSocket
{
ThriftTransport parent;
/* private */
gchar *hostname;
gshort port;
int sd;
guint8 *buf;
guint32 buf_size;
guint32 buf_len;
};
typedef struct _ThriftSocketClass ThriftSocketClass;
/*!
* Thrift Socket class.
*/
struct _ThriftSocketClass
{
ThriftTransportClass parent;
};
/* used by THRIFT_TYPE_SOCKET */
GType thrift_socket_get_type (void);
G_END_DECLS
#endif

View file

@ -0,0 +1,162 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
/* define the GError domain string */
#define THRIFT_TRANSPORT_ERROR_DOMAIN "thrift-transport-error-quark"
G_DEFINE_ABSTRACT_TYPE(ThriftTransport, thrift_transport, G_TYPE_OBJECT)
gboolean
thrift_transport_is_open (ThriftTransport *transport)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->is_open (transport);
}
gboolean
thrift_transport_peek (ThriftTransport *transport, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->peek (transport, error);
}
gboolean
thrift_transport_open (ThriftTransport *transport, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->open (transport, error);
}
gboolean
thrift_transport_close (ThriftTransport *transport, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->close (transport, error);
}
gint32
thrift_transport_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->read (transport, buf,
len, error);
}
gboolean
thrift_transport_read_end (ThriftTransport *transport, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->read_end (transport,
error);
}
gboolean
thrift_transport_write (ThriftTransport *transport, const gpointer buf,
const guint32 len, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->write (transport, buf,
len, error);
}
gboolean
thrift_transport_write_end (ThriftTransport *transport, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->write_end (transport,
error);
}
gboolean
thrift_transport_flush (ThriftTransport *transport, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->flush (transport, error);
}
gint32
thrift_transport_read_all (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
return THRIFT_TRANSPORT_GET_CLASS (transport)->read_all (transport, buf,
len, error);
}
/* by default, peek returns true if and only if the transport is open */
static gboolean
thrift_transport_real_peek (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (error);
return THRIFT_TRANSPORT_GET_CLASS (transport)->is_open (transport);
}
static gint32
thrift_transport_real_read_all (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftTransportClass *ttc;
guint32 have;
gint32 ret;
gint8 *bytes;
THRIFT_UNUSED_VAR (error);
ttc = THRIFT_TRANSPORT_GET_CLASS (transport);
have = 0;
ret = 0;
bytes = (gint8*) buf;
while (have < len) {
if ((ret = ttc->read (transport, (gpointer) (bytes + have), len - have,
error)) < 0) {
return ret;
}
have += ret;
}
return have;
}
/* define the GError domain for Thrift transports */
GQuark
thrift_transport_error_quark (void)
{
return g_quark_from_static_string (THRIFT_TRANSPORT_ERROR_DOMAIN);
}
/* class initializer for ThriftTransport */
static void
thrift_transport_class_init (ThriftTransportClass *cls)
{
/* set these as virtual methods to be implemented by a subclass */
cls->is_open = thrift_transport_is_open;
cls->open = thrift_transport_open;
cls->close = thrift_transport_close;
cls->read = thrift_transport_read;
cls->read_end = thrift_transport_read_end;
cls->write = thrift_transport_write;
cls->write_end = thrift_transport_write_end;
cls->flush = thrift_transport_flush;
/* provide a default implementation for the peek and read_all methods */
cls->peek = thrift_transport_real_peek;
cls->read_all = thrift_transport_real_read_all;
}
static void
thrift_transport_init (ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (transport);
}

View file

@ -0,0 +1,176 @@
/*
* 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.
*/
#ifndef _THRIFT_TRANSPORT_H
#define _THRIFT_TRANSPORT_H
#include <glib-object.h>
G_BEGIN_DECLS
/*! \file thrift_transport.h
* \brief Abstract class for Thrift transports.
*
* An abstract class is used instead of an interface because:
* - interfaces can't seem to be used as properties. ThriftProtocol has
* a ThriftTransport as an object property.
* - if a method needs to be added that all subclasses can use, a class
* is necessary.
*/
/* type macros */
#define THRIFT_TYPE_TRANSPORT (thrift_transport_get_type ())
#define THRIFT_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_TRANSPORT, ThriftTransport))
#define THRIFT_IS_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_TRANSPORT))
#define THRIFT_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_TRANSPORT, ThriftTransportClass))
#define THRIFT_IS_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_TRANSPORT))
#define THRIFT_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_TRANSPORT, ThriftTransportClass))
typedef struct _ThriftTransport ThriftTransport;
/*!
* Thrift Protocol object
*/
struct _ThriftTransport
{
GObject parent;
};
typedef struct _ThriftTransportClass ThriftTransportClass;
/*!
* Thrift Transport class
*/
struct _ThriftTransportClass
{
GObjectClass parent;
/* vtable */
gboolean (*is_open) (ThriftTransport *transport);
gboolean (*peek) (ThriftTransport *transport, GError **error);
gboolean (*open) (ThriftTransport *transport, GError **error);
gboolean (*close) (ThriftTransport *transport, GError **error);
gint32 (*read) (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error);
gboolean (*read_end) (ThriftTransport *transport, GError **error);
gboolean (*write) (ThriftTransport *transport, const gpointer buf,
const guint32 len, GError **error);
gboolean (*write_end) (ThriftTransport *transport, GError **error);
gboolean (*flush) (ThriftTransport *transport, GError **error);
gint32 (*read_all) (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error);
};
/* used by THRIFT_TYPE_TRANSPORT */
GType thrift_transport_get_type (void);
/* virtual public methods */
/*!
* Checks if this transport is opened.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_is_open (ThriftTransport *transport);
/*!
* Open the transport for reading and writing.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_open (ThriftTransport *transport, GError **error);
/*!
* Tests whether there is more data to read or if the remote side is still
* open. By default this is true whenever the transport is open, but
* implementations should add logic to test for this condition where possible
* (i.e. on a socket).
*
* This is used by a server to check if it should listen for another request.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_peek (ThriftTransport *transport, GError **error);
/*!
* Close the transport.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_close (ThriftTransport *transport, GError **error);
/*!
* Read some data into the buffer buf.
* \public \memberof ThriftTransportInterface
*/
gint32 thrift_transport_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error);
/*!
* Called when read is completed.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_read_end (ThriftTransport *transport, GError **error);
/*!
* Writes data from a buffer to the transport.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_write (ThriftTransport *transport, const gpointer buf,
const guint32 len, GError **error);
/*!
* Called when write is completed.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_write_end (ThriftTransport *transport,
GError **error);
/*!
* Flushes any pending data to be written. Typically used with buffered
* transport mechanisms.
* \public \memberof ThriftTransportInterface
*/
gboolean thrift_transport_flush (ThriftTransport *transport, GError **error);
/*!
* Read len bytes of data into the buffer buf.
* \public \memberof ThriftTransportInterface
*/
gint32 thrift_transport_read_all (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error);
/* define error/exception types */
typedef enum
{
THRIFT_TRANSPORT_ERROR_UNKNOWN,
THRIFT_TRANSPORT_ERROR_HOST,
THRIFT_TRANSPORT_ERROR_SOCKET,
THRIFT_TRANSPORT_ERROR_CONNECT,
THRIFT_TRANSPORT_ERROR_SEND,
THRIFT_TRANSPORT_ERROR_RECEIVE,
THRIFT_TRANSPORT_ERROR_CLOSE
} ThriftTransportError;
/* define an error domain for GError to use */
GQuark thrift_transport_error_quark (void);
#define THRIFT_TRANSPORT_ERROR (thrift_transport_error_quark ())
/* define macro for invalid socket */
#define THRIFT_INVALID_SOCKET (-1)
G_END_DECLS
#endif /* _THRIFT_TRANSPORT_H */

View file

@ -0,0 +1,44 @@
/*
* 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 <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
G_DEFINE_TYPE(ThriftTransportFactory, thrift_transport_factory, G_TYPE_OBJECT)
/* builds a transport from the base transport. */
ThriftTransport *
thrift_transport_factory_get_transport (ThriftTransportFactory *factory,
ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (factory);
return transport;
}
static void
thrift_transport_factory_class_init (ThriftTransportFactoryClass *cls)
{
cls->get_transport = thrift_transport_factory_get_transport;
}
static void
thrift_transport_factory_init (ThriftTransportFactory *factory)
{
THRIFT_UNUSED_VAR (factory);
}

View file

@ -0,0 +1,71 @@
/*
* 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.
*/
#ifndef _THRIFT_TRANSPORT_FACTORY_H
#define _THRIFT_TRANSPORT_FACTORY_H
#include <glib-object.h>
#include "thrift_transport.h"
G_BEGIN_DECLS
/*! \file thrift_transport_factory.h
* \brief Base class for Thrift Transport Factories. Used by Thrift Servers
* to obtain a client transport from an existing transport. The default
* implementation simply clones the provided transport.
*/
/* type macros */
#define THRIFT_TYPE_TRANSPORT_FACTORY (thrift_transport_factory_get_type ())
#define THRIFT_TRANSPORT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_TRANSPORT_FACTORY, ThriftTransportFactory))
#define THRIFT_IS_TRANSPORT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_TRANSPORT_FACTORY))
#define THRIFT_TRANSPORT_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_TRANSPORT_FACTORY, ThriftTransportFactoryClass))
#define THRIFT_IS_TRANSPORT_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_TRANSPORT_FACTORY))
#define THRIFT_TRANSPORT_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_TRANSPORT_FACTORY, ThriftTransportFactoryClass))
typedef struct _ThriftTransportFactory ThriftTransportFactory;
/* Thrift Transport Factory instance */
struct _ThriftTransportFactory
{
GObject parent;
};
typedef struct _ThriftTransportFactoryClass ThriftTransportFactoryClass;
/* Thrift Transport Factory class */
struct _ThriftTransportFactoryClass
{
GObjectClass parent;
/* vtable */
ThriftTransport *(*get_transport) (ThriftTransportFactory *factory,
ThriftTransport *transport);
};
/* used by THRIFT_TYPE_TRANSPORT_FACTORY */
GType thrift_transport_factory_get_type (void);
/* virtual public methods */
ThriftTransport *thrift_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport);
G_END_DECLS
#endif /* _THRIFT_TRANSPORT_FACTORY_H */

View file

@ -0,0 +1,200 @@
#
# 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.
#
set(TEST_PREFIX "c_glib")
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
#Make sure gen-cpp and gen-c_glib files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# Create the thrift C test library
set(testgenc_SOURCES
gen-c_glib/t_test_debug_proto_test_types.c
gen-c_glib/t_test_enum_test_types.c
gen-c_glib/t_test_enum_test_service.c
gen-c_glib/t_test_empty_service.c
gen-c_glib/t_test_inherited.c
gen-c_glib/t_test_optional_required_test_types.c
gen-c_glib/t_test_reverse_order_service.c
gen-c_glib/t_test_second_service.c
gen-c_glib/t_test_service_for_exception_with_a_map.c
gen-c_glib/t_test_srv.c
gen-c_glib/t_test_thrift_test.c
gen-c_glib/t_test_thrift_test_types.c
gen-c_glib/t_test_debug_proto_test_types.h
gen-c_glib/t_test_enum_test_types.h
gen-c_glib/t_test_enum_test_service.h
gen-c_glib/t_test_empty_service.h
gen-c_glib/t_test_inherited.h
gen-c_glib/t_test_optional_required_test_types.h
gen-c_glib/t_test_reverse_order_service.h
gen-c_glib/t_test_second_service.h
gen-c_glib/t_test_service_for_exception_with_a_map.h
gen-c_glib/t_test_srv.h
gen-c_glib/t_test_thrift_test.h
gen-c_glib/t_test_thrift_test_types.h
)
add_library(testgenc STATIC ${testgenc_SOURCES})
LINK_AGAINST_THRIFT_LIBRARY(testgenc thrift_c_glib)
add_executable(testserialization testserialization.c)
target_link_libraries(testserialization testgenc)
LINK_AGAINST_THRIFT_LIBRARY(testserialization thrift_c_glib)
add_test(NAME testserialization COMMAND testserialization)
add_executable(testapplicationexception testapplicationexception.c)
LINK_AGAINST_THRIFT_LIBRARY(testapplicationexception thrift_c_glib)
add_test(NAME testapplicationexception COMMAND testapplicationexception)
add_executable(testtransportsocket testtransportsocket.c)
LINK_AGAINST_THRIFT_LIBRARY(testtransportsocket thrift_c_glib)
add_test(NAME testtransportsocket COMMAND testtransportsocket)
add_executable(testbinaryprotocol testbinaryprotocol.c)
LINK_AGAINST_THRIFT_LIBRARY(testbinaryprotocol thrift_c_glib)
add_test(NAME testbinaryprotocol COMMAND testbinaryprotocol)
add_executable(testcompactprotocol testcompactprotocol.c)
LINK_AGAINST_THRIFT_LIBRARY(testcompactprotocol thrift_c_glib)
add_test(NAME testcompactprotocol COMMAND testcompactprotocol)
add_executable(testbufferedtransport testbufferedtransport.c)
LINK_AGAINST_THRIFT_LIBRARY(testbufferedtransport thrift_c_glib)
add_test(NAME testbufferedtransport COMMAND testbufferedtransport)
add_executable(testframedtransport testframedtransport.c)
LINK_AGAINST_THRIFT_LIBRARY(testframedtransport thrift_c_glib)
add_test(NAME testframedtransport COMMAND testframedtransport)
add_executable(testfdtransport testfdtransport.c)
LINK_AGAINST_THRIFT_LIBRARY(testfdtransport thrift_c_glib)
add_test(NAME testfdtransport COMMAND testfdtransport)
add_executable(testmemorybuffer testmemorybuffer.c)
LINK_AGAINST_THRIFT_LIBRARY(testmemorybuffer thrift_c_glib)
add_test(NAME testmemorybuffer COMMAND testmemorybuffer)
add_executable(testsimpleserver testsimpleserver.c)
LINK_AGAINST_THRIFT_LIBRARY(testsimpleserver thrift_c_glib)
add_test(NAME testsimpleserver COMMAND testsimpleserver)
add_executable(testdebugproto testdebugproto.c)
target_link_libraries(testdebugproto testgenc)
add_test(NAME testdebugproto COMMAND testdebugproto)
add_executable(testoptionalrequired testoptionalrequired.c)
target_link_libraries(testoptionalrequired testgenc)
add_test(NAME testoptionalrequired COMMAND testoptionalrequired)
include_directories("${PROJECT_SOURCE_DIR}/test/c_glib/src" "${CMAKE_CURRENT_BINARY_DIR}/gen-c_glib")
add_executable(testthrifttest testthrifttest.c
${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_test_handler.c
${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_test_handler.h
gen-c_glib/t_test_thrift_test_types.h)
target_link_libraries(testthrifttest testgenc)
add_test(NAME testthrifttest COMMAND testthrifttest)
if(BUILD_CPP)
include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")
# Create the thrift C++ test library
set(testgenc_cpp_SOURCES
gen-cpp/ThriftTest.cpp
gen-cpp/ThriftTest_constants.cpp
gen-cpp/ThriftTest_types.cpp
gen-cpp/ThriftTest.h
gen-cpp/ThriftTest_constants.h
gen-cpp/ThriftTest_types.h
)
add_library(testgenc_cpp STATIC ${testgenc_cpp_SOURCES})
LINK_AGAINST_THRIFT_LIBRARY(testgenc_cpp thrift)
#HACK: testthrifttestclient.cpp includes ThriftTest.h without gen-*/ prefixes
# so we include it here
include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp" "${CMAKE_CURRENT_BINARY_DIR}/gen-c_glib")
add_executable(testthrifttestclient testthrifttestclient.cpp)
target_link_libraries(testthrifttestclient testgenc testgenc_cpp ${ZLIB_LIBRARIES})
add_test(NAME testthrifttestclient COMMAND testthrifttestclient)
endif(BUILD_CPP)
#
# Common thrift code generation rules
#
add_custom_command(OUTPUT
gen-c_glib/t_test_debug_proto_test_types.c
gen-c_glib/t_test_debug_proto_test_types.h
gen-c_glib/t_test_empty_service.c
gen-c_glib/t_test_empty_service.h
gen-c_glib/t_test_inherited.c
gen-c_glib/t_test_inherited.h
gen-c_glib/t_test_reverse_order_service.c
gen-c_glib/t_test_reverse_order_service.h
gen-c_glib/t_test_service_for_exception_with_a_map.c
gen-c_glib/t_test_service_for_exception_with_a_map.h
gen-c_glib/t_test_srv.c
gen-c_glib/t_test_srv.h
COMMAND ${THRIFT_COMPILER} --gen c_glib ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift
)
add_custom_command(OUTPUT
gen-c_glib/t_test_enum_test_types.c
gen-c_glib/t_test_enum_test_types.h
gen-c_glib/t_test_enum_test_service.c
gen-c_glib/t_test_enum_test_service.h
COMMAND ${THRIFT_COMPILER} --gen c_glib ${PROJECT_SOURCE_DIR}/test/EnumTest.thrift
)
add_custom_command(OUTPUT
gen-c_glib/t_test_optional_required_test_types.c
gen-c_glib/t_test_optional_required_test_types.h
COMMAND ${THRIFT_COMPILER} --gen c_glib ${PROJECT_SOURCE_DIR}/test/OptionalRequiredTest.thrift
)
add_custom_command(OUTPUT
gen-c_glib/t_test_second_service.c
gen-c_glib/t_test_thrift_test.c
gen-c_glib/t_test_thrift_test_types.c
gen-c_glib/t_test_second_service.h
gen-c_glib/t_test_thrift_test.h
gen-c_glib/t_test_thrift_test_types.h
COMMAND ${THRIFT_COMPILER} --gen c_glib ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
)
add_custom_command(OUTPUT
gen-cpp/ThriftTest.cpp
gen-cpp/ThriftTest_constants.cpp
gen-cpp/ThriftTest_types.cpp
gen-cpp/ThriftTest.h
gen-cpp/ThriftTest_constants.h
gen-cpp/ThriftTest_types.h
COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
)
# TODO: Add memory checks using ctest_memcheck or similar

View file

@ -0,0 +1,35 @@
/*
* 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.
*/
namespace c_glib TTest
typedef list<string> StringList
typedef list<StringList> ListStringList
struct ContainersWithDefaultValues {
1: list<string> StringList = [ "Apache", "Thrift" ];
}
service ContainerService {
void receiveStringList(1: list<string> stringList);
list<string> returnStringList();
list<list<string>> returnListStringList();
ListStringList returnTypedefdListStringList();
}

315
vendor/git.apache.org/thrift.git/lib/c_glib/test/Makefile.am generated vendored Executable file
View file

@ -0,0 +1,315 @@
#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests
SUBDIRS =
BUILT_SOURCES = \
gen-c_glib/t_test_container_test_types.c \
gen-c_glib/t_test_container_test_types.h \
gen-c_glib/t_test_debug_proto_test_types.h \
gen-c_glib/t_test_empty_service.h \
gen-c_glib/t_test_inherited.h \
gen-c_glib/t_test_optional_required_test_types.h \
gen-c_glib/t_test_reverse_order_service.h \
gen-c_glib/t_test_second_service.h \
gen-c_glib/t_test_service_for_exception_with_a_map.h \
gen-c_glib/t_test_container_service.c \
gen-c_glib/t_test_container_service.h \
gen-c_glib/t_test_srv.h \
gen-c_glib/t_test_thrift_test.h \
gen-c_glib/t_test_thrift_test_types.h
AM_CPPFLAGS = -I../src -I./gen-c_glib
AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) \
@GCOV_CFLAGS@
AM_CXXFLAGS = $(AM_CFLAGS)
AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) @GCOV_LDFLAGS@
check_PROGRAMS = \
testserialization \
testapplicationexception \
testcontainertest \
testtransportsocket \
testbinaryprotocol \
testcompactprotocol \
testbufferedtransport \
testframedtransport \
testfdtransport \
testmemorybuffer \
teststruct \
testsimpleserver \
testdebugproto \
testoptionalrequired \
testthrifttest
if WITH_CPP
BUILT_SOURCES += gen-cpp/ThriftTest_types.cpp
check_PROGRAMS += testthrifttestclient
endif
testserialization_SOURCES = testserialization.c
testserialization_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
libtestgenc.la
testapplicationexception_SOURCES = testapplicationexception.c
testapplicationexception_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o
testcontainertest_SOURCES = testcontainertest.c
testcontainertest_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \
libtestgenc.la
testtransportsocket_SOURCES = testtransportsocket.c
testtransportsocket_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o
testbinaryprotocol_SOURCES = testbinaryprotocol.c
testbinaryprotocol_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o
testcompactprotocol_SOURCES = testcompactprotocol.c
testcompactprotocol_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o
testbufferedtransport_SOURCES = testbufferedtransport.c
testbufferedtransport_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o
testframedtransport_SOURCES = testframedtransport.c
testframedtransport_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o
testfdtransport_SOURCES = testfdtransport.c
testfdtransport_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o
testmemorybuffer_SOURCES = testmemorybuffer.c
testmemorybuffer_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o
teststruct_SOURCES = teststruct.c
teststruct_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o
testsimpleserver_SOURCES = testsimpleserver.c
testsimpleserver_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o
testdebugproto_SOURCES = testdebugproto.c
testdebugproto_LDADD = libtestgenc.la
testoptionalrequired_SOURCES = testoptionalrequired.c
testoptionalrequired_LDADD = \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
$(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
libtestgenc.la
testthrifttest_SOURCES = testthrifttest.c
testthrifttest_LDADD = libtestgenc.la \
$(top_builddir)/test/c_glib/src/thrift_test_handler.o
testthrifttest_CFLAGS = -I$(top_srcdir)/test/c_glib/src -I./gen-c_glib $(GLIB_CFLAGS)
testthrifttestclient_SOURCES = testthrifttestclient.cpp
testthrifttestclient_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp -I../src -I./gen-c_glib $(GLIB_CFLAGS)
testthrifttestclient_LDADD = ../../cpp/.libs/libthrift.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la
testthrifttestclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS)
check_LTLIBRARIES = libtestgenc.la
if WITH_CPP
check_LTLIBRARIES += libtestgencpp.la
endif
nodist_libtestgenc_la_SOURCES = \
gen-c_glib/t_test_container_test_types.c \
gen-c_glib/t_test_debug_proto_test_types.c \
gen-c_glib/t_test_enum_test_types.c \
gen-c_glib/t_test_enum_test_service.c \
gen-c_glib/t_test_empty_service.c \
gen-c_glib/t_test_inherited.c \
gen-c_glib/t_test_optional_required_test_types.c \
gen-c_glib/t_test_reverse_order_service.c \
gen-c_glib/t_test_second_service.c \
gen-c_glib/t_test_service_for_exception_with_a_map.c \
gen-c_glib/t_test_srv.c \
gen-c_glib/t_test_container_service.c \
gen-c_glib/t_test_thrift_test.c \
gen-c_glib/t_test_thrift_test_types.c \
gen-c_glib/t_test_container_test_types.h \
gen-c_glib/t_test_debug_proto_test_types.h \
gen-c_glib/t_test_enum_test_types.h \
gen-c_glib/t_test_enum_test_service.h \
gen-c_glib/t_test_empty_service.h \
gen-c_glib/t_test_inherited.h \
gen-c_glib/t_test_optional_required_test_types.h \
gen-c_glib/t_test_reverse_order_service.h \
gen-c_glib/t_test_second_service.h \
gen-c_glib/t_test_service_for_exception_with_a_map.h \
gen-c_glib/t_test_srv.h \
gen-c_glib/t_test_container_service.h \
gen-c_glib/t_test_thrift_test.h \
gen-c_glib/t_test_thrift_test_types.h
libtestgenc_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la
libtestgenc_la_CPPFLAGS = $(AM_CPPFLAGS) -Wno-unused-function
nodist_libtestgencpp_la_SOURCES = \
gen-cpp/ThriftTest.cpp \
gen-cpp/ThriftTest_constants.cpp \
gen-cpp/ThriftTest_types.cpp \
gen-cpp/ThriftTest.h \
gen-cpp/ThriftTest_constants.h \
gen-cpp/ThriftTest_types.h
libtestgencpp_la_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp
THRIFT = $(top_builddir)/compiler/cpp/thrift
gen-c_glib/t_test_container_test_types.c gen-c_glib/t_test_container_test_types.h gen-c_glib/t_test_container_service.c gen-c_glib/t_test_container_service.h: ContainerTest.thrift $(THRIFT)
$(THRIFT) --gen c_glib $<
gen-c_glib/t_test_debug_proto_test_types.c gen-c_glib/t_test_debug_proto_test_types.h gen-c_glib/t_test_empty_service.c gen-c_glib/t_test_empty_service.h gen-c_glib/t_test_inherited.c gen-c_glib/t_test_inherited.h gen-c_glib/t_test_reverse_order_service.c gen-c_glib/t_test_reverse_order_service.h gen-c_glib/t_test_service_for_exception_with_a_map.c gen-c_glib/t_test_service_for_exception_with_a_map.h gen-c_glib/t_test_srv.c gen-c_glib/t_test_srv.h: ../../../test/DebugProtoTest.thrift $(THRIFT)
$(THRIFT) --gen c_glib $<
gen-c_glib/t_test_enum_test_types.c gen-c_glib/t_test_enum_test_types.h gen-c_glib/t_test_enum_test_service.c gen-c_glib/t_test_enum_test_service.h : ../../../test/EnumTest.thrift $(THRIFT)
$(THRIFT) --gen c_glib $<
gen-c_glib/t_test_optional_required_test_types.c gen-c_glib/t_test_optional_required_test_types.h: ../../../test/OptionalRequiredTest.thrift $(THRIFT)
$(THRIFT) --gen c_glib $<
gen-c_glib/t_test_second_service.c gen-c_glib/t_test_thrift_test.c gen-c_glib/t_test_thrift_test_types.c gen-c_glib/t_test_second_service.h gen-c_glib/t_test_thrift_test.h gen-c_glib/t_test_thrift_test_types.h: ../../../test/ThriftTest.thrift $(THRIFT)
$(THRIFT) --gen c_glib $<
gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest_types.cpp: ../../../test/ThriftTest.thrift $(THRIFT)
$(THRIFT) --gen cpp $<
TESTS = \
$(check_PROGRAMS) \
$(check_SCRIPTS)
# globally added to all instances of valgrind calls
# VALGRIND_OPTS = --suppressions=glib.suppress
VALGRIND_OPTS =
# globally added to all memcheck calls
VALGRIND_MEM_OPTS = --tool=memcheck \
--num-callers=10 \
${myextravalgrindmemopts}
# globally added to all leakcheck calls
VALGRIND_LEAK_OPTS = --tool=memcheck \
--num-callers=10 \
--leak-check=full \
--leak-resolution=high \
${myextravalgrindleakopts}
memcheck: $(check_PROGRAMS)
@for x in $(check_PROGRAMS); \
do \
$(MAKE) memcheck-$$x; \
done
leakcheck: $(check_PROGRAMS)
@for x in $(check_PROGRAMS); \
do \
$(MAKE) leakcheck-$$x; \
done
memcheck-%: %
@echo "*****************************************"; \
echo "MEMCHECK: $<"; \
echo "ARGS: ${VALGRIND_OPTS} ${VALGRIND_MEM_OPTS} ${$<_VALGRIND_MEM_OPTS}"; \
$(LIBTOOL) --mode=execute \
valgrind \
${VALGRIND_OPTS} \
${VALGRIND_MEM_OPTS} \
${$<_VALGRIND_MEM_OPTS} ./$<
leakcheck-%: %
@echo "*****************************************"; \
echo "LEAKCHECK: $<"; \
echo "ARGS: ${VALGRIND_OPTS} ${VALGRIND_LEAK_OPTS} ${$<_VALGRIND_LEAK_OPTS}"; \
G_SLICE=always-malloc $(LIBTOOL) --mode=execute \
valgrind \
${VALGRIND_OPTS} \
${VALGRIND_LEAK_OPTS} \
${$<_VALGRIND_LEAK_OPTS} ./$<
clean-local:
$(RM) gen-c_glib/* gen-cpp/*
CLEANFILES = \
*.bb \
*.bbg \
*.da \
*.gcno \
*.gcda \
*.gcov
EXTRA_DIST = \
CMakeLists.txt \
ContainerTest.thrift

View file

@ -0,0 +1,64 @@
{
g_type_init_1
Memcheck:Leak
fun:malloc
...
fun:g_type_init_with_debug_flags
}
{
g_type_init_2
Memcheck:Leak
fun:calloc
...
fun:g_type_init_with_debug_flags
}
{
g_type_init_3
Memcheck:Leak
fun:realloc
...
fun:g_type_init_with_debug_flags
}
{
g_type_register_static_1
Memcheck:Leak
fun:realloc
...
fun:g_type_register_static
}
{
g_type_register_statuc_2
Memcheck:Leak
fun:malloc
fun:realloc
fun:g_realloc
...
fun:g_type_register_static
}
{
type_class_init_Wm1
Memcheck:Leak
fun:calloc
fun:g_malloc0
fun:type_class_init_Wm
fun:g_type_class_ref
...
fun:g_object_newv
}
{
type_class_init_Wm2
Memcheck:Leak
fun:calloc
fun:g_malloc0
fun:type_class_init_Wm
fun:g_type_class_ref
...
fun:type_class_init_Wm
}

View file

@ -0,0 +1,180 @@
/*
* 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 <glib.h>
#include <string.h>
#include <thrift/c_glib/thrift_application_exception.h>
static void
test_create_and_destroy (void)
{
GObject *object = NULL;
/* A ThriftApplicationException can be created... */
object = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);
g_assert (object != NULL);
g_assert (THRIFT_IS_APPLICATION_EXCEPTION (object));
/* ...and destroyed */
g_object_unref (object);
}
static void
test_initialize (void)
{
ThriftApplicationException *xception = NULL;
gint32 type = THRIFT_APPLICATION_EXCEPTION_ERROR_INTERNAL_ERROR;
gchar *message = "Exception message";
gint32 retrieved_type = 0;
gchar *retrieved_message = NULL;
/* A ThriftApplicationException has "type" and "message" properties that can
be initialized at object creation */
xception =
g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION,
"type", type,
"message", message,
NULL);
g_assert (xception != NULL);
/* A ThriftApplicationException's properties can be retrieved */
g_object_get (xception,
"type", &retrieved_type,
"message", &retrieved_message,
NULL);
g_assert (retrieved_type == type);
g_assert (retrieved_message != NULL);
g_assert_cmpstr (retrieved_message, ==, message);
g_free (retrieved_message);
g_object_unref (xception);
}
static void
test_properties_test (void)
{
ThriftApplicationException *xception = NULL;
gint32 retrieved_type;
xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);
#define TEST_TYPE_VALUE(_type) \
retrieved_type = -1; \
g_object_set (xception, "type", _type, NULL); \
g_object_get (xception, "type", &retrieved_type, NULL); \
g_assert_cmpint (retrieved_type, ==, _type);
/* The "type" property can be set to any valid Thrift exception type */
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_BAD_SEQUENCE_ID);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_MISSING_RESULT);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INTERNAL_ERROR);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_PROTOCOL_ERROR);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_TRANSFORM);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_PROTOCOL);
TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_UNSUPPORTED_CLIENT_TYPE);
/* "g_test_expect_message" is required for the property range tests below but is
not present in GLib before version 2.34 */
#if (GLIB_CHECK_VERSION (2, 34, 0))
g_object_set (xception,
"type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN,
NULL);
/* The "type" property cannot be set to a value too low (less than zero) */
g_test_expect_message ("GLib-GObject",
G_LOG_LEVEL_WARNING,
"value*out of range*type*");
g_object_set (xception, "type", -1, NULL);
g_test_assert_expected_messages ();
g_object_get (xception, "type", &retrieved_type, NULL);
g_assert_cmpint (retrieved_type, !=, -1);
g_assert_cmpint (retrieved_type,
==,
THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN);
/* The "type" property cannot be set to a value too high (greater than the
highest defined exception-type value) */
g_test_expect_message ("GLib-GObject",
G_LOG_LEVEL_WARNING,
"value*out of range*type*");
g_object_set (xception, "type", THRIFT_APPLICATION_EXCEPTION_ERROR_N, NULL);
g_test_assert_expected_messages ();
g_object_get (xception, "type", &retrieved_type, NULL);
g_assert_cmpint (retrieved_type, !=, THRIFT_APPLICATION_EXCEPTION_ERROR_N);
g_assert_cmpint (retrieved_type,
==,
THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN);
#endif
g_object_unref (xception);
}
static void
test_properties_message (void)
{
ThriftApplicationException *xception = NULL;
gchar *message = "Exception message";
gchar *retrieved_message;
xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);
/* The "message" property can be set to NULL */
g_object_set (xception, "message", NULL, NULL);
g_object_get (xception, "message", &retrieved_message, NULL);
g_assert (retrieved_message == NULL);
/* The "message" property can be set to a valid string */
g_object_set (xception, "message", message, NULL);
g_object_get (xception, "message", &retrieved_message, NULL);
g_assert_cmpint (strcmp (retrieved_message, message), ==, 0);
g_free (retrieved_message);
g_object_unref (xception);
}
int
main (int argc, char **argv)
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init ();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testapplicationexception/CreateAndDestroy",
test_create_and_destroy);
g_test_add_func ("/testapplicationexception/Initialize",
test_initialize);
g_test_add_func ("/testapplicationexception/Properties/test",
test_properties_test);
g_test_add_func ("/testapplicationexception/Properties/message",
test_properties_message);
return g_test_run ();
}

View file

@ -0,0 +1,838 @@
/*
* 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.
*/
/* Disable string-function optimizations when glibc is used, as these produce
compiler warnings about string length when a string function is used inside
a call to assert () */
#ifdef __GLIBC__
#include <features.h>
#define __NO_STRING_INLINES 1
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <netdb.h>
#include <string.h>
#include <sys/wait.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#include <thrift/c_glib/transport/thrift_framed_transport.h>
#define TEST_BOOL TRUE
#define TEST_BYTE 123
#define TEST_I16 12345
#define TEST_I32 1234567890
#define TEST_I64 G_GINT64_CONSTANT (123456789012345)
#define TEST_DOUBLE 1234567890.123
#define TEST_STRING "this is a test string 1234567890!@#$%^&*()"
#define TEST_PORT 51199
static int transport_read_count = 0;
static int transport_read_error = 0;
static int transport_read_error_at = -1;
gint32
my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
if (transport_read_count != transport_read_error_at
&& transport_read_error == 0)
{
transport_read_count++;
return thrift_transport_read_all (transport, buf, len, error);
}
return -1;
}
static int transport_write_count = 0;
static int transport_write_error = 0;
static int transport_write_error_at = -1;
gboolean
my_thrift_transport_write (ThriftTransport *transport, const gpointer buf,
const guint32 len, GError **error)
{
if (transport_write_count != transport_write_error_at
&& transport_write_error == 0)
{
transport_write_count++;
return thrift_transport_write (transport, buf, len, error);
}
return FALSE;
}
#define thrift_transport_read_all my_thrift_transport_read_all
#define thrift_transport_write my_thrift_transport_write
#include "../src/thrift/c_glib/protocol/thrift_binary_protocol.c"
#undef thrift_transport_read_all
#undef thrift_transport_write
static void thrift_server_primitives (const int port);
static void thrift_server_complex_types (const int port);
static void thrift_server_many_frames (const int port);
static void
test_create_and_destroy(void)
{
GObject *object = NULL;
/* create an object and then destroy it */
object = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, NULL);
assert (object != NULL);
g_object_unref (object);
}
static void
test_initialize(void)
{
ThriftSocket *tsocket = NULL;
ThriftBinaryProtocol *protocol = NULL;
ThriftSocket *temp = NULL;
/* create a ThriftTransport */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", 51188, NULL);
assert (tsocket != NULL);
/* create a ThriftBinaryProtocol using the Transport */
protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
tsocket, NULL);
assert (protocol != NULL);
/* fetch the properties */
g_object_get (G_OBJECT(protocol), "transport", &temp, NULL);
g_object_unref (temp);
/* clean up memory */
g_object_unref (protocol);
g_object_unref (tsocket);
}
static void
test_read_and_write_primitives(void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
ThriftBinaryProtocol *tb = NULL;
ThriftProtocol *protocol = NULL;
gpointer binary = (gpointer *) TEST_STRING;
guint32 len = strlen (TEST_STRING);
int port = TEST_PORT;
/* fork a server from the client */
pid = fork ();
assert (pid >= 0);
if (pid == 0)
{
/* child listens */
thrift_server_primitives (port);
exit (0);
} else {
/* parent. wait a bit for the socket to be created. */
sleep (1);
/* create a ThriftSocket */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
transport = THRIFT_TRANSPORT (tsocket);
thrift_transport_open (transport, NULL);
assert (thrift_transport_is_open (transport));
/* create a ThriftBinaryTransport */
tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
tsocket, NULL);
protocol = THRIFT_PROTOCOL (tb);
assert (protocol != NULL);
/* write a bunch of primitives */
assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
assert (thrift_binary_protocol_write_double (protocol,
TEST_DOUBLE, NULL) > 0);
assert (thrift_binary_protocol_write_string (protocol,
TEST_STRING, NULL) > 0);
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) > 0);
assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) > 0);
/* test write errors */
transport_write_error = 1;
assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE,
NULL) == -1);
assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) == -1);
assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) == -1);
assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) == -1);
assert (thrift_binary_protocol_write_double (protocol, TEST_DOUBLE,
NULL) == -1);
assert (thrift_binary_protocol_write_binary (protocol, binary, len,
NULL) == -1);
transport_write_error = 0;
/* test binary partial failure */
transport_write_count = 0;
transport_write_error_at = 1;
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) == -1);
transport_write_error_at = -1;
/* clean up */
thrift_transport_close (transport, NULL);
g_object_unref (tsocket);
g_object_unref (protocol);
assert (wait (&status) == pid);
assert (status == 0);
}
}
static void
test_read_and_write_complex_types (void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
ThriftBinaryProtocol *tb = NULL;
ThriftProtocol *protocol = NULL;
int port = TEST_PORT;
/* fork a server from the client */
pid = fork ();
assert (pid >= 0);
if (pid == 0)
{
/* child listens */
thrift_server_complex_types (port);
exit (0);
} else {
/* parent. wait a bit for the socket to be created. */
sleep (1);
/* create a ThriftSocket */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
transport = THRIFT_TRANSPORT (tsocket);
thrift_transport_open (transport, NULL);
assert (thrift_transport_is_open (transport));
/* create a ThriftBinaryTransport */
tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
tsocket, NULL);
protocol = THRIFT_PROTOCOL (tb);
assert (protocol != NULL);
/* test structures */
assert (thrift_binary_protocol_write_struct_begin (protocol,
NULL, NULL) == 0);
assert (thrift_binary_protocol_write_struct_end (protocol, NULL) == 0);
assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
1, NULL) > 0);
assert (thrift_binary_protocol_write_field_end (protocol, NULL) == 0);
/* test write error */
transport_write_error = 1;
assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
1, NULL) == -1);
transport_write_error = 0;
/* test 2nd write error */
transport_write_count = 0;
transport_write_error_at = 1;
assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
1, NULL) == -1);
transport_write_error_at = -1;
/* test 2nd read failure on a field */
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
/* test write_field_stop */
assert (thrift_binary_protocol_write_field_stop (protocol, NULL) > 0);
/* write a map */
assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
1, NULL) > 0);
assert (thrift_binary_protocol_write_map_end (protocol, NULL) == 0);
/* test 2nd read failure on a map */
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
/* test 3rd read failure on a map */
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
/* test 1st write failure on a map */
transport_write_error = 1;
assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
1, NULL) == -1);
transport_write_error = 0;
/* test 2nd write failure on a map */
transport_write_count = 0;
transport_write_error_at = 1;
assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
1, NULL) == -1);
transport_write_error_at = -1;
/* test 3rd write failure on a map */
transport_write_count = 0;
transport_write_error_at = 2;
assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
1, NULL) == -1);
transport_write_error_at = -1;
/* test negative map size */
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
thrift_binary_protocol_write_i32 (protocol, -10, NULL);
/* test list operations */
assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
1, NULL) > 0);
assert (thrift_binary_protocol_write_list_end (protocol, NULL) == 0);
/* test 2nd read failure on a list */
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
/* test negative list size */
thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
thrift_binary_protocol_write_i32 (protocol, -10, NULL);
/* test first write error on a list */
transport_write_error = 1;
assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
1, NULL) == -1);
transport_write_error = 0;
/* test 2nd write error on a list */
transport_write_count = 0;
transport_write_error_at = 1;
assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
1, NULL) == -1);
transport_write_error_at = -1;
/* test set operation s*/
assert (thrift_binary_protocol_write_set_begin (protocol, T_VOID,
1, NULL) > 0);
assert (thrift_binary_protocol_write_set_end (protocol, NULL) == 0);
/* invalid version */
assert (thrift_binary_protocol_write_i32 (protocol, -1, NULL) > 0);
/* sz > 0 for a message */
assert (thrift_binary_protocol_write_i32 (protocol, 1, NULL) > 0);
/* send a valid message */
thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL);
thrift_binary_protocol_write_string (protocol, "test", NULL);
thrift_binary_protocol_write_i32 (protocol, 1, NULL);
/* broken 2nd read */
thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL);
/* send a broken 3rd read */
thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL);
thrift_binary_protocol_write_string (protocol, "test", NULL);
/* send a valid message */
assert (thrift_binary_protocol_write_message_begin (protocol, "test",
T_CALL, 1, NULL) > 0);
assert (thrift_binary_protocol_write_message_end (protocol, NULL) == 0);
/* send broken writes */
transport_write_error = 1;
assert (thrift_binary_protocol_write_message_begin (protocol, "test",
T_CALL, 1, NULL) == -1);
transport_write_error = 0;
transport_write_count = 0;
transport_write_error_at = 2;
assert (thrift_binary_protocol_write_message_begin (protocol, "test",
T_CALL, 1, NULL) == -1);
transport_write_error_at = -1;
transport_write_count = 0;
transport_write_error_at = 3;
assert (thrift_binary_protocol_write_message_begin (protocol, "test",
T_CALL, 1, NULL) == -1);
transport_write_error_at = -1;
/* clean up */
thrift_transport_close (transport, NULL);
g_object_unref (tsocket);
g_object_unref (protocol);
assert (wait (&status) == pid);
assert (status == 0);
}
}
static void
test_read_and_write_many_frames (void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
ThriftFramedTransport *ft = NULL;
ThriftBinaryProtocol *tb = NULL;
ThriftProtocol *protocol = NULL;
gpointer binary = (gpointer *) TEST_STRING;
const guint32 len = strlen (TEST_STRING);
int port = TEST_PORT;
/* fork a server from the client */
pid = fork ();
assert (pid >= 0);
if (pid == 0)
{
/* child listens */
thrift_server_many_frames (port);
exit (0);
} else {
/* parent. wait a bit for the socket to be created. */
sleep (1);
/* create a ThriftSocket */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
assert (tsocket != NULL);
transport = THRIFT_TRANSPORT (tsocket);
/* wrap in a framed transport */
ft = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", transport,
"w_buf_size", 1, NULL);
assert (ft != NULL);
transport = THRIFT_TRANSPORT (ft);
thrift_transport_open (transport, NULL);
assert (thrift_transport_is_open (transport));
/* create a binary protocol */
tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
transport, NULL);
protocol = THRIFT_PROTOCOL (tb);
assert (protocol != NULL);
/* write a bunch of primitives */
assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_double (protocol,
TEST_DOUBLE, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_string (protocol,
TEST_STRING, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) > 0);
thrift_transport_flush (transport, NULL);
/* clean up */
thrift_transport_write_end (transport, NULL);
thrift_transport_close (transport, NULL);
g_object_unref (ft);
g_object_unref (tsocket);
g_object_unref (tb);
assert (wait (&status) == pid);
assert (status == 0);
}
}
static void
thrift_server_primitives (const int port)
{
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
ThriftBinaryProtocol *tbp = NULL;
ThriftProtocol *protocol = NULL;
gboolean value_boolean = FALSE;
gint8 value_byte = 0;
gint16 value_16 = 0;
gint32 value_32 = 0;
gint64 value_64 = 0;
gdouble value_double = 0;
gchar *string = NULL;
gpointer binary = NULL;
guint32 len = 0;
void *comparator = (void *) TEST_STRING;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
client = thrift_server_transport_accept (transport, NULL);
assert (client != NULL);
tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
client, NULL);
protocol = THRIFT_PROTOCOL (tbp);
assert (thrift_binary_protocol_read_bool (protocol,
&value_boolean, NULL) > 0);
assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0);
assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0);
assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0);
assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0);
assert (thrift_binary_protocol_read_double (protocol,
&value_double, NULL) > 0);
assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
assert (thrift_binary_protocol_read_binary (protocol, &binary,
&len, NULL) > 0);
assert (value_boolean == TEST_BOOL);
assert (value_byte == TEST_BYTE);
assert (value_16 == TEST_I16);
assert (value_32 == TEST_I32);
assert (value_64 == TEST_I64);
assert (value_double == TEST_DOUBLE);
assert (strcmp (TEST_STRING, string) == 0);
assert (memcmp (comparator, binary, len) == 0);
g_free (string);
g_free (binary);
thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL);
g_free (binary);
transport_read_count = 0;
transport_read_error_at = 0;
assert (thrift_binary_protocol_read_binary (protocol, &binary,
&len, NULL) == -1);
transport_read_error_at = -1;
transport_read_count = 0;
transport_read_error_at = 1;
assert (thrift_binary_protocol_read_binary (protocol, &binary,
&len, NULL) == -1);
transport_read_error_at = -1;
transport_read_error = 1;
assert (thrift_binary_protocol_read_bool (protocol,
&value_boolean, NULL) == -1);
assert (thrift_binary_protocol_read_byte (protocol,
&value_byte, NULL) == -1);
assert (thrift_binary_protocol_read_i16 (protocol,
&value_16, NULL) == -1);
assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) == -1);
assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) == -1);
assert (thrift_binary_protocol_read_double (protocol,
&value_double, NULL) == -1);
transport_read_error = 0;
/* test partial write failure */
thrift_protocol_read_i32 (protocol, &value_32, NULL);
thrift_transport_read_end (client, NULL);
thrift_transport_close (client, NULL);
g_object_unref (tbp);
g_object_unref (client);
g_object_unref (tsocket);
}
static void
thrift_server_complex_types (const int port)
{
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
ThriftBinaryProtocol *tbp = NULL;
ThriftProtocol *protocol = NULL;
gchar *struct_name = NULL;
gchar *field_name = NULL;
gchar *message_name = NULL;
ThriftType element_type, key_type, value_type, field_type;
ThriftMessageType message_type;
gint8 value = 0;
gint16 field_id = 0;
guint32 size = 0;
gint32 seqid = 0;
gint32 version = 0;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
client = thrift_server_transport_accept (transport, NULL);
assert (client != NULL);
tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
client, NULL);
protocol = THRIFT_PROTOCOL (tbp);
thrift_binary_protocol_read_struct_begin (protocol, &struct_name, NULL);
thrift_binary_protocol_read_struct_end (protocol, NULL);
thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type,
&field_id, NULL);
thrift_binary_protocol_read_field_end (protocol, NULL);
/* test first read error on a field */
transport_read_error = 1;
assert (thrift_binary_protocol_read_field_begin (protocol,
&field_name, &field_type,
&field_id, NULL) == -1);
transport_read_error = 0;
/* test 2nd write failure */
thrift_binary_protocol_read_byte (protocol, &value, NULL);
/* test 2nd read failure on a field */
transport_read_count = 0;
transport_read_error_at = 1;
assert (thrift_binary_protocol_read_field_begin (protocol,
&field_name, &field_type,
&field_id, NULL) == -1);
transport_read_error_at = -1;
/* test field stop */
thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type,
&field_id, NULL);
thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type,
&size, NULL);
thrift_binary_protocol_read_map_end (protocol, NULL);
/* test read failure on a map */
transport_read_count = 0;
transport_read_error_at = 0;
assert (thrift_binary_protocol_read_map_begin (protocol,
&key_type, &value_type,
&size, NULL) == -1);
transport_read_error_at = -1;
/* test 2nd read failure on a map */
transport_read_count = 0;
transport_read_error_at = 1;
assert (thrift_binary_protocol_read_map_begin (protocol,
&key_type, &value_type,
&size, NULL) == -1);
transport_read_error_at = -1;
/* test 3rd read failure on a map */
transport_read_count = 0;
transport_read_error_at = 2;
assert (thrift_binary_protocol_read_map_begin (protocol,
&key_type, &value_type,
&size, NULL) == -1);
transport_read_error_at = -1;
/* test 2nd write failure */
thrift_binary_protocol_read_byte (protocol, &value, NULL);
/* test 3rd write failure */
thrift_binary_protocol_read_byte (protocol, &value, NULL);
thrift_binary_protocol_read_byte (protocol, &value, NULL);
/* test negative map size */
assert (thrift_binary_protocol_read_map_begin (protocol,
&key_type, &value_type,
&size, NULL) == -1);
/* test list operations */
thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL);
thrift_binary_protocol_read_list_end (protocol, NULL);
/* test read failure */
transport_read_error = 1;
assert (thrift_binary_protocol_read_list_begin (protocol, &element_type,
&size, NULL) == -1);
transport_read_error = 0;
/* test 2nd read failure */
transport_read_count = 0;
transport_read_error_at = 1;
thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL);
transport_read_error_at = -1;
/* test negative list size failure */
thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL);
/* test 2nd write failure */
thrift_binary_protocol_read_byte (protocol, &value, NULL);
/* test set operations */
thrift_binary_protocol_read_set_begin (protocol, &element_type, &size, NULL);
thrift_binary_protocol_read_set_end (protocol, NULL);
/* broken read */
transport_read_error = 1;
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) == -1);
transport_read_error = 0;
/* invalid protocol version */
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) == -1);
/* sz > 0 */
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) > 0);
/* read a valid message */
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) > 0);
g_free (message_name);
/* broken 2nd read on a message */
transport_read_count = 0;
transport_read_error_at = 1;
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) == -1);
transport_read_error_at = -1;
/* broken 3rd read on a message */
transport_read_count = 0;
transport_read_error_at = 3; /* read_string does two reads */
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) == -1);
g_free (message_name);
transport_read_error_at = -1;
/* read a valid message */
assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
&message_type, &seqid,
NULL) > 0);
g_free (message_name);
assert (thrift_binary_protocol_read_message_end (protocol, NULL) == 0);
/* handle 2nd write failure on a message */
thrift_binary_protocol_read_i32 (protocol, &version, NULL);
/* handle 2nd write failure on a message */
thrift_binary_protocol_read_i32 (protocol, &version, NULL);
thrift_binary_protocol_read_string (protocol, &message_name, NULL);
g_object_unref (client);
/* TODO: investigate g_object_unref (tbp); */
g_object_unref (tsocket);
}
static void
thrift_server_many_frames (const int port)
{
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
ThriftBinaryProtocol *tbp = NULL;
ThriftProtocol *protocol = NULL;
ThriftServerSocket *tsocket = NULL;
gboolean value_boolean = FALSE;
gint8 value_byte = 0;
gint16 value_16 = 0;
gint32 value_32 = 0;
gint64 value_64 = 0;
gdouble value_double = 0;
gchar *string = NULL;
gpointer binary = NULL;
guint32 len = 0;
void *comparator = (void *) TEST_STRING;
tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
/* wrap the client in a framed transport */
client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
thrift_server_transport_accept (transport, NULL),
"r_buf_size", 1, NULL);
assert (client != NULL);
tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
client, NULL);
protocol = THRIFT_PROTOCOL (tbp);
assert (thrift_binary_protocol_read_bool (protocol,
&value_boolean, NULL) > 0);
assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0);
assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0);
assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0);
assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0);
assert (thrift_binary_protocol_read_double (protocol,
&value_double, NULL) > 0);
assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
assert (thrift_binary_protocol_read_binary (protocol, &binary,
&len, NULL) > 0);
assert (value_boolean == TEST_BOOL);
assert (value_byte == TEST_BYTE);
assert (value_16 == TEST_I16);
assert (value_32 == TEST_I32);
assert (value_64 == TEST_I64);
assert (value_double == TEST_DOUBLE);
assert (strcmp (TEST_STRING, string) == 0);
assert (memcmp (comparator, binary, len) == 0);
g_free (string);
g_free (binary);
thrift_transport_read_end (client, NULL);
thrift_transport_close (client, NULL);
g_object_unref (tbp);
g_object_unref (client);
g_object_unref (tsocket);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testbinaryprotocol/CreateAndDestroy", test_create_and_destroy);
g_test_add_func ("/testbinaryprotocol/Initialize", test_initialize);
g_test_add_func ("/testbinaryprotocol/ReadAndWritePrimitives", test_read_and_write_primitives);
g_test_add_func ("/testbinaryprotocol/ReadAndWriteComplexTypes", test_read_and_write_complex_types);
g_test_add_func ("/testbinaryprotocol/ReadAndWriteManyFrames",
test_read_and_write_many_frames);
return g_test_run ();
}

View file

@ -0,0 +1,287 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <signal.h>
#include <sys/wait.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
#include "../src/thrift/c_glib/transport/thrift_buffered_transport.c"
static void thrift_server (const int port);
/* test object creation and destruction */
static void
test_create_and_destroy(void)
{
ThriftTransport *transport = NULL;
guint r_buf_size = 0;
guint w_buf_size = 0;
GObject *object = NULL;
object = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, NULL);
assert (object != NULL);
g_object_get (G_OBJECT (object), "transport", &transport,
"r_buf_size", &r_buf_size,
"w_buf_size", &w_buf_size, NULL);
g_object_unref (object);
}
static void
test_open_and_close(void)
{
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
GError *err = NULL;
/* create a ThriftSocket */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", 51188, NULL);
/* create a BufferedTransport wrapper of the Socket */
transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket), NULL);
/* this shouldn't work */
assert (thrift_buffered_transport_open (transport, NULL) == FALSE);
assert (thrift_buffered_transport_is_open (transport) == TRUE);
assert (thrift_buffered_transport_close (transport, NULL) == TRUE);
g_object_unref (transport);
g_object_unref (tsocket);
/* try and underlying socket failure */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
NULL);
/* create a BufferedTransport wrapper of the Socket */
transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket), NULL);
assert (thrift_buffered_transport_open (transport, &err) == FALSE);
g_object_unref (transport);
g_object_unref (tsocket);
g_error_free (err);
err = NULL;
}
static void
test_read_and_write(void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
int port = 51199;
guchar buf[10] = TEST_DATA; /* a buffer */
pid = fork ();
assert ( pid >= 0 );
if ( pid == 0 )
{
/* child listens */
thrift_server (port);
exit (0);
} else {
/* parent connects, wait a bit for the socket to be created */
sleep (1);
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket),
"w_buf_size", 4, NULL);
assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
assert (thrift_buffered_transport_is_open (transport));
/* write 10 bytes */
thrift_buffered_transport_write (transport, buf, 10, NULL);
/* write 1 byte at a time */
thrift_buffered_transport_write (transport, buf, 1, NULL);
thrift_buffered_transport_write (transport, buf, 1, NULL);
thrift_buffered_transport_write (transport, buf, 1, NULL);
/* overflow the buffer */
thrift_buffered_transport_write (transport, buf, 2, NULL);
thrift_buffered_transport_write (transport, buf, 1, NULL);
thrift_buffered_transport_flush (transport, NULL);
/* write 1 byte and flush */
thrift_buffered_transport_write (transport, buf, 1, NULL);
thrift_buffered_transport_flush (transport, NULL);
/* write and overflow buffer with 2 system calls */
thrift_buffered_transport_write (transport, buf, 1, NULL);
thrift_buffered_transport_write (transport, buf, 3, NULL);
/* write 10 bytes */
thrift_buffered_transport_write (transport, buf, 10, NULL);
thrift_buffered_transport_write_end (transport, NULL);
thrift_buffered_transport_flush (transport, NULL);
thrift_buffered_transport_close (transport, NULL);
g_object_unref (transport);
g_object_unref (tsocket);
assert ( wait (&status) == pid );
assert ( status == 0 );
}
}
static void
thrift_server (const int port)
{
int bytes = 0;
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
guchar buf[10]; /* a buffer */
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
/* wrap the client in a BufferedTransport */
client = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport",
thrift_server_transport_accept (transport, NULL),
"r_buf_size", 5, NULL);
assert (client != NULL);
/* read 10 bytes */
bytes = thrift_buffered_transport_read (client, buf, 10, NULL);
assert (bytes == 10); /* make sure we've read 10 bytes */
assert ( memcmp (buf, match, 10) == 0 ); /* make sure what we got matches */
/* read 1 byte */
bytes = thrift_buffered_transport_read (client, buf, 1, NULL);
bytes = thrift_buffered_transport_read (client, buf, 6, NULL);
bytes = thrift_buffered_transport_read (client, buf, 2, NULL);
bytes = thrift_buffered_transport_read (client, buf, 1, NULL);
thrift_buffered_transport_read_end (client, NULL);
thrift_buffered_transport_close (client, NULL);
g_object_unref (client);
g_object_unref (tsocket);
}
static void
test_write_fail(void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
int port = 51198;
guchar buf[10] = TEST_DATA; /* a buffer */
/* SIGPIPE when send to disconnected socket */
signal(SIGPIPE, SIG_IGN);
pid = fork ();
assert ( pid >= 0 );
if ( pid == 0 )
{
/* child listens */
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
/* wrap the client in a BufferedTransport */
client = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport",
thrift_server_transport_accept (transport, NULL),
"r_buf_size", 5, NULL);
assert (client != NULL);
/* just close socket */
thrift_buffered_transport_close (client, NULL);
g_object_unref (client);
g_object_unref (tsocket);
exit (0);
} else {
/* parent connects, wait a bit for the socket to be created */
sleep (1);
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket),
"w_buf_size", 4, NULL);
assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
assert (thrift_buffered_transport_is_open (transport));
/* recognize disconnection */
sleep(1);
assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == TRUE);
assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
/* write and overflow buffer */
assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
/* write 1 and flush */
assert (thrift_buffered_transport_write (transport, buf, 1, NULL) == TRUE);
assert (thrift_buffered_transport_flush (transport, NULL) == FALSE);
thrift_buffered_transport_close (transport, NULL);
g_object_unref (transport);
g_object_unref (tsocket);
assert ( wait (&status) == pid );
assert ( status == 0 );
}
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testbufferedtransport/CreateAndDestroy", test_create_and_destroy);
g_test_add_func ("/testbufferedtransport/OpenAndClose", test_open_and_close);
g_test_add_func ("/testbufferedtransport/ReadAndWrite", test_read_and_write);
g_test_add_func ("/testbufferedtransport/WriteFail", test_write_fail);
return g_test_run ();
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,530 @@
/*
* 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 "gen-c_glib/t_test_container_test_types.h"
#include "gen-c_glib/t_test_container_service.h"
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
#include <thrift/c_glib/server/thrift_server.h>
#include <thrift/c_glib/server/thrift_simple_server.h>
#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <glib-object.h>
#include <glib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#define TEST_SERVER_HOSTNAME "localhost"
#define TEST_SERVER_PORT 9090
/* --------------------------------------------------------------------------
The ContainerService handler we'll use for testing */
G_BEGIN_DECLS
GType test_container_service_handler_get_type (void);
#define TYPE_TEST_CONTAINER_SERVICE_HANDLER \
(test_container_service_handler_get_type ())
#define TEST_CONTAINER_SERVICE_HANDLER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
TYPE_TEST_CONTAINER_SERVICE_HANDLER, \
TestContainerServiceHandler))
#define TEST_CONTAINER_SERVICE_HANDLER_CLASS(c) \
(G_TYPE_CHECK_CLASS_CAST ((c), \
TYPE_TEST_CONTAINER_SERVICE_HANDLER, \
TestContainerServiceHandlerClass))
#define IS_TEST_CONTAINER_SERVICE_HANDLER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
TYPE_TEST_CONTAINER_SERVICE_HANDLER))
#define IS_TEST_CONTAINER_SERVICE_HANDLER_CLASS(c) \
(G_TYPE_CHECK_CLASS_TYPE ((c), \
TYPE_TEST_CONTAINER_SERVICE_HANDLER))
#define TEST_CONTAINER_SERVICE_HANDLER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
TYPE_TEST_CONTAINER_SERVICE_HANDLER, \
TestContainerServiceHandlerClass))
struct _TestContainerServiceHandler {
TTestContainerServiceHandler parent_instance;
/* private */
GPtrArray *string_list;
};
typedef struct _TestContainerServiceHandler TestContainerServiceHandler;
struct _TestContainerServiceHandlerClass {
TTestContainerServiceHandlerClass parent_class;
};
typedef struct _TestContainerServiceHandlerClass
TestContainerServiceHandlerClass;
G_END_DECLS
/* -------------------------------------------------------------------------- */
G_DEFINE_TYPE (TestContainerServiceHandler,
test_container_service_handler,
T_TEST_TYPE_CONTAINER_SERVICE_HANDLER)
/* A helper function used to append copies of strings to a string list */
static void append_string_to_ptr_array (gpointer element, gpointer ptr_array)
{
g_ptr_array_add ((GPtrArray *)ptr_array, g_strdup ((gchar *)element));
}
/* Accept a string list from the client and append its contents to our internal
list */
static gboolean
test_container_service_handler_receive_string_list (TTestContainerServiceIf *iface,
const GPtrArray *stringList,
GError **error)
{
TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface);
/* Append the client's strings to our own internal string list */
g_ptr_array_foreach ((GPtrArray *)stringList,
append_string_to_ptr_array,
self->string_list);
g_clear_error (error);
return TRUE;
}
/* Return the contents of our internal string list to the client */
static gboolean
test_container_service_handler_return_string_list (TTestContainerServiceIf *iface,
GPtrArray **_return,
GError **error)
{
TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface);
/* Return (copies of) the strings contained in our list */
g_ptr_array_foreach (self->string_list,
append_string_to_ptr_array,
*_return);
g_clear_error (error);
return TRUE;
}
static gboolean
test_container_service_handler_return_list_string_list (TTestContainerServiceIf *iface,
GPtrArray **_return,
GError **error)
{
TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface);
GPtrArray *nested_list;
/* Return a list containing our list of strings */
nested_list
= g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref);
g_ptr_array_add (nested_list, self->string_list);
g_ptr_array_ref (self->string_list);
g_ptr_array_add (*_return, nested_list);
g_clear_error (error);
return TRUE;
}
static gboolean
test_container_service_handler_return_typedefd_list_string_list (TTestContainerServiceIf *iface,
TTestListStringList **_return,
GError **error)
{
TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface);
TTestStringList *nested_list;
/* Return a list containing our list of strings */
nested_list
= g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref);
g_ptr_array_add (nested_list, self->string_list);
g_ptr_array_ref (self->string_list);
g_ptr_array_add (*_return, nested_list);
g_clear_error (error);
return TRUE;
}
static void
test_container_service_handler_finalize (GObject *object) {
TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (object);
/* Destroy our internal containers */
g_ptr_array_unref (self->string_list);
self->string_list = NULL;
G_OBJECT_CLASS (test_container_service_handler_parent_class)->
finalize (object);
}
static void
test_container_service_handler_init (TestContainerServiceHandler *self)
{
/* Create our internal containers */
self->string_list = g_ptr_array_new_with_free_func (g_free);
}
static void
test_container_service_handler_class_init (TestContainerServiceHandlerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
TTestContainerServiceHandlerClass *parent_class =
T_TEST_CONTAINER_SERVICE_HANDLER_CLASS (klass);
gobject_class->finalize = test_container_service_handler_finalize;
parent_class->receive_string_list =
test_container_service_handler_receive_string_list;
parent_class->return_string_list =
test_container_service_handler_return_string_list;
parent_class->return_list_string_list =
test_container_service_handler_return_list_string_list;
parent_class->return_typedefd_list_string_list =
test_container_service_handler_return_typedefd_list_string_list;
}
/* -------------------------------------------------------------------------- */
/* Our test server, declared globally so we can access it within a signal
handler */
ThriftServer *server = NULL;
/* A signal handler used to detect when the child process (the test suite) has
exited so we know to shut down the server and terminate ourselves */
static void
sigchld_handler (int signal_number)
{
THRIFT_UNUSED_VAR (signal_number);
/* The child process (the tests) has exited or been terminated; shut down the
server gracefully */
if (server != NULL)
thrift_server_stop (server);
}
/* A helper function that executes a test case against a newly constructed
service client */
static void
execute_with_service_client (void (*test_case)(TTestContainerServiceIf *,
GError **))
{
ThriftSocket *socket;
ThriftTransport *transport;
ThriftProtocol *protocol;
TTestContainerServiceIf *client;
GError *error = NULL;
/* Create a client with which to access the server */
socket = g_object_new (THRIFT_TYPE_SOCKET,
"hostname", TEST_SERVER_HOSTNAME,
"port", TEST_SERVER_PORT,
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);
g_assert_no_error (error);
client = g_object_new (T_TEST_TYPE_CONTAINER_SERVICE_CLIENT,
"input_protocol", protocol,
"output_protocol", protocol,
NULL);
/* Execute the test against this client */
(*test_case)(client, &error);
g_assert_no_error (error);
/* Clean up and exit */
thrift_transport_close (transport, NULL);
g_object_unref (client);
g_object_unref (protocol);
g_object_unref (transport);
g_object_unref (socket);
}
static void
test_containers_with_default_values (void)
{
TTestContainersWithDefaultValues *default_values;
GPtrArray *string_list;
/* Fetch a new ContainersWithDefaultValues struct and its StringList member */
default_values = g_object_new (T_TEST_TYPE_CONTAINERS_WITH_DEFAULT_VALUES,
NULL);
g_object_get (default_values,
"StringList", &string_list,
NULL);
/* Make sure the list has been populated with its default values */
g_assert_cmpint (string_list->len, ==, 2);
g_assert_cmpstr (((gchar **)string_list->pdata)[0], ==, "Apache");
g_assert_cmpstr (((gchar **)string_list->pdata)[1], ==, "Thrift");
g_ptr_array_unref (string_list);
g_object_unref (default_values);
}
static void
test_container_service_string_list_inner (TTestContainerServiceIf *client,
GError **error)
{
gchar *test_data[] = { "one", "two", "three" };
GPtrArray *outgoing_string_list;
GPtrArray *incoming_string_list;
guint index;
g_clear_error (error);
/* Prepare our test data (our string list to send) */
outgoing_string_list = g_ptr_array_new ();
for (index = 0; index < 3; index += 1)
g_ptr_array_add (outgoing_string_list, &test_data[index]);
/* Send our data to the server and make sure we get the same data back on
retrieve */
g_assert
(t_test_container_service_client_receive_string_list (client,
outgoing_string_list,
error) &&
*error == NULL);
incoming_string_list = g_ptr_array_new ();
g_assert
(t_test_container_service_client_return_string_list (client,
&incoming_string_list,
error) &&
*error == NULL);
/* Make sure the two lists are equivalent */
g_assert_cmpint (incoming_string_list->len, ==, outgoing_string_list->len);
for (index = 0; index < incoming_string_list->len; index += 1)
g_assert_cmpstr (((gchar **)incoming_string_list->pdata)[index],
==,
((gchar **)outgoing_string_list->pdata)[index]);
/* Clean up and exit */
g_ptr_array_unref (incoming_string_list);
g_ptr_array_unref (outgoing_string_list);
}
static void
test_container_service_string_list (void)
{
execute_with_service_client (test_container_service_string_list_inner);
}
static void
test_container_service_list_string_list_inner (TTestContainerServiceIf *client,
GError **error)
{
GPtrArray *incoming_list;
GPtrArray *nested_list;
g_clear_error (error);
/* Receive a list of string lists from the server */
incoming_list =
g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref);
g_assert
(t_test_container_service_client_return_list_string_list (client,
&incoming_list,
error) &&
*error == NULL);
/* Make sure the list and its contents are valid */
g_assert_cmpint (incoming_list->len, >, 0);
nested_list = (GPtrArray *)g_ptr_array_index (incoming_list, 0);
g_assert (nested_list != NULL);
g_assert_cmpint (nested_list->len, >=, 0);
/* Clean up and exit */
g_ptr_array_unref (incoming_list);
}
static void
test_container_service_list_string_list (void)
{
execute_with_service_client (test_container_service_list_string_list_inner);
}
static void
test_container_service_typedefd_list_string_list_inner (TTestContainerServiceIf *client,
GError **error)
{
TTestListStringList *incoming_list;
TTestStringList *nested_list;
g_clear_error (error);
/* Receive a list of string lists from the server */
incoming_list =
g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref);
g_assert
(t_test_container_service_client_return_list_string_list (client,
&incoming_list,
error) &&
*error == NULL);
/* Make sure the list and its contents are valid */
g_assert_cmpint (incoming_list->len, >, 0);
nested_list = (TTestStringList *)g_ptr_array_index (incoming_list, 0);
g_assert (nested_list != NULL);
g_assert_cmpint (nested_list->len, >=, 0);
/* Clean up and exit */
g_ptr_array_unref (incoming_list);
}
static void
test_container_service_typedefd_list_string_list (void)
{
execute_with_service_client
(test_container_service_typedefd_list_string_list_inner);
}
int
main(int argc, char *argv[])
{
pid_t pid;
int status;
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init ();
#endif
/* Fork to run our test suite in a child process */
pid = fork ();
g_assert_cmpint (pid, >=, 0);
if (pid == 0) { /* The child process */
/* Wait a moment for the server to finish starting */
sleep (1);
g_test_init (&argc, &argv, NULL);
g_test_add_func
("/testcontainertest/ContainerTest/Structs/ContainersWithDefaultValues",
test_containers_with_default_values);
g_test_add_func
("/testcontainertest/ContainerTest/Services/ContainerService/StringList",
test_container_service_string_list);
g_test_add_func
("/testcontainertest/ContainerTest/Services/ContainerService/ListStringList",
test_container_service_list_string_list);
g_test_add_func
("/testcontainertest/ContainerTest/Services/ContainerService/TypedefdListStringList",
test_container_service_typedefd_list_string_list);
/* Run the tests and make the result available to our parent process */
_exit (g_test_run ());
}
else {
TTestContainerServiceHandler *handler;
TTestContainerServiceProcessor *processor;
ThriftServerTransport *server_transport;
ThriftTransportFactory *transport_factory;
ThriftProtocolFactory *protocol_factory;
struct sigaction sigchld_action;
GError *error = NULL;
int exit_status = 1;
/* Trap the event of the child process terminating so we know to stop the
server and exit */
memset (&sigchld_action, 0, sizeof (sigchld_action));
sigchld_action.sa_handler = sigchld_handler;
sigchld_action.sa_flags = SA_RESETHAND;
sigaction (SIGCHLD, &sigchld_action, NULL);
/* Create our test server */
handler = g_object_new (TYPE_TEST_CONTAINER_SERVICE_HANDLER,
NULL);
processor = g_object_new (T_TEST_TYPE_CONTAINER_SERVICE_PROCESSOR,
"handler", handler,
NULL);
server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", TEST_SERVER_PORT,
NULL);
transport_factory = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY,
NULL);
protocol_factory = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY,
NULL);
server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
"processor", processor,
"server_transport", server_transport,
"input_transport_factory", transport_factory,
"output_transport_factory", transport_factory,
"input_protocol_factory", protocol_factory,
"output_protocol_factory", protocol_factory,
NULL);
/* Start the server */
thrift_server_serve (server, &error);
/* Make sure the server stopped only because it was interrupted (by the
child process terminating) */
g_assert(!error || g_error_matches(error,
THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_ACCEPT));
/* Free our resources */
g_object_unref (server);
g_object_unref (transport_factory);
g_object_unref (protocol_factory);
g_object_unref (server_transport);
g_object_unref (processor);
g_object_unref (handler);
/* Wait for the child process to complete and return its exit status */
g_assert (wait (&status) == pid);
if (WIFEXITED (status))
exit_status = WEXITSTATUS (status);
return exit_status;
}
}

View file

@ -0,0 +1,942 @@
/*
* 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 <assert.h>
#include <math.h>
#include <string.h>
#include <glib-object.h>
#ifndef M_PI
#define M_PI 3.1415926535897932385
#endif
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include "gen-c_glib/t_test_debug_proto_test_types.h"
#include "gen-c_glib/t_test_srv.h"
#include "gen-c_glib/t_test_inherited.h"
static void
test_structs_doubles_create_and_destroy (void)
{
GObject *object = NULL;
/* A Doubles structure can be created... */
object = g_object_new (T_TEST_TYPE_DOUBLES, NULL);
g_assert (object != NULL);
g_assert (T_TEST_IS_DOUBLES (object));
/* ...and destroyed */
g_object_unref (object);
}
static void
test_structs_doubles_initialize (void)
{
TTestDoubles *doubles = NULL;
gdouble nan;
gdouble inf;
gdouble neginf;
gdouble repeating;
gdouble big;
gdouble tiny;
gdouble zero;
gdouble negzero;
/* Note there seems to be no way to get not-a-number ("NAN") values past
GObject's range-checking, so that portion of the test has been commented
out below. */
/* A Doubles structure's members are available as GObject properties
that can be initialized at construction... */
doubles = g_object_new (T_TEST_TYPE_DOUBLES,
/* "nan", 0 * INFINITY, */
"inf", INFINITY,
"neginf", -INFINITY,
"repeating", 1.0 / 3,
"big", G_MAXDOUBLE,
"tiny", 10E-101,
"zero", 1.0 * 0,
"negzero", -1.0 * 0,
NULL);
g_assert (doubles != NULL);
/* ...and later retrieved */
g_object_get (doubles,
"nan", &nan,
"inf", &inf,
"neginf", &neginf,
"repeating", &repeating,
"big", &big,
"tiny", &tiny,
"zero", &zero,
"negzero", &negzero,
NULL);
/* g_assert_cmpint (isnan (nan), !=, 0); */
g_assert_cmpint (isinf (inf), ==, 1);
g_assert_cmpint (isinf (neginf), ==, -1);
g_assert_cmpfloat (repeating, ==, 1.0 / 3);
g_assert_cmpfloat (big, ==, G_MAXDOUBLE);
g_assert_cmpfloat (tiny, ==, 10E-101);
g_assert_cmpfloat (zero, ==, 1.0 * 0);
g_assert_cmpfloat (negzero, ==, -1.0 * 0);
g_object_unref (doubles);
}
static void
test_structs_one_of_each_create_and_destroy (void)
{
GObject *object = NULL;
/* A OneOfEach structure can be created... */
object = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL);
g_assert (object != NULL);
g_assert (T_TEST_IS_ONE_OF_EACH (object));
/* ...and destroyed */
g_object_unref (object);
}
static void
test_structs_one_of_each_initialize_default_values (void)
{
TTestOneOfEach *one_of_each = NULL;
gint a_bite;
gint integer16;
gint64 integer64;
GArray *byte_list;
GArray *i16_list;
GArray *i64_list;
/* A OneOfEach structure created with no explicit property values
will hold the default values specified in the .thrift file */
one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL);
g_object_get (one_of_each,
"a_bite", &a_bite,
"integer16", &integer16,
"integer64", &integer64,
"byte_list", &byte_list,
"i16_list", &i16_list,
"i64_list", &i64_list,
NULL);
g_assert_cmpint (a_bite, ==, 0x7f);
g_assert_cmpint (integer16, ==, 0x7fff);
g_assert_cmpint (integer64, ==, G_GINT64_CONSTANT (10000000000));
g_assert (byte_list != NULL);
g_assert_cmpint (byte_list->len, ==, 3);
g_assert_cmpint (g_array_index (byte_list, gint8, 0), ==, 1);
g_assert_cmpint (g_array_index (byte_list, gint8, 1), ==, 2);
g_assert_cmpint (g_array_index (byte_list, gint8, 2), ==, 3);
g_assert (i16_list != NULL);
g_assert_cmpint (i16_list->len, ==, 3);
g_assert_cmpint (g_array_index (i16_list, gint16, 0), ==, 1);
g_assert_cmpint (g_array_index (i16_list, gint16, 1), ==, 2);
g_assert_cmpint (g_array_index (i16_list, gint16, 2), ==, 3);
g_assert (i64_list != NULL);
g_assert_cmpint (i64_list->len, ==, 3);
g_assert_cmpint (g_array_index (i64_list, gint64, 0), ==, 1);
g_assert_cmpint (g_array_index (i64_list, gint64, 1), ==, 2);
g_assert_cmpint (g_array_index (i64_list, gint64, 2), ==, 3);
g_array_unref (i64_list);
g_array_unref (i16_list);
g_array_unref (byte_list);
g_object_unref (one_of_each);
}
static void
test_structs_one_of_each_initialize_specified_values (void)
{
static const gint8 initial_byte_list[5] = { 13, 21, 34, 55, 89 };
static const gint16 initial_i16_list[5] = { 4181, 6765, 10946, 17711, 28657 };
static const gint64 initial_i64_list[5] =
{
G_GINT64_CONSTANT (1100087778366101931),
G_GINT64_CONSTANT (1779979416004714189),
G_GINT64_CONSTANT (2880067194370816120),
G_GINT64_CONSTANT (4660046610375530309),
G_GINT64_CONSTANT (7540113804746346429)
};
static const guint8 initial_base64[8] =
{
0x56, 0x47, 0x68, 0x79, 0x61, 0x57, 0x5a, 0x30
};
TTestOneOfEach *one_of_each;
gboolean im_true;
gboolean im_false;
gint a_bite;
gint integer16;
gint integer32;
gint64 integer64;
double double_precision;
gchar *some_characters;
gchar *zomg_unicode;
gboolean what_who;
GByteArray *base64;
GArray *byte_list;
GArray *i16_list;
GArray *i64_list;
base64 = g_byte_array_new ();
g_byte_array_append (base64, initial_base64, 8);
byte_list = g_array_new (FALSE, FALSE, sizeof (gint8));
g_array_append_vals (byte_list, initial_byte_list, 5);
i16_list = g_array_new (FALSE, FALSE, sizeof (gint16));
g_array_append_vals (i16_list, initial_i16_list, 5);
i64_list = g_array_new (FALSE, FALSE, sizeof (gint64));
g_array_append_vals (i64_list, initial_i64_list, 5);
/* All of OneOfEach's properties can be set at construction... */
one_of_each =
g_object_new (T_TEST_TYPE_ONE_OF_EACH,
"im_true", TRUE,
"im_false", FALSE,
"a_bite", 0x50,
"integer16", 0x7e57,
"integer32", 0xdeadbeef,
"integer64", G_GINT64_CONSTANT (0xfa15efacade15bad),
"double_precision", M_PI,
"some_characters", "Debug THIS!",
"zomg_unicode", "\xd7\n\a\t",
"what_who", TRUE,
"base64", base64,
"byte_list", byte_list,
"i16_list", i16_list,
"i64_list", i64_list,
NULL);
g_assert (one_of_each != NULL);
g_array_unref (i64_list);
i64_list = NULL;
g_array_unref (i16_list);
i16_list = NULL;
g_array_unref (byte_list);
byte_list = NULL;
g_byte_array_unref (base64);
base64 = NULL;
/* ...and later retrieved */
g_object_get (one_of_each,
"im_true", &im_true,
"im_false", &im_false,
"a_bite", &a_bite,
"integer16", &integer16,
"integer32", &integer32,
"integer64", &integer64,
"double_precision", &double_precision,
"some_characters", &some_characters,
"zomg_unicode", &zomg_unicode,
"what_who", &what_who,
"base64", &base64,
"byte_list", &byte_list,
"i16_list", &i16_list,
"i64_list", &i64_list,
NULL);
g_assert (im_true == TRUE);
g_assert (im_false == FALSE);
g_assert_cmphex (a_bite, ==, 0x50);
g_assert_cmphex (integer16, ==, 0x7e57);
g_assert_cmphex (integer32, ==, (gint32)0xdeadbeef);
g_assert_cmphex (integer64, ==, G_GINT64_CONSTANT (0xfa15efacade15bad));
g_assert_cmpfloat (double_precision, ==, M_PI);
g_assert_cmpstr (some_characters, ==, "Debug THIS!");
g_assert_cmpstr (zomg_unicode, ==, "\xd7\n\a\t");
g_assert (what_who == TRUE);
g_assert_cmpint (base64->len, ==, 8);
g_assert_cmpint (memcmp (base64->data,
initial_base64,
8 * sizeof (guint8)), ==, 0);
g_assert_cmpint (byte_list->len, ==, 5);
g_assert_cmpint (memcmp (byte_list->data,
initial_byte_list,
5 * sizeof (gint8)), ==, 0);
g_assert_cmpint (i16_list->len, ==, 5);
g_assert_cmpint (memcmp (i16_list->data,
initial_i16_list,
5 * sizeof (gint16)), ==, 0);
g_assert_cmpint (i64_list->len, ==, 5);
g_assert_cmpint (memcmp (i64_list->data,
initial_i64_list,
5 * sizeof (gint64)), ==, 0);
g_array_unref (i64_list);
g_array_unref (i16_list);
g_array_unref (byte_list);
g_byte_array_unref (base64);
g_object_unref (one_of_each);
}
static void
test_structs_one_of_each_properties_byte_list (void)
{
TTestOneOfEach *one_of_each;
GArray *byte_list = NULL;
one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL);
/* OneOfEach's "byte_list" member is a list that holds eight-bit-wide integer
values */
g_object_get (one_of_each, "byte_list", &byte_list, NULL);
g_assert (byte_list != NULL);
g_assert_cmpint (g_array_get_element_size (byte_list), ==, sizeof (gint8));
g_array_unref (byte_list);
g_object_unref (one_of_each);
}
static void
test_structs_one_of_each_properties_i16_list (void)
{
TTestOneOfEach *one_of_each;
GArray *i16_list = NULL;
one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL);
/* OneOfEach's "i16_list" member is a list that holds sixteen-bit-wide integer
values */
g_object_get (one_of_each, "i16_list", &i16_list, NULL);
g_assert (i16_list != NULL);
g_assert_cmpint (g_array_get_element_size (i16_list), ==, sizeof (gint16));
g_array_unref (i16_list);
g_object_unref (one_of_each);
}
static void
test_structs_one_of_each_properties_i64_list (void)
{
TTestOneOfEach *one_of_each;
GArray *i64_list = NULL;
one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL);
/* OneOfEach's "i64_list" member is a list that holds sixty-four-bit-wide
integer values */
g_object_get (one_of_each, "i64_list", &i64_list, NULL);
g_assert (i64_list != NULL);
g_assert_cmpint (g_array_get_element_size (i64_list), ==, sizeof (gint64));
g_array_unref (i64_list);
g_object_unref (one_of_each);
}
static void
test_structs_nesting_create_and_destroy (void)
{
GObject *object = NULL;
/* A Nesting structure can be created... */
object = g_object_new (T_TEST_TYPE_NESTING, NULL);
g_assert (object != NULL);
g_assert (T_TEST_IS_NESTING (object));
/* ...and destroyed */
g_object_unref (object);
}
static void
test_structs_nesting_properties_my_bonk (void)
{
TTestNesting *nesting;
TTestBonk *bonk = NULL;
gint type;
gchar *message;
nesting = g_object_new (T_TEST_TYPE_NESTING, NULL);
/* Nesting's "my_bonk" member is initialized with a new, default Bonk object
during construction */
g_object_get (nesting, "my_bonk", &bonk, NULL);
g_assert (bonk != NULL);
g_assert (T_TEST_IS_BONK (bonk));
g_object_get (bonk,
"type", &type,
"message", &message,
NULL);
g_assert_cmpint (type, ==, 0);
g_assert (message == NULL);
g_object_unref (bonk);
bonk = NULL;
/* It can be replaced... */
bonk = g_object_new (T_TEST_TYPE_BONK,
"type", 100,
"message", "Replacement Bonk",
NULL);
g_object_set (nesting, "my_bonk", bonk, NULL);
g_object_unref (bonk);
bonk = NULL;
g_object_get (nesting, "my_bonk", &bonk, NULL);
g_assert (bonk != NULL);
g_assert (T_TEST_IS_BONK (bonk));
g_object_get (bonk,
"type", &type,
"message", &message,
NULL);
g_assert_cmpint (type, ==, 100);
g_assert_cmpstr (message, ==, "Replacement Bonk");
g_free (message);
g_object_unref (bonk);
bonk = NULL;
/* ...or set to null */
g_object_set (nesting, "my_bonk", NULL, NULL);
g_object_get (nesting, "my_bonk", &bonk, NULL);
g_assert (bonk == NULL);
g_object_unref (nesting);
}
static void
test_structs_nesting_properties_my_ooe (void)
{
TTestNesting *nesting;
TTestOneOfEach *one_of_each = NULL;
gint a_bite;
gint integer16;
nesting = g_object_new (T_TEST_TYPE_NESTING, NULL);
/* Nesting's "my_ooe" member is initialized with a new, default OneOfEach
object during construction */
g_object_get (nesting, "my_ooe", &one_of_each, NULL);
g_assert (one_of_each != NULL);
g_assert (T_TEST_IS_ONE_OF_EACH (one_of_each));
g_object_get (one_of_each,
"a_bite", &a_bite,
"integer16", &integer16,
NULL);
g_assert_cmphex (a_bite, ==, 0x7f);
g_assert_cmphex (integer16, ==, 0x7fff);
g_object_unref (one_of_each);
one_of_each = NULL;
/* It can be replaced... */
one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH,
"a_bite", 0x50,
"integer16", 0x5050,
NULL);
g_object_set (nesting, "my_ooe", one_of_each, NULL);
g_object_unref (one_of_each);
one_of_each = NULL;
g_object_get (nesting, "my_ooe", &one_of_each, NULL);
g_assert (one_of_each != NULL);
g_assert (T_TEST_IS_ONE_OF_EACH (one_of_each));
g_object_get (one_of_each,
"a_bite", &a_bite,
"integer16", &integer16,
NULL);
g_assert_cmphex (a_bite, ==, 0x50);
g_assert_cmphex (integer16, ==, 0x5050);
g_object_unref (one_of_each);
one_of_each = NULL;
/* ...or set to null */
g_object_set (nesting, "my_ooe", NULL, NULL);
g_object_get (nesting, "my_ooe", &one_of_each, NULL);
g_assert (one_of_each == NULL);
g_object_unref (nesting);
}
static void
test_structs_holy_moley_create_and_destroy (void)
{
GObject *object = NULL;
/* A HolyMoley structure can be created... */
object = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL);
g_assert (object != NULL);
g_assert (T_TEST_IS_HOLY_MOLEY (object));
/* ...and destroyed */
g_object_unref (object);
}
static void
test_structs_holy_moley_properties_big (void)
{
TTestHolyMoley *holy_moley;
GPtrArray *big = NULL;
gint a_bite = 0;
gint integer16 = 0;
holy_moley = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL);
/* A HolyMoley's "big" member is is initialized on construction */
g_object_get (holy_moley, "big", &big, NULL);
g_assert (big != NULL);
g_assert_cmpint (big->len, ==, 0);
/* It can be modified... */
g_ptr_array_add (big,
g_object_new (T_TEST_TYPE_ONE_OF_EACH,
"a_bite", 0x50,
"integer16", 0x5050,
NULL));
g_ptr_array_unref (big);
big = NULL;
g_object_get (holy_moley, "big", &big, NULL);
g_assert_cmpint (big->len, ==, 1);
g_object_get (g_ptr_array_index (big, 0),
"a_bite", &a_bite,
"integer16", &integer16,
NULL);
g_assert_cmphex (a_bite, ==, 0x50);
g_assert_cmphex (integer16, ==, 0x5050);
g_ptr_array_unref (big);
big = NULL;
/* ...replaced... */
big = g_ptr_array_new_with_free_func (g_object_unref);
g_ptr_array_add (big,
g_object_new (T_TEST_TYPE_ONE_OF_EACH,
"a_bite", 0x64,
"integer16", 0x1541,
NULL));
g_object_set (holy_moley, "big", big, NULL);
g_ptr_array_unref (big);
big = NULL;
g_object_get (holy_moley, "big", &big, NULL);
g_assert_cmpint (big->len, ==, 1);
g_object_get (g_ptr_array_index (big, 0),
"a_bite", &a_bite,
"integer16", &integer16,
NULL);
g_assert_cmphex (a_bite, ==, 0x64);
g_assert_cmphex (integer16, ==, 0x1541);
g_ptr_array_unref (big);
big = NULL;
/* ...or set to NULL */
g_object_set (holy_moley, "big", NULL, NULL);
g_object_get (holy_moley, "big", &big, NULL);
g_assert (big == NULL);
g_object_unref (holy_moley);
}
static void
test_structs_holy_moley_properties_contain (void)
{
static gchar *strings[2] = { "Apache", "Thrift" };
TTestHolyMoley *holy_moley;
GHashTable *contain = NULL;
GPtrArray *string_list;
GList *key_list;
holy_moley = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL);
/* A HolyMoley's "contain" member is initialized on construction */
g_object_get (holy_moley, "contain", &contain, NULL);
g_assert (contain != NULL);
g_assert_cmpint (g_hash_table_size (contain), ==, 0);
/* It can be modified... */
string_list = g_ptr_array_new ();
g_ptr_array_add (string_list, strings[0]);
g_ptr_array_add (string_list, strings[1]);
g_hash_table_insert (contain, string_list, NULL);
string_list = NULL;
g_hash_table_unref (contain);
contain = NULL;
g_object_get (holy_moley, "contain", &contain, NULL);
g_assert_cmpint (g_hash_table_size (contain), ==, 1);
key_list = g_hash_table_get_keys (contain);
string_list = g_list_nth_data (key_list, 0);
g_assert_cmpint (string_list->len, ==, 2);
g_assert_cmpstr (g_ptr_array_index (string_list, 0), ==, "Apache");
g_assert_cmpstr (g_ptr_array_index (string_list, 1), ==, "Thrift");
g_list_free (key_list);
g_hash_table_unref (contain);
contain = NULL;
/* ...replaced... */
contain = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
(GDestroyNotify) g_ptr_array_unref,
NULL);
g_object_set (holy_moley, "contain", contain, NULL);
g_hash_table_unref (contain);
contain = NULL;
g_object_get (holy_moley, "contain", &contain, NULL);
g_assert_cmpint (g_hash_table_size (contain), ==, 0);
g_hash_table_unref (contain);
contain = NULL;
/* ...or set to NULL */
g_object_set (holy_moley, "contain", NULL, NULL);
g_object_get (holy_moley, "contain", &contain, NULL);
g_assert (contain == NULL);
g_object_unref (holy_moley);
}
static void
test_structs_holy_moley_properties_bonks (void)
{
TTestHolyMoley *holy_moley;
GHashTable *bonks = NULL;
GPtrArray *bonk_list = NULL;
TTestBonk *bonk = NULL;
gint type;
gchar *message;
GList *key_list;
holy_moley = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL);
/* A HolyMoley's "bonks" member is initialized on construction */
g_object_get (holy_moley, "bonks", &bonks, NULL);
g_assert (bonks != NULL);
g_assert_cmpint (g_hash_table_size (bonks), ==, 0);
/* It can be modified... */
bonk = g_object_new (T_TEST_TYPE_BONK,
"type", 100,
"message", "Sample Bonk",
NULL);
bonk_list = g_ptr_array_new_with_free_func (g_object_unref);
g_ptr_array_add (bonk_list, bonk);
bonk = NULL;
g_hash_table_insert (bonks, g_strdup ("Sample Bonks"), bonk_list);
bonk_list = NULL;
g_hash_table_unref (bonks);
bonks = NULL;
g_object_get (holy_moley, "bonks", &bonks, NULL);
g_assert_cmpint (g_hash_table_size (bonks), ==, 1);
key_list = g_hash_table_get_keys (bonks);
bonk_list = g_hash_table_lookup (bonks, g_list_nth_data (key_list, 0));
g_assert_cmpint (bonk_list->len, ==, 1);
bonk = (g_ptr_array_index (bonk_list, 0));
g_object_get (bonk,
"type", &type,
"message", &message,
NULL);
g_assert_cmpint (type, ==, 100);
g_assert_cmpstr (message, ==, "Sample Bonk");
bonk = NULL;
g_free (message);
g_list_free (key_list);
g_hash_table_unref (bonks);
bonks = NULL;
/* ...replaced... */
bonks = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) g_ptr_array_unref);
g_object_set (holy_moley, "bonks", bonks, NULL);
g_hash_table_unref (bonks);
bonks = NULL;
g_object_get (holy_moley, "bonks", &bonks, NULL);
g_assert_cmpint (g_hash_table_size (bonks), ==, 0);
g_hash_table_unref (bonks);
bonks = NULL;
/* ...or set to NULL */
g_object_set (holy_moley, "bonks", NULL, NULL);
g_object_get (holy_moley, "bonks", &bonks, NULL);
g_assert (bonks == NULL);
g_object_unref (holy_moley);
}
static void
test_structs_empty (void)
{
GObject *object = NULL;
GParamSpec **properties;
guint property_count;
/* An Empty structure can be created */
object = g_object_new (T_TEST_TYPE_EMPTY, NULL);
g_assert (object != NULL);
g_assert (T_TEST_IS_EMPTY (object));
/* An Empty structure has no members and thus no properties */
properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (object),
&property_count);
g_assert_cmpint (property_count, ==, 0);
g_free (properties);
/* An Empty structure can be destroyed */
g_object_unref (object);
}
static void
test_structs_wrapper_create_and_destroy (void)
{
GObject *object = NULL;
/* A Wrapper structure can be created... */
object = g_object_new (T_TEST_TYPE_EMPTY, NULL);
g_assert (object != NULL);
g_assert (T_TEST_IS_EMPTY (object));
/* ...and destroyed */
g_object_unref (object);
}
static void
test_structs_wrapper_properties_foo (void) {
TTestWrapper *wrapper;
TTestEmpty *foo;
wrapper = g_object_new (T_TEST_TYPE_WRAPPER, NULL);
/* A Wrapper structure has one member, "foo", which is an Empty
structure initialized during construction */
g_object_get (wrapper, "foo", &foo, NULL);
g_assert (foo != NULL);
g_assert (T_TEST_IS_EMPTY (foo));
g_object_unref (foo);
foo = NULL;
/* A Wrapper's foo property can be replaced... */
foo = g_object_new (T_TEST_TYPE_EMPTY, NULL);
g_object_set (wrapper, "foo", foo, NULL);
g_object_unref (foo);
foo = NULL;
g_object_get (wrapper, "foo", &foo, NULL);
g_assert (foo != NULL);
g_assert (T_TEST_IS_EMPTY (foo));
g_object_unref (foo);
foo = NULL;
/* ...or set to NULL */
g_object_set (wrapper, "foo", NULL, NULL);
g_object_get (wrapper, "foo", &foo, NULL);
g_assert (foo == NULL);
g_object_unref (wrapper);
}
static void
test_services_inherited (void)
{
ThriftProtocol *protocol;
TTestInheritedClient *inherited_client;
GObject *input_protocol, *output_protocol;
protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, NULL);
inherited_client = g_object_new (T_TEST_TYPE_INHERITED_CLIENT,
NULL);
/* TTestInheritedClient inherits from TTestSrvClient */
assert (g_type_is_a (T_TEST_TYPE_INHERITED_CLIENT,
T_TEST_TYPE_SRV_CLIENT));
/* TTestInheritedClient implements TTestSrvClient's interface */
assert (g_type_is_a (T_TEST_TYPE_INHERITED_CLIENT,
T_TEST_TYPE_SRV_IF));
/* TTestInheritedClient's inherited properties can be set and retrieved */
g_object_set (inherited_client,
"input_protocol", protocol,
"output_protocol", protocol,
NULL);
g_object_get (inherited_client,
"input_protocol", &input_protocol,
"output_protocol", &output_protocol,
NULL);
assert (input_protocol == G_OBJECT(protocol));
assert (output_protocol == G_OBJECT(protocol));
g_object_unref (output_protocol);
g_object_unref (input_protocol);
g_object_unref (inherited_client);
g_object_unref (protocol);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init ();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Doubles/CreateAndDestroy",
test_structs_doubles_create_and_destroy);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Doubles/Initialize",
test_structs_doubles_initialize);
g_test_add_func
("/testdebugproto/DebugProto/Structs/OneOfEach/CreateAndDestroy",
test_structs_one_of_each_create_and_destroy);
g_test_add_func
("/testdebugproto/DebugProto/Structs/OneOfEach/Initialize/DefaultValues",
test_structs_one_of_each_initialize_default_values);
g_test_add_func
("/testdebugproto/DebugProto/Structs/OneOfEach/Initialize/SpecifiedValues",
test_structs_one_of_each_initialize_specified_values);
g_test_add_func
("/testdebugproto/DebugProto/Structs/OneOfEach/Properties/byte_list",
test_structs_one_of_each_properties_byte_list);
g_test_add_func
("/testdebugproto/DebugProto/Structs/OneOfEach/Properties/i16_list",
test_structs_one_of_each_properties_i16_list);
g_test_add_func
("/testdebugproto/DebugProto/Structs/OneOfEach/Properties/i64_list",
test_structs_one_of_each_properties_i64_list);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Nesting/CreateAndDestroy",
test_structs_nesting_create_and_destroy);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Nesting/Properties/my_bonk",
test_structs_nesting_properties_my_bonk);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Nesting/Properties/my_ooe",
test_structs_nesting_properties_my_ooe);
g_test_add_func
("/testdebugproto/DebugProto/Structs/HolyMoley/CreateAndDestroy",
test_structs_holy_moley_create_and_destroy);
g_test_add_func
("/testdebugproto/DebugProto/Structs/HolyMoley/Properties/big",
test_structs_holy_moley_properties_big);
g_test_add_func
("/testdebugproto/DebugProto/Structs/HolyMoley/Properties/contain",
test_structs_holy_moley_properties_contain);
g_test_add_func
("/testdebugproto/DebugProto/Structs/HolyMoley/Properties/bonks",
test_structs_holy_moley_properties_bonks);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Empty",
test_structs_empty);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Wrapper/CreateAndDestroy",
test_structs_wrapper_create_and_destroy);
g_test_add_func
("/testdebugproto/DebugProto/Structs/Wrapper/Properties/foo",
test_structs_wrapper_properties_foo);
g_test_add_func
("/testdebugproto/DebugProto/Services/Inherited",
test_services_inherited);
return g_test_run ();
}

View file

@ -0,0 +1,185 @@
/*
* 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 <assert.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_fd_transport.h>
static const gchar TEST_DATA[12] = "abcde01234!";
static void
test_create_and_destroy (void)
{
GObject *object;
object = g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", -1, NULL);
assert (object != NULL);
g_object_unref (object);
}
static void
test_open_and_close (void)
{
ThriftTransport *transport;
ThriftTransportClass *klass;
GError *error;
gint fd;
gchar *filename;
error = NULL;
filename = NULL;
fd = g_file_open_tmp (NULL, &filename, &error);
assert (fd >= 0);
transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
"fd", fd,
NULL));
klass = THRIFT_TRANSPORT_GET_CLASS (transport);
/* open is no-op */
assert (klass->is_open (transport));
assert (klass->peek (transport, &error));
assert (klass->open (transport, &error));
assert (klass->is_open (transport));
assert (klass->peek (transport, &error));
assert (klass->close (transport, &error));
assert (! klass->open (transport, &error));
assert (! klass->is_open (transport));
assert (! klass->peek (transport, &error));
/* already closed */
assert (close (fd) != 0);
assert (errno == EBADF);
g_object_unref (transport);
g_remove (filename);
g_free (filename);
/* test bad fd */
transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
"fd", -1,
NULL));
klass = THRIFT_TRANSPORT_GET_CLASS (transport);
assert (! klass->is_open (transport));
error = NULL;
assert (! klass->peek (transport, &error));
error = NULL;
assert (! klass->open (transport, &error));
error = NULL;
assert (! klass->close (transport, &error));
g_object_unref (transport);
}
static void
test_read_and_write (void)
{
gchar out_buf[8];
gchar *b;
gint want, got;
ThriftTransport *transport;
ThriftTransportClass *klass;
GError *error;
gint fd;
gchar *filename;
error = NULL;
filename = NULL;
fd = g_file_open_tmp (NULL, &filename, &error);
assert (fd >= 0);
/* write */
transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
"fd", fd,
NULL));
klass = THRIFT_TRANSPORT_GET_CLASS (transport);
assert (klass->is_open (transport));
assert (klass->write (transport, (gpointer) TEST_DATA, 11, &error));
assert (klass->flush (transport, &error));
assert (klass->close (transport, &error));
g_object_unref (transport);
/* read */
fd = open(filename, O_RDONLY, S_IRUSR | S_IWUSR);
assert (fd >= 0);
transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
"fd", fd,
NULL));
klass = THRIFT_TRANSPORT_GET_CLASS (transport);
memset(out_buf, 0, 8);
b = out_buf;
want = 7;
while (want > 0) {
got = klass->read (transport, (gpointer) b, want, &error);
assert (got > 0 && got <= want);
b += got;
want -= got;
}
assert (memcmp (out_buf, TEST_DATA, 7) == 0);
memset(out_buf, 0, 8);
b = out_buf;
want = 4;
while (want > 0) {
got = klass->read (transport, (gpointer) b, want, &error);
assert (got > 0 && got <= want);
b += got;
want -= got;
}
assert (memcmp (out_buf, TEST_DATA + 7, 4) == 0);
assert (klass->close (transport, &error));
g_object_unref (transport);
/* clean up */
g_remove (filename);
g_free (filename);
}
int
main (int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init ();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testfdtransport/CreateAndDestroy", test_create_and_destroy);
g_test_add_func ("/testfdtransport/OpenAndClose", test_open_and_close);
g_test_add_func ("/testfdtransport/ReadAndWrite", test_read_and_write);
return g_test_run ();
}

View file

@ -0,0 +1,284 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <sys/wait.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
#include "../src/thrift/c_glib/transport/thrift_framed_transport.c"
static void thrift_server (const int port);
/* test object creation and destruction */
static void
test_create_and_destroy(void)
{
ThriftTransport *transport = NULL;
guint r_buf_size = 0;
guint w_buf_size = 0;
GObject *object = NULL;
object = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, NULL);
assert (object != NULL);
g_object_get (G_OBJECT (object), "transport", &transport,
"r_buf_size", &r_buf_size,
"w_buf_size", &w_buf_size, NULL);
g_object_unref (object);
}
static void
test_open_and_close(void)
{
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
GError *err = NULL;
/* create a ThriftSocket */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", 51188, NULL);
/* create a BufferedTransport wrapper of the Socket */
transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket), NULL);
/* this shouldn't work */
assert (thrift_framed_transport_open (transport, NULL) == FALSE);
assert (thrift_framed_transport_is_open (transport) == TRUE);
assert (thrift_framed_transport_close (transport, NULL) == TRUE);
g_object_unref (transport);
g_object_unref (tsocket);
/* try and underlying socket failure */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
NULL);
/* create a BufferedTransport wrapper of the Socket */
transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket), NULL);
assert (thrift_framed_transport_open (transport, &err) == FALSE);
g_object_unref (transport);
g_object_unref (tsocket);
g_error_free (err);
err = NULL;
}
static void
test_read_and_write(void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
int port = 51199;
guchar buf[10] = TEST_DATA; /* a buffer */
pid = fork ();
assert ( pid >= 0 );
if ( pid == 0 )
{
/* child listens */
thrift_server (port);
exit (0);
} else {
/* parent connects, wait a bit for the socket to be created */
sleep (1);
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket),
"w_buf_size", 4, NULL);
assert (thrift_framed_transport_open (transport, NULL) == TRUE);
assert (thrift_framed_transport_is_open (transport));
/* write 10 bytes */
thrift_framed_transport_write (transport, buf, 10, NULL);
thrift_framed_transport_flush (transport, NULL);
thrift_framed_transport_write (transport, buf, 1, NULL);
thrift_framed_transport_flush (transport, NULL);
thrift_framed_transport_write (transport, buf, 10, NULL);
thrift_framed_transport_flush (transport, NULL);
thrift_framed_transport_write (transport, buf, 10, NULL);
thrift_framed_transport_flush (transport, NULL);
thrift_framed_transport_write_end (transport, NULL);
thrift_framed_transport_flush (transport, NULL);
thrift_framed_transport_close (transport, NULL);
g_object_unref (transport);
g_object_unref (tsocket);
assert ( wait (&status) == pid );
assert ( status == 0 );
}
}
/* test reading from the transport after the peer has unexpectedly
closed the connection */
static void
test_read_after_peer_close(void)
{
int status;
pid_t pid;
int port = 51199;
GError *err = NULL;
pid = fork ();
g_assert (pid >= 0);
if (pid == 0)
{
ThriftServerTransport *server_transport = NULL;
ThriftTransport *client_transport = NULL;
/* child listens */
server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port,
NULL);
g_assert (server_transport != NULL);
thrift_server_transport_listen (server_transport, &err);
g_assert (err == NULL);
/* wrap the client transport in a ThriftFramedTransport */
client_transport = g_object_new
(THRIFT_TYPE_FRAMED_TRANSPORT,
"transport", thrift_server_transport_accept (server_transport, &err),
"r_buf_size", 0,
NULL);
g_assert (err == NULL);
g_assert (client_transport != NULL);
/* close the connection immediately after the client connects */
thrift_transport_close (client_transport, NULL);
g_object_unref (client_transport);
g_object_unref (server_transport);
exit (0);
} else {
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
guchar buf[10]; /* a buffer */
/* parent connects, wait a bit for the socket to be created */
sleep (1);
tsocket = g_object_new (THRIFT_TYPE_SOCKET,
"hostname", "localhost",
"port", port,
NULL);
transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
"transport", THRIFT_TRANSPORT (tsocket),
"w_buf_size", 0,
NULL);
g_assert (thrift_transport_open (transport, NULL) == TRUE);
g_assert (thrift_transport_is_open (transport));
/* attempting to read from the transport after the peer has closed
the connection fails gracefully without generating a critical
warning or segmentation fault */
thrift_transport_read (transport, buf, 10, &err);
g_assert (err != NULL);
g_error_free (err);
err = NULL;
thrift_transport_read_end (transport, &err);
g_assert (err == NULL);
thrift_transport_close (transport, &err);
g_assert (err == NULL);
g_object_unref (transport);
g_object_unref (tsocket);
g_assert (wait (&status) == pid);
g_assert (status == 0);
}
}
static void
thrift_server (const int port)
{
int bytes = 0;
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
guchar buf[12]; /* a buffer */
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
/* wrap the client in a BufferedTransport */
client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
thrift_server_transport_accept (transport, NULL),
"r_buf_size", 5, NULL);
assert (client != NULL);
/* read 10 bytes */
bytes = thrift_framed_transport_read (client, buf, 10, NULL);
assert (bytes == 10); /* make sure we've read 10 bytes */
assert ( memcmp (buf, match, 10) == 0 ); /* make sure what we got matches */
bytes = thrift_framed_transport_read (client, buf, 6, NULL);
bytes = thrift_framed_transport_read (client, buf, 5, NULL);
bytes = thrift_framed_transport_read (client, buf, 1, NULL);
bytes = thrift_framed_transport_read (client, buf, 12, NULL);
thrift_framed_transport_read_end (client, NULL);
thrift_framed_transport_close (client, NULL);
g_object_unref (client);
g_object_unref (tsocket);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testframedtransport/CreateAndDestroy", test_create_and_destroy);
g_test_add_func ("/testframedtransport/OpenAndClose", test_open_and_close);
g_test_add_func ("/testframedtransport/ReadAndWrite", test_read_and_write);
g_test_add_func ("/testframedtransport/ReadAfterPeerClose", test_read_after_peer_close);
return g_test_run ();
}

View file

@ -0,0 +1,224 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
static const gchar TEST_DATA[11] = "abcdefghij";
#include "../src/thrift/c_glib/transport/thrift_memory_buffer.c"
/* test object creation and destruction */
static void
test_create_and_destroy (void)
{
GObject *object = NULL;
object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER,
"buf_size", 10,
NULL);
assert (object != NULL);
g_object_unref (object);
}
static void
test_create_and_destroy_large (void)
{
GObject *object = NULL;
object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER,
"buf_size", 10 * 1024 * 1024,
NULL);
assert (object != NULL);
g_object_unref (object);
}
static void
test_create_and_destroy_default (void)
{
GObject *object = NULL;
object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL);
assert (object != NULL);
g_object_unref (object);
}
static void
test_create_and_destroy_external (void)
{
GObject *object = NULL;
GByteArray *buf = g_byte_array_new ();
assert (buf != NULL);
object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER,
"buf", buf,
NULL);
assert (object != NULL);
g_object_unref (object);
}
static void
test_create_and_destroy_unowned (void)
{
GObject *object = NULL;
GValue val = G_VALUE_INIT;
GByteArray *buf;
object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER,
"owner", FALSE,
NULL);
assert (object != NULL);
g_value_init (&val, G_TYPE_POINTER);
g_object_get_property (object, "buf", &val);
buf = (GByteArray*) g_value_get_pointer (&val);
assert (buf != NULL);
g_byte_array_unref (buf);
g_value_unset (&val);
g_object_unref (object);
}
static void
test_open_and_close (void)
{
ThriftMemoryBuffer *tbuffer = NULL;
/* create a ThriftMemoryBuffer */
tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL);
/* no-ops */
assert (thrift_memory_buffer_open (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE);
assert (thrift_memory_buffer_is_open (THRIFT_TRANSPORT (tbuffer)) == TRUE);
assert (thrift_memory_buffer_close (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE);
g_object_unref (tbuffer);
}
static void
test_read_and_write (void)
{
ThriftMemoryBuffer *tbuffer = NULL;
gint got, want;
gchar read[10];
gchar *b;
GError *error = NULL;
tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 5, NULL);
assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
(gpointer) TEST_DATA,
10, &error) == FALSE);
assert (error != NULL);
g_error_free (error);
error = NULL;
g_object_unref (tbuffer);
tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 15, NULL);
assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
(gpointer) TEST_DATA, 10, &error) == TRUE);
assert (error == NULL);
memset(read, 0, 10);
b = read;
want = 10;
while (want > 0) {
got = thrift_memory_buffer_read (THRIFT_TRANSPORT (tbuffer),
(gpointer) b, want, &error);
assert (got > 0 && got <= want);
assert (error == NULL);
b += got;
want -= got;
}
assert (memcmp (read, TEST_DATA, 10) == 0);
g_object_unref (tbuffer);
}
static void
test_read_and_write_default (void)
{
ThriftMemoryBuffer *tbuffer = NULL;
gint got, want, i;
gchar read[10];
gchar *b;
GError *error = NULL;
tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL);
for (i = 0; i < 100; ++i) {
assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
(gpointer) TEST_DATA, 10, &error) == TRUE);
assert (error == NULL);
}
for (i = 0; i < 100; ++i) {
memset(read, 0, 10);
b = read;
want = 10;
while (want > 0) {
got = thrift_memory_buffer_read (THRIFT_TRANSPORT (tbuffer),
(gpointer) b, want, &error);
assert (got > 0 && got <= want);
assert (error == NULL);
b += got;
want -= got;
}
assert (memcmp (read, TEST_DATA, 10) == 0);
}
g_object_unref (tbuffer);
}
static void
test_read_and_write_external (void)
{
ThriftMemoryBuffer *tbuffer = NULL;
gchar *b;
GError *error = NULL;
GByteArray *buf = g_byte_array_new ();
assert (buf != NULL);
tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf", buf, NULL);
assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
(gpointer) TEST_DATA, 10, &error) == TRUE);
assert (error == NULL);
assert (memcmp (buf->data, TEST_DATA, 10) == 0);
g_object_unref (tbuffer);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init ();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testmemorybuffer/CreateAndDestroy", test_create_and_destroy);
g_test_add_func ("/testmemorybuffer/CreateAndDestroyLarge", test_create_and_destroy_large);
g_test_add_func ("/testmemorybuffer/CreateAndDestroyUnlimited", test_create_and_destroy_default);
g_test_add_func ("/testmemorybuffer/CreateAndDestroyExternal", test_create_and_destroy_external);
g_test_add_func ("/testmemorybuffer/CreateAndDestroyUnowned", test_create_and_destroy_unowned);
g_test_add_func ("/testmemorybuffer/OpenAndClose", test_open_and_close);
g_test_add_func ("/testmemorybuffer/ReadAndWrite", test_read_and_write);
g_test_add_func ("/testmemorybuffer/ReadAndWriteUnlimited", test_read_and_write_default);
g_test_add_func ("/testmemorybuffer/ReadAndWriteExternal", test_read_and_write_external);
return g_test_run ();
}

View file

@ -0,0 +1,228 @@
/*
* 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 <assert.h>
#include <glib.h>
#include <thrift/c_glib/thrift_struct.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include <thrift/c_glib/transport/thrift_memory_buffer.h>
#include "gen-c_glib/t_test_optional_required_test_types.h"
#include "gen-c_glib/t_test_optional_required_test_types.c"
static void
write_to_read (ThriftStruct *w, ThriftStruct *r, GError **write_error,
GError **read_error)
{
ThriftMemoryBuffer *tbuffer = NULL;
ThriftProtocol *protocol = NULL;
tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL);
protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
tbuffer, NULL);
thrift_struct_write (w, protocol, write_error);
thrift_struct_read (r, protocol, read_error);
g_object_unref (protocol);
g_object_unref (tbuffer);
}
static void
test_old_school1 (void)
{
TTestOldSchool *o = NULL;
o = g_object_new (T_TEST_TYPE_OLD_SCHOOL, NULL);
o->im_int = 10;
o->im_str = g_strdup ("test");
o->im_big = g_ptr_array_new ();
g_ptr_array_free (o->im_big, TRUE);
o->im_big = NULL;
g_free (o->im_str);
o->im_str = NULL;
g_object_unref (o);
}
/**
* Write to read with optional fields
*/
static void
test_simple (void)
{
TTestSimple *s1 = NULL, *s2 = NULL, *s3 = NULL;
s1 = g_object_new (T_TEST_TYPE_SIMPLE, NULL);
s2 = g_object_new (T_TEST_TYPE_SIMPLE, NULL);
s3 = g_object_new (T_TEST_TYPE_SIMPLE, NULL);
/* write-to-read with optional fields */
s1->im_optional = 10;
assert (s1->__isset_im_default == FALSE);
assert (s1->__isset_im_optional == FALSE);
write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s2), NULL, NULL);
assert (s2->__isset_im_default == TRUE);
assert (s2->__isset_im_optional == FALSE);
assert (s2->im_optional == 0);
s1->__isset_im_optional = TRUE;
write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s3), NULL, NULL);
assert (s3->__isset_im_default == TRUE);
assert (s3->__isset_im_optional == TRUE);
assert (s3->im_optional == 10);
g_object_unref (s1);
g_object_unref (s2);
}
/**
* Writing between optional and default
*/
static void
test_tricky1 (void)
{
TTestTricky1 *t1 = NULL;
TTestTricky2 *t2 = NULL;
t1 = g_object_new (T_TEST_TYPE_TRICKY1, NULL);
t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL);
t2->im_optional = 10;
write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t1), NULL, NULL);
write_to_read (THRIFT_STRUCT (t1), THRIFT_STRUCT (t2), NULL, NULL);
assert (t1->__isset_im_default == FALSE);
assert (t2->__isset_im_optional == TRUE);
assert (t1->im_default == t2->im_optional);
assert (t1->im_default == 0);
g_object_unref (t1);
g_object_unref (t2);
}
/**
* Writing between default and required.
*/
static void
test_tricky2 (void)
{
TTestTricky1 *t1 = NULL;
TTestTricky3 *t3 = NULL;
t1 = g_object_new (T_TEST_TYPE_TRICKY1, NULL);
t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL);
write_to_read (THRIFT_STRUCT (t1), THRIFT_STRUCT (t3), NULL, NULL);
write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t1), NULL, NULL);
assert (t1->__isset_im_default == TRUE);
g_object_unref (t1);
g_object_unref (t3);
}
/**
* Writing between optional and required.
*/
static void
test_tricky3 (void)
{
TTestTricky2 *t2 = NULL;
TTestTricky3 *t3 = NULL;
t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL);
t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL);
t2->__isset_im_optional = TRUE;
write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t3), NULL, NULL);
write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL);
g_object_unref (t2);
g_object_unref (t3);
}
/**
* Catch an optional not set exception. To quote the
* C++ test, "Mu-hu-ha-ha-ha!"
*/
static void
test_tricky4 (void)
{
TTestTricky2 *t2 = NULL;
TTestTricky3 *t3 = NULL;
GError *read_error = NULL;
t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL);
t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL);
/* throws protocol exception */
write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t3), NULL, &read_error);
assert (read_error != NULL);
g_error_free (read_error);
write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL);
assert (t2->__isset_im_optional);
g_object_unref (t2);
g_object_unref (t3);
}
static void
test_non_set_binary (void)
{
TTestBinaries *b1 = NULL;
TTestBinaries *b2 = NULL;
GError *error = NULL;
b1 = g_object_new (T_TEST_TYPE_BINARIES, NULL);
b2 = g_object_new (T_TEST_TYPE_BINARIES, NULL);
write_to_read (THRIFT_STRUCT (b1), THRIFT_STRUCT (b2), NULL, &error);
g_assert(!error);
write_to_read (THRIFT_STRUCT (b2), THRIFT_STRUCT (b1), NULL, &error);
g_assert(!error);
/* OK. No segfault */
g_object_unref (b1);
g_object_unref (b2);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testoptionalrequired/OldSchool", test_old_school1);
g_test_add_func ("/testoptionalrequired/Simple", test_simple);
g_test_add_func ("/testoptionalrequired/Tricky1", test_tricky1);
g_test_add_func ("/testoptionalrequired/Tricky2", test_tricky2);
g_test_add_func ("/testoptionalrequired/Tricky3", test_tricky3);
g_test_add_func ("/testoptionalrequired/Tricky4", test_tricky4);
g_test_add_func ("/testoptionalrequired/Binary", test_non_set_binary);
return g_test_run ();
}

View file

@ -0,0 +1,95 @@
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_memory_buffer.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include "gen-c_glib/t_test_debug_proto_test_types.h"
#include "gen-c_glib/t_test_enum_test_types.h"
static void enum_constants_read_write() {
GError* error = NULL;
ThriftTransport* transport
= THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 1024, NULL));
ThriftProtocol* protocol
= THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));
TTestEnumTestStruct* src = T_TEST_ENUM_TEST;
TTestEnumTestStruct* dst = g_object_new(T_TEST_TYPE_ENUM_TEST_STRUCT, NULL);
TTestEnumTestStructClass* cls = T_TEST_ENUM_TEST_STRUCT_GET_CLASS(src);
int write_len;
int read_len;
write_len = THRIFT_STRUCT_CLASS(cls)->write(THRIFT_STRUCT(src), protocol, &error);
g_assert(!error);
g_assert(write_len > 0);
read_len = THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(dst), protocol, &error);
g_assert(!error);
g_assert_cmpint(write_len, ==, read_len);
g_object_unref(dst);
g_object_unref(protocol);
g_object_unref(transport);
}
static void struct_constants_read_write() {
GError* error = NULL;
ThriftTransport* transport
= THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 4096, NULL));
ThriftProtocol* protocol
= THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));
TTestCompactProtoTestStruct* src = T_TEST_COMPACT_TEST;
TTestCompactProtoTestStruct* dst = g_object_new(T_TEST_TYPE_COMPACT_PROTO_TEST_STRUCT, NULL);
TTestCompactProtoTestStructClass* cls = T_TEST_COMPACT_PROTO_TEST_STRUCT_GET_CLASS(src);
int write_len;
int read_len;
write_len = THRIFT_STRUCT_CLASS(cls)->write(THRIFT_STRUCT(src), protocol, &error);
g_assert(!error);
g_assert(write_len > 0);
read_len = THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(dst), protocol, &error);
g_assert(!error);
g_assert_cmpint(write_len, ==, read_len);
g_object_unref(dst);
g_object_unref(protocol);
g_object_unref(transport);
}
static void struct_read_write_length_should_equal() {
GError* error = NULL;
ThriftTransport* transport
= THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 2048, NULL));
ThriftProtocol* protocol
= THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));
TTestBonk* src = g_object_new(T_TEST_TYPE_BONK, NULL);
TTestBonk* dst = g_object_new(T_TEST_TYPE_BONK, NULL);
TTestBonkClass* cls = T_TEST_BONK_GET_CLASS(src);
int write_len;
int read_len;
write_len = THRIFT_STRUCT_CLASS(cls)->write(THRIFT_STRUCT(src), protocol, &error);
g_assert(!error);
g_assert(write_len > 0);
read_len = THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(dst), protocol, &error);
g_assert(!error);
g_assert_cmpint(write_len, ==, read_len);
g_object_unref(dst);
g_object_unref(src);
g_object_unref(protocol);
g_object_unref(transport);
}
int main(int argc, char* argv[]) {
#if (!GLIB_CHECK_VERSION(2, 36, 0))
g_type_init();
#endif
g_test_init(&argc, &argv, NULL);
g_test_add_func("/testserialization/StructReadWriteLengthShouldEqual",
struct_read_write_length_should_equal);
g_test_add_func("/testserialization/StructConstants", struct_constants_read_write);
g_test_add_func("/testserialization/EnumConstants", enum_constants_read_write);
return g_test_run();
}

View file

@ -0,0 +1,123 @@
/*
* 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 <assert.h>
#include <glib.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/processor/thrift_processor.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#define TEST_PORT 51199
#include <thrift/c_glib/server/thrift_simple_server.c>
/* create a rudimentary processor */
#define TEST_PROCESSOR_TYPE (test_processor_get_type ())
struct _TestProcessor
{
ThriftProcessor parent;
};
typedef struct _TestProcessor TestProcessor;
struct _TestProcessorClass
{
ThriftProcessorClass parent;
};
typedef struct _TestProcessorClass TestProcessorClass;
G_DEFINE_TYPE(TestProcessor, test_processor, THRIFT_TYPE_PROCESSOR)
gboolean
test_processor_process (ThriftProcessor *processor, ThriftProtocol *in,
ThriftProtocol *out, GError **error)
{
THRIFT_UNUSED_VAR (processor);
THRIFT_UNUSED_VAR (in);
THRIFT_UNUSED_VAR (out);
THRIFT_UNUSED_VAR (error);
return FALSE;
}
static void
test_processor_init (TestProcessor *p)
{
THRIFT_UNUSED_VAR (p);
}
static void
test_processor_class_init (TestProcessorClass *proc)
{
(THRIFT_PROCESSOR_CLASS(proc))->process = test_processor_process;
}
static void
test_server (void)
{
int status;
pid_t pid;
TestProcessor *p = NULL;
ThriftServerSocket *tss = NULL;
ThriftSimpleServer *ss = NULL;
p = g_object_new (TEST_PROCESSOR_TYPE, NULL);
tss = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", TEST_PORT, NULL);
ss = g_object_new (THRIFT_TYPE_SIMPLE_SERVER, "processor", p,
"server_transport", THRIFT_SERVER_TRANSPORT (tss), NULL);
/* run the server in a child process */
pid = fork ();
assert (pid >= 0);
if (pid == 0)
{
THRIFT_SERVER_GET_CLASS (THRIFT_SERVER (ss))->serve (THRIFT_SERVER (ss),
NULL);
exit (0);
} else {
sleep (5);
kill (pid, SIGINT);
g_object_unref (ss);
g_object_unref (tss);
g_object_unref (p);
assert (wait (&status) == pid);
assert (status == SIGINT);
}
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testsimpleserver/SimpleServer", test_server);
return g_test_run ();
}

112
vendor/git.apache.org/thrift.git/lib/c_glib/test/teststruct.c generated vendored Executable file
View file

@ -0,0 +1,112 @@
/*
* 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 <assert.h>
#include <glib-object.h>
#include "../src/thrift/c_glib/thrift_struct.c"
/* tests to ensure we can extend a ThriftStruct */
struct _ThriftTestStruct
{
ThriftStruct parent;
};
typedef struct _ThriftTestStruct ThriftTestStruct;
struct _ThriftTestStructClass
{
ThriftStructClass parent;
};
typedef struct _ThriftTestStructClass ThriftTestStructClass;
GType thrift_test_struct_get_type (void);
#define THRIFT_TYPE_TEST_STRUCT (thrift_test_struct_get_type ())
#define THRIFT_TEST_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_TEST_STRUCT, ThriftTestStruct))
#define THRIFT_TEST_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_TEST_STRUCT, ThriftTestStructClass))
#define THRIFT_IS_TEST_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_TEST_STRUCT))
#define THRIFT_IS_TEST_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_TEST_STRUCT))
#define THRIFT_TEST_STRUCT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_TEST_STRUCT, ThriftTestStructClass))
G_DEFINE_TYPE(ThriftTestStruct, thrift_test_struct, THRIFT_TYPE_STRUCT)
gint32
thrift_test_struct_read (ThriftStruct *object, ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (object);
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
gint32
thrift_test_struct_write (ThriftStruct *object, ThriftProtocol *protocol,
GError **error)
{
THRIFT_UNUSED_VAR (object);
THRIFT_UNUSED_VAR (protocol);
THRIFT_UNUSED_VAR (error);
return 0;
}
static void
thrift_test_struct_class_init (ThriftTestStructClass *cls)
{
ThriftStructClass *ts_cls = THRIFT_STRUCT_CLASS (cls);
ts_cls->read = thrift_test_struct_read;
ts_cls->write = thrift_test_struct_write;
}
static void
thrift_test_struct_init (ThriftTestStruct *s)
{
THRIFT_UNUSED_VAR (s);
}
static void
test_initialize_object (void)
{
ThriftTestStruct *t = NULL;
t = g_object_new (THRIFT_TYPE_TEST_STRUCT, NULL);
assert ( THRIFT_IS_STRUCT (t));
thrift_struct_read (THRIFT_STRUCT (t), NULL, NULL);
thrift_struct_write (THRIFT_STRUCT (t), NULL, NULL);
thrift_test_struct_read (THRIFT_STRUCT (t), NULL, NULL);
thrift_test_struct_write (THRIFT_STRUCT (t), NULL, NULL);
g_object_unref (t);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/teststruct/InitializeObject", test_initialize_object);
return g_test_run ();
}

View file

@ -0,0 +1,113 @@
#include <assert.h>
#include <netdb.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#include "t_test_thrift_test_types.h"
#include "thrift_test_handler.h"
static const char TEST_ADDRESS[] = "localhost";
static const int TEST_PORT = 64444;
static void
test_thrift_server (void)
{
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", TEST_PORT, NULL);
g_object_unref (tsocket);
}
static void
set_indicator (gpointer data, GObject *where_the_object_was) {
THRIFT_UNUSED_VAR(where_the_object_was);
*(gboolean *) data = TRUE;
}
static void
test_thrift_handler (void)
{
GError *error;
GHashTable *_return;
TTestInsanity *argument;
gboolean indicator;
TTestXtruct *xtruct, *xtruct2;
TTestNumberz numberz;
TTestNumberz numberz2;
TTestUserId user_id, *user_id_ptr, *user_id_ptr2;
GHashTable *user_map;
GPtrArray *xtructs;
error = NULL;
indicator = FALSE;
user_map = NULL;
xtructs = NULL;
argument = g_object_new (T_TEST_TYPE_INSANITY, NULL);
g_object_get (argument,
"userMap", &user_map,
"xtructs", &xtructs,
NULL);
numberz = T_TEST_NUMBERZ_FIVE;
numberz2 = T_TEST_NUMBERZ_EIGHT;
user_id_ptr = g_malloc (sizeof *user_id_ptr);
*user_id_ptr = 5;
user_id_ptr2 = g_malloc (sizeof *user_id_ptr);
*user_id_ptr2 = 8;
g_hash_table_insert (user_map, (gpointer)numberz, user_id_ptr);
g_hash_table_insert (user_map, (gpointer)numberz2, user_id_ptr2);
g_hash_table_unref (user_map);
xtruct = g_object_new (T_TEST_TYPE_XTRUCT,
"string_thing", "Hello2",
"byte_thing", 2,
"i32_thing", 2,
"i64_thing", 2LL,
NULL);
xtruct2 = g_object_new (T_TEST_TYPE_XTRUCT,
"string_thing", "Goodbye4",
"byte_thing", 4,
"i32_thing", 4,
"i64_thing", 4LL,
NULL);
g_ptr_array_add (xtructs, xtruct2);
g_ptr_array_add (xtructs, xtruct);
g_ptr_array_unref (xtructs);
_return = g_hash_table_new_full (g_int64_hash,
g_int64_equal,
g_free,
(GDestroyNotify)g_hash_table_unref);
g_object_weak_ref (G_OBJECT (argument), set_indicator, (gpointer) &indicator);
assert (thrift_test_handler_test_insanity (NULL, &_return, argument, &error));
assert (! indicator);
g_hash_table_unref (_return);
assert (! indicator);
g_object_unref (argument);
assert (indicator);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testthrift/Server", test_thrift_server);
g_test_add_func ("/testthrift/Handler", test_thrift_handler);
return g_test_run ();
}

View file

@ -0,0 +1,628 @@
/*
* 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.
*/
/* test a C client with a C++ server */
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TDebugProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include "ThriftTest.h"
#include "ThriftTest_types.h"
#include <iostream>
using namespace std;
using namespace boost;
using namespace apache::thrift;
using namespace apache::thrift::concurrency;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace thrift::test;
#define TEST_PORT 9980
// Extra functions required for ThriftTest_types to work
namespace thrift { namespace test {
bool Insanity::operator<(thrift::test::Insanity const& other) const {
using apache::thrift::ThriftDebugString;
return ThriftDebugString(*this) < ThriftDebugString(other);
}
}}
class TestHandler : public ThriftTestIf {
public:
TestHandler() {}
void testVoid() {
cout << "[C -> C++] testVoid()" << endl;
}
void testString(string& out, const string &thing) {
cout << "[C -> C++] testString(\"" << thing << "\")" << endl;
out = thing;
}
bool testBool(const bool thing) {
cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl;
return thing;
}
int8_t testByte(const int8_t thing) {
cout << "[C -> C++] testByte(" << (int)thing << ")" << endl;
return thing;
}
int32_t testI32(const int32_t thing) {
cout << "[C -> C++] testI32(" << thing << ")" << endl;
return thing;
}
int64_t testI64(const int64_t thing) {
cout << "[C -> C++] testI64(" << thing << ")" << endl;
return thing;
}
double testDouble(const double thing) {
cout.precision(6);
cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl;
return thing;
}
void testBinary(string& out, const string &thing) {
cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl;
out = thing;
}
void testStruct(Xtruct& out, const Xtruct &thing) {
cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << endl;
out = thing;
}
void testNest(Xtruct2& out, const Xtruct2& nest) {
const Xtruct &thing = nest.struct_thing;
cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << endl;
out = nest;
}
void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) {
cout << "[C -> C++] testMap({";
map<int32_t, int32_t>::const_iterator m_iter;
bool first = true;
for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
if (first) {
first = false;
} else {
cout << ", ";
}
cout << m_iter->first << " => " << m_iter->second;
}
cout << "})" << endl;
out = thing;
}
void testStringMap(map<std::string, std::string> &out, const map<std::string, std::string> &thing) {
cout << "[C -> C++] testStringMap({";
map<std::string, std::string>::const_iterator m_iter;
bool first = true;
for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
if (first) {
first = false;
} else {
cout << ", ";
}
cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\"";
}
cout << "})" << endl;
out = thing;
}
void testSet(set<int32_t> &out, const set<int32_t> &thing) {
cout << "[C -> C++] testSet({";
set<int32_t>::const_iterator s_iter;
bool first = true;
for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
if (first) {
first = false;
} else {
cout << ", ";
}
cout << *s_iter;
}
cout << "})" << endl;
out = thing;
}
void testList(vector<int32_t> &out, const vector<int32_t> &thing) {
cout << "[C -> C++] testList({";
vector<int32_t>::const_iterator l_iter;
bool first = true;
for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
if (first) {
first = false;
} else {
cout << ", ";
}
cout << *l_iter;
}
cout << "})" << endl;
out = thing;
}
Numberz::type testEnum(const Numberz::type thing) {
cout << "[C -> C++] testEnum(" << thing << ")" << endl;
return thing;
}
UserId testTypedef(const UserId thing) {
cout << "[C -> C++] testTypedef(" << thing << ")" << endl;
return thing; }
void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) {
cout << "[C -> C++] testMapMap(" << hello << ")" << endl;
map<int32_t,int32_t> pos;
map<int32_t,int32_t> neg;
for (int i = 1; i < 5; i++) {
pos.insert(make_pair(i,i));
neg.insert(make_pair(-i,-i));
}
mapmap.insert(make_pair(4, pos));
mapmap.insert(make_pair(-4, neg));
}
void testInsanity(map<UserId, map<Numberz::type,Insanity> > &insane, const Insanity &argument) {
THRIFT_UNUSED_VARIABLE (argument);
cout << "[C -> C++] testInsanity()" << endl;
Xtruct hello;
hello.string_thing = "Hello2";
hello.byte_thing = 2;
hello.i32_thing = 2;
hello.i64_thing = 2;
Xtruct goodbye;
goodbye.string_thing = "Goodbye4";
goodbye.byte_thing = 4;
goodbye.i32_thing = 4;
goodbye.i64_thing = 4;
Insanity crazy;
crazy.userMap.insert(make_pair(Numberz::EIGHT, 8));
crazy.xtructs.push_back(goodbye);
Insanity looney;
crazy.userMap.insert(make_pair(Numberz::FIVE, 5));
crazy.xtructs.push_back(hello);
map<Numberz::type, Insanity> first_map;
map<Numberz::type, Insanity> second_map;
first_map.insert(make_pair(Numberz::TWO, crazy));
first_map.insert(make_pair(Numberz::THREE, crazy));
second_map.insert(make_pair(Numberz::SIX, looney));
insane.insert(make_pair(1, first_map));
insane.insert(make_pair(2, second_map));
cout << "return = {";
map<UserId, map<Numberz::type,Insanity> >::const_iterator i_iter;
for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
cout << i_iter->first << " => {";
map<Numberz::type,Insanity>::const_iterator i2_iter;
for (i2_iter = i_iter->second.begin();
i2_iter != i_iter->second.end();
++i2_iter) {
cout << i2_iter->first << " => {";
map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
map<Numberz::type, UserId>::const_iterator um;
cout << "{";
for (um = userMap.begin(); um != userMap.end(); ++um) {
cout << um->first << " => " << um->second << ", ";
}
cout << "}, ";
vector<Xtruct> xtructs = i2_iter->second.xtructs;
vector<Xtruct>::const_iterator x;
cout << "{";
for (x = xtructs.begin(); x != xtructs.end(); ++x) {
cout << "{\"" << x->string_thing << "\", " << (int)x->byte_thing << ", " << x->i32_thing << ", " << x->i64_thing << "}, ";
}
cout << "}";
cout << "}, ";
}
cout << "}, ";
}
cout << "}" << endl;
}
void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string> &arg3, const Numberz::type arg4, const UserId arg5) {
THRIFT_UNUSED_VARIABLE (arg3);
THRIFT_UNUSED_VARIABLE (arg4);
THRIFT_UNUSED_VARIABLE (arg5);
cout << "[C -> C++] testMulti()" << endl;
hello.string_thing = "Hello2";
hello.byte_thing = arg0;
hello.i32_thing = arg1;
hello.i64_thing = (int64_t)arg2;
}
void testException(const std::string &arg)
throw(Xception, apache::thrift::TException)
{
cout << "[C -> C++] testException(" << arg << ")" << endl;
if (arg.compare("Xception") == 0) {
Xception e;
e.errorCode = 1001;
e.message = arg;
throw e;
} else if (arg.compare("ApplicationException") == 0) {
apache::thrift::TException e;
throw e;
} else {
Xtruct result;
result.string_thing = arg;
return;
}
}
void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) {
cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl;
if (arg0.compare("Xception") == 0) {
Xception e;
e.errorCode = 1001;
e.message = "This is an Xception";
throw e;
} else if (arg0.compare("Xception2") == 0) {
Xception2 e;
e.errorCode = 2002;
e.struct_thing.string_thing = "This is an Xception2";
throw e;
} else {
result.string_thing = arg1;
return;
}
}
void testOneway(int sleepFor) {
cout << "testOneway(" << sleepFor << "): Sleeping..." << endl;
sleep(sleepFor);
cout << "testOneway(" << sleepFor << "): done sleeping!" << endl;
}
};
// C CLIENT
extern "C" {
#undef THRIFT_SOCKET /* from lib/cpp */
#include "t_test_thrift_test.h"
#include "t_test_thrift_test_types.h"
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
static void
test_thrift_client (void)
{
ThriftSocket *tsocket = NULL;
ThriftBinaryProtocol *protocol = NULL;
TTestThriftTestClient *client = NULL;
TTestThriftTestIf *iface = NULL;
GError *error = NULL;
gchar *string = NULL;
gint8 byte = 0;
gint16 i16 = 0;
gint32 i32 = 0, another_i32 = 56789;
gint64 i64 = 0;
double dbl = 0.0;
TTestXtruct *xtruct_in, *xtruct_out;
TTestXtruct2 *xtruct2_in, *xtruct2_out;
GHashTable *map_in = NULL, *map_out = NULL;
GHashTable *set_in = NULL, *set_out = NULL;
GArray *list_in = NULL, *list_out = NULL;
TTestNumberz enum_in, enum_out;
TTestUserId user_id_in, user_id_out;
GHashTable *insanity_in = NULL;
TTestXtruct *xtruct1, *xtruct2;
TTestInsanity *insanity_out = NULL;
TTestXtruct *multi_in = NULL;
GHashTable *multi_map_out = NULL;
TTestXception *xception = NULL;
TTestXception2 *xception2 = NULL;
#if (!GLIB_CHECK_VERSION (2, 36, 0))
// initialize gobject
g_type_init ();
#endif
// create a C client
tsocket = (ThriftSocket *) g_object_new (THRIFT_TYPE_SOCKET,
"hostname", "localhost",
"port", TEST_PORT, NULL);
protocol = (ThriftBinaryProtocol *) g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
"transport",
tsocket, NULL);
client = (TTestThriftTestClient *) g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT, "input_protocol", protocol, "output_protocol", protocol, NULL);
iface = T_TEST_THRIFT_TEST_IF (client);
// open and send
thrift_transport_open (THRIFT_TRANSPORT(tsocket), NULL);
assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE);
assert (error == NULL);
assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE);
assert (strcmp (string, "test123") == 0);
g_free (string);
assert (error == NULL);
assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE);
assert (byte == 5);
assert (error == NULL);
assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE);
assert (i32 == 123);
assert (error == NULL);
assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE);
assert (i64 == 12345);
assert (error == NULL);
assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE);
assert (dbl == 5.6);
assert (error == NULL);
xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
xtruct_out->byte_thing = 1;
xtruct_out->__isset_byte_thing = TRUE;
xtruct_out->i32_thing = 15;
xtruct_out->__isset_i32_thing = TRUE;
xtruct_out->i64_thing = 151;
xtruct_out->__isset_i64_thing = TRUE;
xtruct_out->string_thing = g_strdup ("abc123");
xtruct_out->__isset_string_thing = TRUE;
xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, NULL);
assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE);
assert (error == NULL);
xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
xtruct2_out->byte_thing = 1;
xtruct2_out->__isset_byte_thing = TRUE;
if (xtruct2_out->struct_thing != NULL)
g_object_unref(xtruct2_out->struct_thing);
xtruct2_out->struct_thing = xtruct_out;
xtruct2_out->__isset_struct_thing = TRUE;
xtruct2_out->i32_thing = 123;
xtruct2_out->__isset_i32_thing = TRUE;
xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE);
assert (error == NULL);
g_object_unref (xtruct2_out);
g_object_unref (xtruct2_in);
g_object_unref (xtruct_in);
map_out = g_hash_table_new (NULL, NULL);
map_in = g_hash_table_new (NULL, NULL); g_hash_table_insert (map_out, &i32, &i32);
assert (t_test_thrift_test_client_test_map (iface, &map_in, map_out, &error) == TRUE);
assert (error == NULL);
g_hash_table_destroy (map_out);
g_hash_table_destroy (map_in);
map_out = g_hash_table_new (NULL, NULL);
map_in = g_hash_table_new (NULL, NULL);
g_hash_table_insert (map_out, g_strdup ("a"), g_strdup ("123"));
g_hash_table_insert (map_out, g_strdup ("a b"), g_strdup ("with spaces "));
g_hash_table_insert (map_out, g_strdup ("same"), g_strdup ("same"));
g_hash_table_insert (map_out, g_strdup ("0"), g_strdup ("numeric key"));
assert (t_test_thrift_test_client_test_string_map (iface, &map_in, map_out, &error) == TRUE);
assert (error == NULL);
g_hash_table_destroy (map_out);
g_hash_table_destroy (map_in);
set_out = g_hash_table_new (NULL, NULL);
set_in = g_hash_table_new (NULL, NULL);
g_hash_table_insert (set_out, &i32, &i32);
assert (t_test_thrift_test_client_test_set (iface, &set_in, set_out, &error) == TRUE);
assert (error == NULL);
g_hash_table_destroy (set_out);
g_hash_table_destroy (set_in);
list_out = g_array_new(TRUE, TRUE, sizeof(gint32));
list_in = g_array_new(TRUE, TRUE, sizeof(gint32));
another_i32 = 456;
g_array_append_val (list_out, i32);
g_array_append_val (list_out, another_i32);
assert (t_test_thrift_test_client_test_list (iface, &list_in, list_out, &error) == TRUE);
assert (error == NULL);
g_array_free (list_out, TRUE);
g_array_free (list_in, TRUE);
enum_out = T_TEST_NUMBERZ_ONE;
assert (t_test_thrift_test_client_test_enum (iface, &enum_in, enum_out, &error) == TRUE);
assert (enum_in == enum_out);
assert (error == NULL);
user_id_out = 12345;
assert (t_test_thrift_test_client_test_typedef (iface, &user_id_in, user_id_out, &error) == TRUE);
assert (user_id_in == user_id_out);
assert (error == NULL);
map_in = g_hash_table_new (NULL, NULL);
assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE);
assert (error == NULL);
g_hash_table_destroy (map_in);
// insanity
insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, NULL);
insanity_out->userMap = g_hash_table_new (NULL, NULL);
g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out);
xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
xtruct1->byte_thing = 1;
xtruct1->__isset_byte_thing = TRUE;
xtruct1->i32_thing = 15;
xtruct1->__isset_i32_thing = TRUE;
xtruct1->i64_thing = 151;
xtruct1->__isset_i64_thing = TRUE;
xtruct1->string_thing = g_strdup ("abc123");
xtruct1->__isset_string_thing = TRUE;
xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
xtruct2->byte_thing = 1;
xtruct2->__isset_byte_thing = TRUE;
xtruct2->i32_thing = 15;
xtruct2->__isset_i32_thing = TRUE;
xtruct2->i64_thing = 151;
xtruct2->__isset_i64_thing = TRUE;
xtruct2->string_thing = g_strdup ("abc123");
xtruct2->__isset_string_thing = TRUE;
insanity_in = g_hash_table_new (NULL, NULL);
g_ptr_array_add (insanity_out->xtructs, xtruct1);
g_ptr_array_add (insanity_out->xtructs, xtruct2);
assert (t_test_thrift_test_client_test_insanity (iface, &insanity_in, insanity_out, &error) == TRUE);
g_hash_table_unref (insanity_in);
g_ptr_array_free (insanity_out->xtructs, TRUE);
multi_map_out = g_hash_table_new (NULL, NULL);
string = g_strdup ("abc123");
g_hash_table_insert (multi_map_out, &i16, string);
multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE);
assert (multi_in->i32_thing == i32);
assert (multi_in->i64_thing == i64);
g_object_unref (multi_in);
g_hash_table_unref (multi_map_out);
g_free (string);
assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE);
assert (xception->errorCode == 1001);
g_error_free (error);
error = NULL;
g_object_unref (xception);
xception = NULL;
assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE);
g_error_free (error);
error = NULL;
assert (xception == NULL);
assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE);
assert (error == NULL);
multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", NULL, &xception, &xception2, &error) == FALSE);
assert (xception->errorCode == 1001);
assert (xception2 == NULL);
g_error_free (error);
error = NULL;
g_object_unref (xception);
g_object_unref (multi_in);
xception = NULL;
multi_in = NULL;
multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", NULL, &xception, &xception2, &error) == FALSE);
assert (xception2->errorCode == 2002);
assert (xception == NULL);
g_error_free (error);
error = NULL;
g_object_unref (xception2);
g_object_unref (multi_in);
xception2 = NULL;
multi_in = NULL;
multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, NULL , NULL, &xception, &xception2, &error) == TRUE);
assert (error == NULL);
g_object_unref(multi_in);
multi_in = NULL;
assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE);
assert (error == NULL);
/* sleep to let the oneway call go through */
sleep (5);
thrift_transport_close (THRIFT_TRANSPORT(tsocket), NULL);
g_object_unref (client);
g_object_unref (protocol);
g_object_unref (tsocket);
}
} /* extern "C" */
static void
bailout (int signum)
{
THRIFT_UNUSED_VARIABLE (signum);
exit (1);
}
int
main (void)
{
int status;
int pid = fork ();
assert (pid >= 0);
if (pid == 0) /* child */
{
boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
boost::shared_ptr<TestHandler> testHandler(new TestHandler());
boost::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
boost::shared_ptr<TServerSocket> serverSocket(new TServerSocket(TEST_PORT));
boost::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
TSimpleServer simpleServer(testProcessor, serverSocket, transportFactory, protocolFactory);
signal (SIGALRM, bailout);
alarm (60);
simpleServer.serve();
} else {
sleep (1);
test_thrift_client ();
kill (pid, SIGINT);
assert (wait (&status) == pid);
}
return 0;
}

View file

@ -0,0 +1,323 @@
/*
* 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 <assert.h>
#include <netdb.h>
#include <sys/wait.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
/* substituted functions to test failures of system and library calls */
static int socket_error = 0;
int
my_socket(int domain, int type, int protocol)
{
if (socket_error == 0)
{
return socket (domain, type, protocol);
}
return -1;
}
static int recv_error = 0;
ssize_t
my_recv(int socket, void *buffer, size_t length, int flags)
{
if (recv_error == 0)
{
return recv (socket, buffer, length, flags);
}
return -1;
}
static int send_error = 0;
ssize_t
my_send(int socket, const void *buffer, size_t length, int flags)
{
if (send_error == 0)
{
return send (socket, buffer, length, flags);
}
return -1;
}
#define socket my_socket
#define recv my_recv
#define send my_send
#include "../src/thrift/c_glib/transport/thrift_socket.c"
#undef socket
#undef recv
#undef send
static void thrift_socket_server (const int port);
/* test object creation and destruction */
static void
test_create_and_destroy(void)
{
gchar *hostname = NULL;
guint port = 0;
GObject *object = NULL;
object = g_object_new (THRIFT_TYPE_SOCKET, NULL);
assert (object != NULL);
g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL);
g_free (hostname);
g_object_unref (object);
}
static void
test_open_and_close(void)
{
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
GError *err = NULL;
/* open a connection and close it */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", 51188, NULL);
transport = THRIFT_TRANSPORT (tsocket);
thrift_socket_open (transport, NULL);
assert (thrift_socket_is_open (transport) == TRUE);
thrift_socket_close (transport, NULL);
assert (thrift_socket_is_open (transport) == FALSE);
/* test close failure */
tsocket->sd = -1;
thrift_socket_close (transport, NULL);
g_object_unref (tsocket);
/* try a hostname lookup failure */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
NULL);
transport = THRIFT_TRANSPORT (tsocket);
assert (thrift_socket_open (transport, &err) == FALSE);
g_object_unref (tsocket);
g_error_free (err);
err = NULL;
/* try an error call to socket() */
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", NULL);
transport = THRIFT_TRANSPORT (tsocket);
socket_error = 1;
assert (thrift_socket_open (transport, &err) == FALSE);
socket_error = 0;
g_object_unref (tsocket);
g_error_free (err);
}
static void
test_read_and_write(void)
{
int status;
pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
int port = 51199;
guchar buf[10] = TEST_DATA; /* a buffer */
pid = fork ();
assert ( pid >= 0 );
if ( pid == 0 )
{
/* child listens */
thrift_socket_server (port);
exit (0);
} else {
/* parent connects, wait a bit for the socket to be created */
sleep (1);
tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
"port", port, NULL);
transport = THRIFT_TRANSPORT (tsocket);
assert (thrift_socket_open (transport, NULL) == TRUE);
assert (thrift_socket_is_open (transport));
thrift_socket_write (transport, buf, 10, NULL);
/* write fail */
send_error = 1;
thrift_socket_write (transport, buf, 1, NULL);
send_error = 0;
thrift_socket_write_end (transport, NULL);
thrift_socket_flush (transport, NULL);
thrift_socket_close (transport, NULL);
g_object_unref (tsocket);
assert ( wait (&status) == pid );
assert ( status == 0 );
}
}
/* test ThriftSocket's peek() implementation */
static void
test_peek(void)
{
gint status;
pid_t pid;
guint port = 51199;
gchar data = 'A';
ThriftTransport *client_transport;
GError *error = NULL;
client_transport = g_object_new (THRIFT_TYPE_SOCKET,
"hostname", "localhost",
"port", port,
NULL);
/* thrift_transport_peek returns FALSE when the socket is closed */
g_assert (thrift_transport_is_open (client_transport) == FALSE);
g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
g_assert (error == NULL);
pid = fork ();
g_assert (pid >= 0);
if (pid == 0)
{
ThriftServerTransport *server_transport = NULL;
g_object_unref (client_transport);
/* child listens */
server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port,
NULL);
g_assert (server_transport != NULL);
thrift_server_transport_listen (server_transport, &error);
g_assert (error == NULL);
client_transport = g_object_new
(THRIFT_TYPE_BUFFERED_TRANSPORT,
"transport", thrift_server_transport_accept (server_transport, &error),
"r_buf_size", 0,
"w_buf_size", sizeof data,
NULL);
g_assert (error == NULL);
g_assert (client_transport != NULL);
/* write exactly one character to the client */
g_assert (thrift_transport_write (client_transport,
&data,
sizeof data,
&error) == TRUE);
thrift_transport_flush (client_transport, &error);
thrift_transport_write_end (client_transport, &error);
thrift_transport_close (client_transport, &error);
g_object_unref (client_transport);
g_object_unref (server_transport);
exit (0);
}
else {
/* parent connects, wait a bit for the socket to be created */
sleep (1);
/* connect to the child */
thrift_transport_open (client_transport, &error);
g_assert (error == NULL);
g_assert (thrift_transport_is_open (client_transport) == TRUE);
/* thrift_transport_peek returns TRUE when the socket is open and there is
data available to be read */
g_assert (thrift_transport_peek (client_transport, &error) == TRUE);
g_assert (error == NULL);
/* read exactly one character from the server */
g_assert_cmpint (thrift_transport_read (client_transport,
&data,
sizeof data,
&error), ==, sizeof data);
/* thrift_transport_peek returns FALSE when the socket is open but there is
no (more) data available to be read */
g_assert (thrift_transport_is_open (client_transport) == TRUE);
g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
g_assert (error == NULL);
thrift_transport_read_end (client_transport, &error);
thrift_transport_close (client_transport, &error);
g_object_unref (client_transport);
g_assert (wait (&status) == pid);
g_assert (status == 0);
}
}
static void
thrift_socket_server (const int port)
{
int bytes = 0;
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
guchar buf[10]; /* a buffer */
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
client = thrift_server_transport_accept (transport, NULL);
assert (client != NULL);
/* read 10 bytes */
bytes = thrift_socket_read (client, buf, 10, NULL);
assert (bytes == 10); /* make sure we've read 10 bytes */
assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */
/* failed read */
recv_error = 1;
thrift_socket_read (client, buf, 1, NULL);
recv_error = 0;
thrift_socket_read_end (client, NULL);
thrift_socket_close (client, NULL);
g_object_unref (tsocket);
g_object_unref (client);
}
int
main(int argc, char *argv[])
{
#if (!GLIB_CHECK_VERSION (2, 36, 0))
g_type_init();
#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/testtransportsocket/CreateAndDestroy", test_create_and_destroy);
g_test_add_func ("/testtransportsocket/OpenAndClose", test_open_and_close);
g_test_add_func ("/testtransportsocket/ReadAndWrite", test_read_and_write);
g_test_add_func ("/testtransportsocket/Peek", test_peek);
return g_test_run ();
}

View file

@ -0,0 +1,30 @@
#
# 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.
#
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Thrift
Description: Thrift C API
Version: @VERSION@
Requires: glib-2.0 gobject-2.0
Libs: -L${libdir} -lthrift_c_glib
Cflags: -I${includedir}