summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/lib/c_glib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/jaegertracing/thrift/lib/c_glib
parentInitial commit. (diff)
downloadceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz
ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/thrift/lib/c_glib')
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/CMakeLists.txt87
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/Makefile.am118
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/README.md49
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/coding_standards.md5
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.c143
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.h95
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c346
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h114
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.c45
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.h76
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c911
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h72
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c50
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h56
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c1609
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.h107
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c140
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h70
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c158
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h76
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c646
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.h341
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c623
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h72
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.c43
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.h73
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c192
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h78
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.c195
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.h93
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.c138
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.h70
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.c101
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.h49
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c277
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.h86
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.c52
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.h68
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c390
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h77
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.c55
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.h86
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.c265
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.h74
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c383
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h77
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.c55
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.h86
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c285
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h72
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h120
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c307
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h91
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.c62
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.h89
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c427
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h73
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c804
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h218
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c162
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h176
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.c44
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.h71
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/CMakeLists.txt202
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/ContainerTest.thrift35
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/Makefile.am324
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/glib.suppress64
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/testapplicationexception.c180
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testbinaryprotocol.c859
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testbufferedtransport.c325
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testcompactprotocol.c1293
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/testcontainertest.c529
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/testdebugproto.c941
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testfdtransport.c184
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testframedtransport.c323
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testmemorybuffer.c223
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testoptionalrequired.c227
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/testserialization.c95
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testsimpleserver.c122
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/teststruct.c111
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testthrifttest.c112
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/testthrifttestclient.cpp639
-rwxr-xr-xsrc/jaegertracing/thrift/lib/c_glib/test/testtransportsocket.c361
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/test/testtransportsslsocket.c542
-rw-r--r--src/jaegertracing/thrift/lib/c_glib/thrift_c_glib.pc.in30
85 files changed, 19794 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/lib/c_glib/CMakeLists.txt b/src/jaegertracing/thrift/lib/c_glib/CMakeLists.txt
new file mode 100644
index 000000000..3e4a154b8
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/CMakeLists.txt
@@ -0,0 +1,87 @@
+#
+# 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/processor/thrift_multiplexed_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_protocol_decorator.c
+ src/thrift/c_glib/protocol/thrift_binary_protocol.c
+ src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
+ src/thrift/c_glib/protocol/thrift_multiplexed_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
+)
+
+# If OpenSSL is not found just ignore the OpenSSL stuff
+find_package(OpenSSL)
+if(OPENSSL_FOUND AND WITH_OPENSSL)
+ list( APPEND thrift_c_glib_SOURCES
+ src/thrift/c_glib/transport/thrift_ssl_socket.c
+ )
+ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
+ list(APPEND SYSLIBS "${OPENSSL_LIBRARIES}")
+endif()
+
+
+# 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()
diff --git a/src/jaegertracing/thrift/lib/c_glib/Makefile.am b/src/jaegertracing/thrift/lib/c_glib/Makefile.am
new file mode 100755
index 000000000..fd7f93d76
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/Makefile.am
@@ -0,0 +1,118 @@
+#
+# 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 nostdinc
+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/processor/thrift_multiplexed_processor.c \
+ src/thrift/c_glib/protocol/thrift_protocol.c \
+ src/thrift/c_glib/protocol/thrift_protocol_decorator.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_stored_message_protocol.c \
+ src/thrift/c_glib/protocol/thrift_multiplexed_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_ssl_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) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) -I$(top_builddir)/lib/c_glib/src/thrift
+libthrift_c_glib_la_LDFLAGS = $(AM_LDFLAGS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS)
+
+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_decorator.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 \
+ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h \
+ src/thrift/c_glib/protocol/thrift_stored_message_protocol.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_platform_socket.h \
+ src/thrift/c_glib/transport/thrift_ssl_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 \
+ src/thrift/c_glib/processor/thrift_multiplexed_processor.h
+
+
+EXTRA_DIST = \
+ CMakeLists.txt \
+ coding_standards.md \
+ README.md \
+ test/glib.suppress \
+ thrift_c_glib.pc.in
+
+CLEANFILES = \
+ *.gcno \
+ *.gcda
diff --git a/src/jaegertracing/thrift/lib/c_glib/README.md b/src/jaegertracing/thrift/lib/c_glib/README.md
new file mode 100644
index 000000000..dd84f3d35
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/README.md
@@ -0,0 +1,49 @@
+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/
+
+Breaking Changes
+================
+
+0.12.0
+------
+
+The compiler's handling of namespaces when generating the name of types,
+functions and header files has been improved. This means code written to use
+classes generated by previous versions of the compiler may need to be updated to
+reflect the proper convention for class names, which is
+
+- A lowercase, [snake-case](https://en.wikipedia.org/wiki/Snake_case)
+ representation of the class' namespace, followed by
+- An underscore and
+- A lowercase, snake-case representation of the class' name.
diff --git a/src/jaegertracing/thrift/lib/c_glib/coding_standards.md b/src/jaegertracing/thrift/lib/c_glib/coding_standards.md
new file mode 100644
index 000000000..24b3a0056
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/coding_standards.md
@@ -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)
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.c
new file mode 100644
index 000000000..57d621751
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.c
@@ -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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.h
new file mode 100644
index 000000000..5afb85ec8
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
new file mode 100644
index 000000000..68a0f4d46
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
@@ -0,0 +1,346 @@
+/*
+ * 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/processor/thrift_processor.h>
+#include <thrift/c_glib/processor/thrift_multiplexed_processor.h>
+#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h>
+#include <thrift/c_glib/protocol/thrift_stored_message_protocol.h>
+#include <thrift/c_glib/thrift_application_exception.h>
+
+G_DEFINE_TYPE(ThriftMultiplexedProcessor, thrift_multiplexed_processor, THRIFT_TYPE_PROCESSOR)
+
+
+enum
+{
+ PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME = 1,
+ PROP_THRIFT_MULTIPLEXED_PROCESSOR_END
+};
+
+static GParamSpec *thrift_multiplexed_processor_obj_properties[PROP_THRIFT_MULTIPLEXED_PROCESSOR_END] = { NULL, };
+
+
+static gboolean
+thrift_multiplexed_processor_register_processor_impl(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(processor);
+ g_hash_table_replace(self->multiplexed_services,
+ g_strdup(multiplexed_processor_name),
+ g_object_ref (multiplexed_processor));
+
+ /* Make first registered become default */
+ if(!self->default_processor_name){
+ self->default_processor_name = g_strdup(multiplexed_processor_name);
+ }
+ return TRUE;
+}
+
+
+static gboolean
+thrift_multiplexed_processor_process_impl (ThriftProcessor *processor, ThriftProtocol *in,
+ ThriftProtocol *out, GError **error)
+{
+ gboolean retval = FALSE;
+ gboolean token_error = FALSE;
+ ThriftApplicationException *xception;
+ ThriftStoredMessageProtocol *stored_message_protocol = NULL;
+ ThriftMessageType message_type;
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(processor);
+ ThriftProcessor *multiplexed_processor = NULL;
+ ThriftTransport *transport;
+ char *token=NULL;
+ int token_index=0;
+ char *state=NULL;
+ gchar *fname=NULL;
+ gint32 seqid, result;
+
+ /* FIXME It seems that previous processor is not managing error correctly */
+ if(*error!=NULL) {
+ g_debug ("thrift_multiplexed_processor: last error not removed: %s",
+ *error != NULL ? (*error)->message : "(null)");
+ g_clear_error (error);
+ }
+
+
+ THRIFT_PROTOCOL_GET_CLASS(in)->read_message_begin(in, &fname, &message_type, &seqid, error);
+
+ if(!(message_type == T_CALL || message_type == T_ONEWAY)) {
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_TYPE,
+ "message type invalid for this processor");
+ }else{
+ /* Split by the token */
+ for (token = strtok_r(fname, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, &state),
+ token_index=0;
+ token != NULL && !token_error;
+ token = strtok_r(NULL, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, &state),
+ token_index++)
+ {
+ switch(token_index){
+ case 0:
+ /* It should be the service name */
+ multiplexed_processor = g_hash_table_lookup(self->multiplexed_services, token);
+ if(multiplexed_processor==NULL){
+ token_error=TRUE;
+ }
+ break;
+ case 1:
+ /* It should be the function name */
+ stored_message_protocol = g_object_new (THRIFT_TYPE_STORED_MESSAGE_PROTOCOL,
+ "protocol", in,
+ "name", token,
+ "type", message_type,
+ "seqid", seqid,
+ NULL);
+ break;
+ default:
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_WRONGLY_MULTIPLEXED,
+ "the message has more tokens than expected!");
+ token_error=TRUE;
+ break;
+ }
+ }
+ /* Set default */
+ if(!stored_message_protocol &&
+ !multiplexed_processor &&
+ token_index==1 && self->default_processor_name){
+ /* It should be the service name */
+ multiplexed_processor = g_hash_table_lookup(self->multiplexed_services, self->default_processor_name);
+ if(multiplexed_processor==NULL){
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE,
+ "service %s not available on this processor",
+ self->default_processor_name);
+ }else{
+ /* Set the message name to the original name */
+ stored_message_protocol = g_object_new (THRIFT_TYPE_STORED_MESSAGE_PROTOCOL,
+ "protocol", in,
+ "name", fname,
+ "type", message_type,
+ "seqid", seqid,
+ NULL);
+ }
+
+ }
+
+ if(stored_message_protocol!=NULL && multiplexed_processor!=NULL){
+ retval = THRIFT_PROCESSOR_GET_CLASS (multiplexed_processor)->process (multiplexed_processor, (ThriftProtocol *) stored_message_protocol, out, error) ;
+ }else{
+ if(!error)
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE,
+ "service %s is not multiplexed in this processor",
+ fname);
+ }
+
+
+ }
+
+ if(!retval){
+ /* By default, return an application exception to the client indicating the
+ method name is not recognized. */
+ /* Copied from dispach processor */
+
+ if ((thrift_protocol_skip (in, T_STRUCT, error) < 0) ||
+ (thrift_protocol_read_message_end (in, error) < 0))
+ return retval;
+
+ g_object_get (in, "transport", &transport, NULL);
+ result = thrift_transport_read_end (transport, error);
+ g_object_unref (transport);
+ if (result < 0) {
+ /* We must free fname */
+ g_free(fname);
+ return retval;
+ }
+
+ if (thrift_protocol_write_message_begin (out,
+ fname,
+ T_EXCEPTION,
+ seqid,
+ error) < 0){
+ /* We must free fname */
+ g_free(fname);
+
+ return retval;
+ }
+
+
+ xception =
+ g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION,
+ "type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD,
+ "message", (*error)->message,
+ NULL);
+ 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 retval;
+
+ g_object_get (out, "transport", &transport, NULL);
+ retval =
+ ((thrift_transport_write_end (transport, error) >= 0) &&
+ (thrift_transport_flush (transport, error) >= 0));
+ g_object_unref (transport);
+ }else{
+ /* The protocol now has a copy we can free it */
+ g_free(fname);
+
+ }
+
+ /*
+ FIXME This makes everything fail, I don't know why.
+ if(stored_message_protocol!=NULL){
+ // After its use we must free it
+ g_object_unref(stored_message_protocol);
+ }
+ */
+ return retval;
+}
+
+/* define the GError domain for Thrift transports */
+GQuark
+thrift_multiplexed_processor_error_quark (void)
+{
+ return g_quark_from_static_string (THRIFT_MULTIPLEXED_PROCESSOR_ERROR_DOMAIN);
+}
+
+
+static void
+thrift_multiplexed_processor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME:
+ self->default_processor_name = g_value_dup_string (value);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+thrift_multiplexed_processor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME:
+ g_value_set_string (value, self->default_processor_name);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+/* destructor */
+static void
+thrift_multiplexed_processor_finalize (GObject *object)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(object);
+
+ /* Free our multiplexed hash table */
+ g_hash_table_unref (self->multiplexed_services);
+ self->multiplexed_services = NULL;
+
+ if(self->default_processor_name){
+ g_free(self->default_processor_name);
+ self->default_processor_name=NULL;
+ }
+
+ /* Chain up to parent */
+ if (G_OBJECT_CLASS (thrift_multiplexed_processor_parent_class)->finalize)
+ (*G_OBJECT_CLASS (thrift_multiplexed_processor_parent_class)->finalize) (object);
+}
+
+/* class initializer for ThriftMultiplexedProcessor */
+static void
+thrift_multiplexed_processor_class_init (ThriftMultiplexedProcessorClass *cls)
+{
+ /* Override */
+ THRIFT_PROCESSOR_CLASS(cls)->process = thrift_multiplexed_processor_process_impl;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+
+ /* Object methods */
+ gobject_class->set_property = thrift_multiplexed_processor_set_property;
+ gobject_class->get_property = thrift_multiplexed_processor_get_property;
+ gobject_class->finalize = thrift_multiplexed_processor_finalize;
+
+ /* Class methods */
+ cls->register_processor = thrift_multiplexed_processor_register_processor_impl;
+
+
+ thrift_multiplexed_processor_obj_properties[PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME] =
+ g_param_spec_string ("default",
+ "Default service name the protocol points to where no multiplexed client used",
+ "Set the default service name",
+ NULL,
+ (G_PARAM_READWRITE));
+
+ g_object_class_install_properties (gobject_class,
+ PROP_THRIFT_MULTIPLEXED_PROCESSOR_END,
+ thrift_multiplexed_processor_obj_properties);
+
+}
+
+static void
+thrift_multiplexed_processor_init (ThriftMultiplexedProcessor *self)
+{
+
+ /* Create our multiplexed services hash table */
+ self->multiplexed_services = g_hash_table_new_full (
+ g_str_hash,
+ g_str_equal,
+ g_free,
+ g_object_unref);
+ self->default_processor_name = NULL;
+}
+
+
+gboolean
+thrift_multiplexed_processor_register_processor(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error)
+{
+ return THRIFT_MULTIPLEXED_PROCESSOR_GET_CLASS(processor)->register_processor(processor, multiplexed_processor_name, multiplexed_processor, error);
+}
+
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h
new file mode 100644
index 000000000..6406616c2
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h
@@ -0,0 +1,114 @@
+/*
+ * thrift_multiplexed_processor.h
+ *
+ * Created on: 14 sept. 2017
+ * Author: gaguilar
+ */
+
+#ifndef _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_
+#define _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_
+
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/processor/thrift_processor.h>
+
+
+G_BEGIN_DECLS
+
+/*! \file thrift_multiplexed_processor.h
+ * \brief The multiplexed processor for c_glib.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_MULTIPLEXED_PROCESSOR (thrift_multiplexed_processor_get_type ())
+#define THRIFT_MULTIPLEXED_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessor))
+#define THRIFT_IS_MULTIPLEXED_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR))
+#define THRIFT_MULTIPLEXED_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessorClass))
+#define THRIFT_IS_MULTIPLEXED_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROCESSOR))
+#define THRIFT_MULTIPLEXED_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessorClass))
+
+/* define the GError domain string */
+#define THRIFT_MULTIPLEXED_PROCESSOR_ERROR_DOMAIN "thrift-multiplexed-processor-error-quark"
+
+
+/*!
+ * Thrift MultiplexedProcessor object
+ */
+struct _ThriftMultiplexedProcessor
+{
+ ThriftProcessor parent;
+
+ /* private */
+ gchar * default_processor_name;
+ GHashTable *multiplexed_services;
+};
+typedef struct _ThriftMultiplexedProcessor ThriftMultiplexedProcessor;
+
+/*!
+ * Thrift MultiplexedProcessor class
+ */
+struct _ThriftMultiplexedProcessorClass
+{
+ ThriftProcessorClass parent;
+
+ gboolean (* register_processor) (ThriftProcessor *self, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error);
+
+};
+typedef struct _ThriftMultiplexedProcessorClass ThriftMultiplexedProcessorClass;
+
+/* used by THRIFT_TYPE_MULTIPLEXED_PROCESSOR */
+GType thrift_multiplexed_processor_get_type (void);
+
+/*!
+ * Processes the request.
+ * \public \memberof ThriftMultiplexedProcessorClass
+ */
+gboolean thrift_multiplexed_processor_process (ThriftMultiplexedProcessor *processor,
+ ThriftProtocol *in, ThriftProtocol *out,
+ GError **error);
+
+
+/* Public API */
+
+/**
+ * @brief Registers a processor in the multiplexed processor under its name. It
+ * will take a reference to the processor so refcount will be incremented.
+ * It will also be decremented on object destruction.
+ *
+ * The first registered processor becomes default. But you can override it with
+ * "default" property.
+ *
+ * It returns a compliant error if it cannot be registered.
+ *
+ * @param processor Pointer to the multiplexed processor.
+ * @param multiplexed_processor_name Name of the processor you want to register
+ * @param multiplexed_processor Pointer to implemented processor you want multiplex.
+ * @param error Error object where we should store errors.
+ *
+ * @see https://developer.gnome.org/glib/stable/glib-Error-Reporting.html#g-set-error
+ */
+gboolean thrift_multiplexed_processor_register_processor(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error);
+
+
+/* define error/exception types */
+typedef enum
+{
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_UNKNOWN,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_TYPE,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_WRONGLY_MULTIPLEXED,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SEND,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_RECEIVE,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_CLOSE
+} ThriftMultiplexedProcessorError;
+
+
+GQuark thrift_multiplexed_processor_error_quark (void);
+#define THRIFT_MULTIPLEXED_PROCESSOR_ERROR (thrift_multiplexed_processor_error_quark ())
+
+
+G_END_DECLS
+
+
+#endif /* _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_ */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.c
new file mode 100644
index 000000000..c242c2503
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.h
new file mode 100644
index 000000000..ff2d2dae4
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
new file mode 100644
index 000000000..7c2d017e1
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
@@ -0,0 +1,911 @@
+/*
+ * 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) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", read_len);
+ *str = NULL;
+ return -1;
+ }
+
+ /* allocate the memory for the string */
+ len = (guint32) read_len + 1; /* space for null terminator */
+ *str = g_new0 (gchar, len);
+ if (read_len > 0) {
+ 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 = 0;
+ }
+
+ 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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h
new file mode 100644
index 000000000..5230bcced
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c
new file mode 100644
index 000000000..774e9ad4a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h
new file mode 100644
index 000000000..eddc07390
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c
new file mode 100644
index 000000000..cae4749f0
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c
@@ -0,0 +1,1609 @@
+/*
+ * 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_compact_protocol.h>
+
+#include <thrift/config.h>
+
+/*
+ * *_to_zigzag depend on the fact that the right shift
+ * operator on a signed integer is an arithmetic (sign-extending) shift.
+ * If this is not the case, the current implementation will not work.
+ */
+#if !defined(SIGNED_RIGHT_SHIFT_IS) || !defined(ARITHMETIC_RIGHT_SHIFT)
+# error "Unable to determine the behavior of a signed right shift"
+#endif
+#if SIGNED_RIGHT_SHIFT_IS != ARITHMETIC_RIGHT_SHIFT
+# error "thrift_compact_protocol only works if signed right shift is arithmetic"
+#endif
+
+/* object properties */
+enum _ThriftCompactProtocolProperties
+{
+ PROP_0,
+ PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT,
+ PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT
+};
+
+G_DEFINE_TYPE (ThriftCompactProtocol, thrift_compact_protocol,
+ THRIFT_TYPE_PROTOCOL)
+
+static const gint8 PROTOCOL_ID = (gint8)0x82u;
+static const gint8 VERSION_N = 1;
+static const gint8 VERSION_MASK = 0x1f; /* 0001 1111 */
+static const gint8 TYPE_MASK = (gint8)0xe0u; /* 1110 0000 */
+static const gint8 TYPE_BITS = 0x07; /* 0000 0111 */
+static const gint32 TYPE_SHIFT_AMOUNT = 5;
+
+enum Types {
+ CT_STOP = 0x00,
+ CT_BOOLEAN_TRUE = 0x01,
+ CT_BOOLEAN_FALSE = 0x02,
+ CT_BYTE = 0x03,
+ CT_I16 = 0x04,
+ CT_I32 = 0x05,
+ CT_I64 = 0x06,
+ CT_DOUBLE = 0x07,
+ CT_BINARY = 0x08,
+ CT_LIST = 0x09,
+ CT_SET = 0x0A,
+ CT_MAP = 0x0B,
+ CT_STRUCT = 0x0C
+};
+
+static const gint8 TTypeToCType[16] = {
+ CT_STOP, /* T_STOP */
+ 0, /* unused */
+ CT_BOOLEAN_TRUE, /* T_BOOL */
+ CT_BYTE, /* T_BYTE */
+ CT_DOUBLE, /* T_DOUBLE */
+ 0, /* unused */
+ CT_I16, /* T_I16 */
+ 0, /* unused */
+ CT_I32, /* T_I32 */
+ 0, /* unused */
+ CT_I64, /* T_I64 */
+ CT_BINARY, /* T_STRING */
+ CT_STRUCT, /* T_STRUCT */
+ CT_MAP, /* T_MAP */
+ CT_SET, /* T_SET */
+ CT_LIST, /* T_LIST */
+};
+
+static guint64
+thrift_bitwise_cast_guint64 (const gdouble v)
+{
+ union {
+ gdouble from;
+ guint64 to;
+ } u;
+ u.from = v;
+ return u.to;
+}
+
+static gdouble
+thrift_bitwise_cast_gdouble (const guint64 v)
+{
+ union {
+ guint64 from;
+ gdouble to;
+ } u;
+ u.from = v;
+ return u.to;
+}
+
+/**
+ * Convert l into a zigzag long. This allows negative numbers to be
+ * represented compactly as a varint.
+ */
+static guint64
+i64_to_zigzag (const gint64 l)
+{
+ return (((guint64)l) << 1) ^ (l >> 63);
+}
+
+/**
+ * Convert n into a zigzag int. This allows negative numbers to be
+ * represented compactly as a varint.
+ */
+static guint32
+i32_to_zigzag (const gint32 n)
+{
+ return (((guint32)n) << 1) ^ (n >> 31);
+}
+
+/**
+ * Convert from zigzag int to int.
+ */
+static gint32
+zigzag_to_i32 (guint32 n)
+{
+ return (n >> 1) ^ (guint32) (-(gint32) (n & 1));
+}
+
+/**
+ * Convert from zigzag long to long.
+ */
+static gint64
+zigzag_to_i64 (guint64 n)
+{
+ return (n >> 1) ^ (guint64) (-(gint64) (n & 1));
+}
+
+ThriftType thrift_compact_protocol_get_ttype (ThriftCompactProtocol *protocol,
+ const gint8 type, GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+
+ switch (type) {
+ case T_STOP:
+ return T_STOP;
+ case CT_BOOLEAN_FALSE:
+ case CT_BOOLEAN_TRUE:
+ return T_BOOL;
+ case CT_BYTE:
+ return T_BYTE;
+ case CT_I16:
+ return T_I16;
+ case CT_I32:
+ return T_I32;
+ case CT_I64:
+ return T_I64;
+ case CT_DOUBLE:
+ return T_DOUBLE;
+ case CT_BINARY:
+ return T_STRING;
+ case CT_LIST:
+ return T_LIST;
+ case CT_SET:
+ return T_SET;
+ case CT_MAP:
+ return T_MAP;
+ case CT_STRUCT:
+ return T_STRUCT;
+ default:
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_INVALID_DATA,
+ "unrecognized type");
+ return -1;
+ }
+}
+
+/**
+ * Write an i32 as a varint. Results in 1-5 bytes on the wire.
+ */
+gint32
+thrift_compact_protocol_write_varint32 (ThriftCompactProtocol *protocol,
+ const guint32 n,
+ GError **error)
+{
+ guint8 buf[5];
+ gint32 xfer;
+ guint32 m;
+
+ THRIFT_UNUSED_VAR (error);
+
+ xfer = 0;
+ m = n;
+
+ while (TRUE) {
+ if ((m & ~0x7F) == 0) {
+ buf[xfer++] = (gint8)m;
+ break;
+ } else {
+ buf[xfer++] = (gint8)((m & 0x7F) | 0x80);
+ m >>= 7;
+ }
+ }
+
+ if (thrift_transport_write (THRIFT_PROTOCOL (protocol)->transport,
+ (const gpointer) buf, xfer, error)) {
+ return xfer;
+ } else {
+ return -1;
+ }
+}
+
+/**
+ * Write an i64 as a varint. Results in 1-10 bytes on the wire.
+ */
+gint32
+thrift_compact_protocol_write_varint64 (ThriftCompactProtocol *protocol,
+ const guint64 n,
+ GError **error)
+{
+ guint8 buf[10];
+ gint32 xfer;
+ guint64 m;
+
+ THRIFT_UNUSED_VAR (error);
+
+ xfer = 0;
+ m = n;
+
+ while (TRUE) {
+ if ((m & ~0x7FL) == 0) {
+ buf[xfer++] = (gint8)m;
+ break;
+ } else {
+ buf[xfer++] = (gint8)((m & 0x7F) | 0x80);
+ m >>= 7;
+ }
+ }
+
+ if (thrift_transport_write (THRIFT_PROTOCOL (protocol)->transport,
+ (const gpointer) buf, xfer, error)) {
+ return xfer;
+ } else {
+ return -1;
+ }
+}
+
+/**
+ * Read an i64 from the wire as a proper varint. The MSB of each byte is set
+ * if there is another byte to follow. This can read up to 10 bytes.
+ */
+gint32
+thrift_compact_protocol_read_varint64 (ThriftCompactProtocol *protocol,
+ gint64 *i64,
+ GError **error)
+{
+ ThriftProtocol *tp;
+ gint32 ret;
+ gint32 xfer;
+ guint64 val;
+ gint shift;
+ guint8 byte;
+
+ tp = THRIFT_PROTOCOL (protocol);
+ xfer = 0;
+ val = 0;
+ shift = 0;
+ byte = 0;
+
+ while (TRUE) {
+ if ((ret = thrift_transport_read_all (tp->transport,
+ (gpointer) &byte, 1, error)) < 0) {
+ return -1;
+ }
+ ++xfer;
+ val |= (guint64)(byte & 0x7f) << shift;
+ shift += 7;
+ if (!(byte & 0x80)) {
+ *i64 = (gint64) val;
+ return xfer;
+ }
+ if (G_UNLIKELY (xfer == 10)) { /* 7 * 9 < 64 < 7 * 10 */
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_INVALID_DATA,
+ "variable-length int over 10 bytes");
+ return -1;
+ }
+ }
+}
+
+/**
+ * Read an i32 from the wire as a varint. The MSB of each byte is set
+ * if there is another byte to follow. This can read up to 5 bytes.
+ */
+gint32
+thrift_compact_protocol_read_varint32 (ThriftCompactProtocol *protocol,
+ gint32 *i32,
+ GError **error)
+{
+ gint64 val;
+ gint32 ret;
+ gint32 xfer;
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_read_varint64 (protocol, &val,
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ *i32 = (gint32)val;
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_write_field_begin_internal (ThriftCompactProtocol
+ *protocol,
+ const gchar *name,
+ const ThriftType field_type,
+ const gint16 field_id,
+ const gint8 type_override,
+ GError **error)
+{
+ gint32 ret;
+ gint32 xfer;
+ gint8 type_to_write;
+
+ THRIFT_UNUSED_VAR (name);
+
+ xfer = 0;
+
+ /* if there's a type override, use that. */
+ type_to_write
+ = (type_override == -1 ? TTypeToCType[field_type] : type_override);
+
+ /* check if we can use delta encoding for the field id */
+ if (field_id > protocol->_last_field_id
+ && field_id - protocol->_last_field_id <= 15) {
+ /* write them together */
+ if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
+ (gint8) ((field_id
+ - protocol->_last_field_id)
+ << 4 | type_to_write),
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ } else {
+ /* write them separate */
+ if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
+ type_to_write, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if ((ret = thrift_protocol_write_i16 (THRIFT_PROTOCOL (protocol), field_id,
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ }
+
+ protocol->_last_field_id = field_id;
+ return xfer;
+}
+
+/**
+ * Method for writing the start of lists and sets. List and sets on
+ * the wire differ only by the type indicator.
+ */
+gint32
+thrift_compact_protocol_write_collection_begin (ThriftCompactProtocol *protocol,
+ const ThriftType elem_type,
+ guint32 size, GError **error)
+{
+ gint32 ret;
+ gint32 xfer;
+
+ xfer = 0;
+
+ if (size <= 14) {
+ if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
+ (gint8) (size << 4
+ | TTypeToCType[elem_type]),
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ } else {
+ if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
+ (gint8) (0xf0
+ | TTypeToCType[elem_type]),
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if ((ret = thrift_compact_protocol_write_varint32 (protocol,
+ (guint32) size,
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ }
+
+ return xfer;
+}
+
+/*
+ * public methods
+ */
+
+gint32
+thrift_compact_protocol_write_message_begin (ThriftProtocol *protocol,
+ const gchar *name,
+ const ThriftMessageType
+ message_type,
+ const gint32 seqid, GError **error)
+{
+ gint8 version;
+ gint32 ret;
+ gint32 xfer;
+
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ version = (VERSION_N & VERSION_MASK)
+ | (((gint32) message_type << TYPE_SHIFT_AMOUNT) & TYPE_MASK);
+ xfer = 0;
+
+ if ((ret = thrift_protocol_write_byte (protocol, PROTOCOL_ID, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if ((ret = thrift_protocol_write_byte (protocol, version, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if ((ret = thrift_compact_protocol_write_varint32 (cp,
+ (guint32) seqid,
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if ((ret = thrift_protocol_write_string (protocol, name, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_write_message_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ /* satisfy -Wall */
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_struct_begin (ThriftProtocol *protocol,
+ const gchar *name,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+ GQueue *q;
+
+ /* satisfy -Wall */
+ THRIFT_UNUSED_VAR (name);
+ THRIFT_UNUSED_VAR (error);
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+ q = &(cp->_last_field);
+
+ g_queue_push_tail (q, GINT_TO_POINTER ((gint) cp->_last_field_id));
+ cp->_last_field_id = 0;
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_struct_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+ GQueue *q;
+
+ /* satisfy -Wall */
+ THRIFT_UNUSED_VAR (error);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+ q = &(cp->_last_field);
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp->_last_field_id = (gint16) GPOINTER_TO_INT (g_queue_pop_tail (q));
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_field_begin (ThriftProtocol *protocol,
+ const gchar *name,
+ const ThriftType field_type,
+ const gint16 field_id,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ if (field_type == T_BOOL) {
+ cp->_bool_field_name = name;
+ cp->_bool_field_type = field_type;
+ cp->_bool_field_id = field_id;
+ return 0;
+ } else {
+ return thrift_compact_protocol_write_field_begin_internal (cp, name,
+ field_type,
+ field_id, -1,
+ error);
+ }
+}
+
+gint32
+thrift_compact_protocol_write_field_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ /* satisfy -Wall */
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_field_stop (ThriftProtocol *protocol,
+ GError **error)
+{
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+ return thrift_protocol_write_byte (protocol, (gint8) T_STOP, error);
+}
+
+gint32
+thrift_compact_protocol_write_map_begin (ThriftProtocol *protocol,
+ const ThriftType key_type,
+ const ThriftType value_type,
+ const guint32 size,
+ GError **error)
+{
+ gint32 ret;
+ gint32 xfer;
+
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_write_varint32 (cp, (guint32) size,
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if (size > 0) {
+ if ((ret = thrift_protocol_write_byte (protocol,
+ (gint8) (TTypeToCType[key_type] << 4
+ | TTypeToCType[value_type]),
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ }
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_write_map_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_list_begin (ThriftProtocol *protocol,
+ const ThriftType element_type,
+ const guint32 size,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ return thrift_compact_protocol_write_collection_begin (cp, element_type,
+ size, error);
+}
+
+gint32
+thrift_compact_protocol_write_list_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_set_begin (ThriftProtocol *protocol,
+ const ThriftType element_type,
+ const guint32 size,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ return thrift_compact_protocol_write_collection_begin (cp, element_type,
+ size, error);
+}
+
+gint32
+thrift_compact_protocol_write_set_end (ThriftProtocol *protocol, GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_write_bool (ThriftProtocol *protocol,
+ const gboolean value, GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if (cp->_bool_field_name != NULL) {
+ /* we haven't written the field header yet */
+ if ((ret = thrift_compact_protocol_write_field_begin_internal (cp,
+ cp->_bool_field_name,
+ cp->_bool_field_type,
+ cp->_bool_field_id,
+ (gint8) (value
+ ? CT_BOOLEAN_TRUE : CT_BOOLEAN_FALSE),
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ cp->_bool_field_name = NULL;
+ } else {
+ /* we're not part of a field, so just write the value */
+ if ((ret = thrift_protocol_write_byte (protocol,
+ (gint8) (value ? CT_BOOLEAN_TRUE
+ : CT_BOOLEAN_FALSE),
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ }
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
+ GError **error)
+{
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ if (thrift_transport_write (protocol->transport,
+ (const gpointer) &value, 1, error)) {
+ return 1;
+ } else {
+ return -1;
+ }
+}
+
+gint32
+thrift_compact_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ return thrift_compact_protocol_write_varint32 (cp,
+ i32_to_zigzag ((gint32) value),
+ error);
+}
+
+gint32
+thrift_compact_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ return thrift_compact_protocol_write_varint32 (cp,
+ i32_to_zigzag (value),
+ error);
+}
+
+gint32
+thrift_compact_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ return thrift_compact_protocol_write_varint64 (cp,
+ i64_to_zigzag (value),
+ error);
+}
+
+gint32
+thrift_compact_protocol_write_double (ThriftProtocol *protocol,
+ const gdouble value, GError **error)
+{
+ guint64 bits;
+
+ g_assert (sizeof (gdouble) == sizeof (guint64));
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ bits = GUINT64_TO_LE (thrift_bitwise_cast_guint64 (value));
+ if (thrift_transport_write (protocol->transport,
+ (const gpointer) &bits, 8, error)) {
+ return 8;
+ } else {
+ return -1;
+ }
+}
+
+gint32
+thrift_compact_protocol_write_string (ThriftProtocol *protocol,
+ const gchar *str, GError **error)
+{
+ size_t len;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ len = str != NULL ? strlen (str) : 0;
+ if (len > G_MAXINT32) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
+ "string size (guess: %lu) is too large", (unsigned long) len);
+ return -1;
+ }
+
+ /* write the string length + 1 which includes the null terminator */
+ return thrift_protocol_write_binary (protocol, (const gpointer) str,
+ (const guint32) len, error);
+}
+
+gint32
+thrift_compact_protocol_write_binary (ThriftProtocol *protocol,
+ const gpointer buf,
+ const guint32 len, GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_write_varint32 (cp, len, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if (len > 0) {
+ /* checking len + xfer > uint_max, but we don't want to overflow while
+ * checking for overflows. transforming to len > uint_max - xfer.
+ */
+ if (len > (guint32) (G_MAXINT32 - xfer)) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
+ "size %d + %d is too large", len, xfer);
+ return -1;
+ }
+
+ if (thrift_transport_write (protocol->transport,
+ (const gpointer) buf, len, error) == FALSE) {
+ return -1;
+ }
+ xfer += len;
+ }
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_message_begin (ThriftProtocol *protocol,
+ gchar **name,
+ ThriftMessageType *message_type,
+ gint32 *seqid, GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ gint8 protocol_id, version_and_type, version;
+
+ xfer = 0;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ if ((ret = thrift_protocol_read_byte (protocol, &protocol_id, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if (protocol_id != PROTOCOL_ID) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_BAD_VERSION,
+ "bad protocol id");
+ return -1;
+ }
+
+ if ((ret = thrift_protocol_read_byte (protocol, &version_and_type,
+ error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ version = (gint8)(version_and_type & VERSION_MASK);
+ if (version != VERSION_N) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_BAD_VERSION,
+ "bad version and/or type");
+ return -1;
+ }
+
+ *message_type
+ = (ThriftMessageType)((version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
+
+ if ((ret = thrift_compact_protocol_read_varint32 (cp, seqid, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if ((ret = thrift_protocol_read_string (protocol, name, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_message_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_struct_begin (ThriftProtocol *protocol,
+ gchar **name,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+ GQueue *q;
+
+ THRIFT_UNUSED_VAR (error);
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+ q = &(cp->_last_field);
+
+ *name = NULL;
+
+ g_queue_push_tail (q, GINT_TO_POINTER ((gint) cp->_last_field_id));
+ cp->_last_field_id = 0;
+
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_struct_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+ GQueue *q;
+
+ THRIFT_UNUSED_VAR (error);
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+ q = &(cp->_last_field);
+
+ cp->_last_field_id = (gint16) GPOINTER_TO_INT (g_queue_pop_tail (q));
+
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_field_begin (ThriftProtocol *protocol,
+ gchar **name,
+ ThriftType *field_type,
+ gint16 *field_id,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ gint16 modifier;
+ gint8 byte;
+ gint8 type;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ THRIFT_UNUSED_VAR (name);
+
+ xfer = 0;
+
+ if ((ret = thrift_protocol_read_byte (protocol, &byte, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ type = (byte & 0x0f);
+
+ /* if it's a stop, then we can return immediately, as the struct is over. */
+ if (type == T_STOP) {
+ *field_type = T_STOP;
+ *field_id = 0;
+ return xfer;
+ }
+
+ /* mask off the 4 MSB of the type header.
+ * it could contain a field id delta.
+ */
+ modifier = (gint16)(((guint8)byte & 0xf0) >> 4);
+ if (modifier == 0) {
+ /* not a delta, look ahead for the zigzag varint field id. */
+ if ((ret = thrift_protocol_read_i16 (protocol, field_id, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ } else {
+ *field_id = (gint16)(cp->_last_field_id + modifier);
+ }
+ if ((ret = thrift_compact_protocol_get_ttype (cp, type, error)) < 0) {
+ return -1;
+ }
+ *field_type = ret;
+
+ /* if this happens to be a boolean field, the value is encoded in the type */
+ if (type == CT_BOOLEAN_TRUE || type == CT_BOOLEAN_FALSE) {
+ /* save the boolean value in a special instance variable. */
+ cp->_has_bool_value = TRUE;
+ cp->_bool_value =
+ (type == CT_BOOLEAN_TRUE ? TRUE : FALSE);
+ }
+
+ /* push the new field onto the field stack so we can keep the deltas going. */
+ cp->_last_field_id = *field_id;
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_field_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_map_begin (ThriftProtocol *protocol,
+ ThriftType *key_type,
+ ThriftType *value_type,
+ guint32 *size,
+ GError **error)
+{
+ gint32 ret;
+ gint32 xfer;
+
+ gint8 kv_type;
+ gint32 msize;
+
+ ThriftCompactProtocol *cp;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ kv_type = 0;
+ msize = 0;
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_read_varint32 (cp, &msize, error)) <0) {
+ return -1;
+ }
+ xfer += ret;
+
+ /* still read the kv byte if negative size */
+ if (msize != 0) {
+ if ((ret = thrift_protocol_read_byte (protocol, &kv_type, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ }
+
+ if (cp->container_limit > 0 && msize > cp->container_limit) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
+ "got size over limit (%d > %d)", msize, cp->container_limit);
+ return -1;
+ } else if (msize > 0) {
+ if ((ret = thrift_compact_protocol_get_ttype (cp,
+ (gint8)((guint8)kv_type
+ >> 4),
+ error)) < 0) {
+ return -1;
+ }
+ *key_type = ret;
+ if ((ret = thrift_compact_protocol_get_ttype (cp,
+ (gint8)((guint8)kv_type
+ & 0xf),
+ error)) < 0) {
+ return -1;
+ }
+ *value_type = ret;
+ *size = (guint32) msize;
+ } else if (msize == 0) {
+ *key_type = 0;
+ *value_type = 0;
+ *size = 0;
+ } else {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", msize);
+ return -1;
+ }
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_map_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_list_begin (ThriftProtocol *protocol,
+ ThriftType *element_type,
+ guint32 *size, GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ gint8 size_and_type;
+ gint32 lsize;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ size_and_type = 0;
+
+ xfer = 0;
+
+ if ((ret = thrift_protocol_read_byte (protocol, &size_and_type, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ lsize = ((guint8)size_and_type >> 4) & 0x0f;
+ if (lsize == 15) {
+ if ((ret = thrift_compact_protocol_read_varint32 (cp, &lsize, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+ }
+
+ if (lsize < 0) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", lsize);
+ return -1;
+ } else if (cp->container_limit > 0 && lsize > cp->container_limit) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
+ "got size over limit (%d > %d)", lsize, cp->container_limit);
+ return -1;
+ }
+
+ if ((ret = thrift_compact_protocol_get_ttype (cp,
+ (gint8)(size_and_type & 0x0f),
+ error)) < 0) {
+ return -1;
+ }
+ *element_type = ret;
+ *size = (guint32) lsize;
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_list_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_set_begin (ThriftProtocol *protocol,
+ ThriftType *element_type,
+ guint32 *size, GError **error)
+{
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ return thrift_protocol_read_list_begin (protocol, element_type, size, error);
+}
+
+gint32
+thrift_compact_protocol_read_set_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (protocol);
+ THRIFT_UNUSED_VAR (error);
+ return 0;
+}
+
+gint32
+thrift_compact_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ gint8 val;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if (cp->_has_bool_value == TRUE) {
+ *value = cp->_bool_value;
+ cp->_has_bool_value = FALSE;
+ return 0;
+ } else {
+ if ((ret = thrift_protocol_read_byte (protocol, &val, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ *value = (val == CT_BOOLEAN_TRUE);
+ return xfer;
+ }
+}
+
+gint32
+thrift_compact_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
+ GError **error)
+{
+ gint32 ret;
+ gpointer b[1];
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ if ((ret =
+ thrift_transport_read_all (protocol->transport,
+ b, 1, error)) < 0) {
+ return -1;
+ }
+ *value = *(gint8 *) b;
+ return ret;
+}
+
+gint32
+thrift_compact_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 val;
+ gint32 xfer;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_read_varint32 (cp, &val, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ *value = (gint16) zigzag_to_i32 ((guint32) val);
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 val;
+ gint32 xfer;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_read_varint32 (cp, &val, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ *value = zigzag_to_i32 ((guint32) val);
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint64 val;
+ gint32 xfer;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+
+ if ((ret = thrift_compact_protocol_read_varint64 (cp, &val, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ *value = zigzag_to_i64 ((guint64) val);
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_double (ThriftProtocol *protocol,
+ gdouble *value, GError **error)
+{
+ gint32 ret;
+ union {
+ guint64 bits;
+ guint8 b[8];
+ } u;
+
+ g_assert (sizeof (gdouble) == sizeof (guint64));
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ if ((ret =
+ thrift_transport_read_all (protocol->transport,
+ u.b, 8, error)) < 0) {
+ return -1;
+ }
+ u.bits = GUINT64_FROM_LE (u.bits);
+ *value = thrift_bitwise_cast_gdouble (u.bits);
+ return ret;
+}
+
+gint32
+thrift_compact_protocol_read_string (ThriftProtocol *protocol,
+ gchar **str, GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ gint32 read_len;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+ read_len = 0;
+
+ /* read the length into read_len */
+ if ((ret =
+ thrift_compact_protocol_read_varint32 (cp, &read_len, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if (cp->string_limit > 0 && read_len > cp->string_limit) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
+ "got size over limit (%d > %d)", read_len, cp->string_limit);
+ *str = NULL;
+ return -1;
+ }
+
+ if (read_len < 0) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", read_len);
+ *str = NULL;
+ return -1;
+ }
+
+ /* allocate the memory as an array of unsigned char for binary data */
+ *str = g_new0 (gchar, read_len + 1);
+ if (read_len > 0) {
+ if ((ret =
+ thrift_transport_read_all (protocol->transport,
+ *str, read_len, error)) < 0) {
+ g_free (*str);
+ *str = NULL;
+ return -1;
+ }
+ xfer += ret;
+ } else {
+ **str = 0;
+ }
+
+ return xfer;
+}
+
+gint32
+thrift_compact_protocol_read_binary (ThriftProtocol *protocol,
+ gpointer *buf, guint32 *len,
+ GError **error)
+{
+ ThriftCompactProtocol *cp;
+
+ gint32 ret;
+ gint32 xfer;
+
+ gint32 read_len;
+
+ g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
+
+ cp = THRIFT_COMPACT_PROTOCOL (protocol);
+
+ xfer = 0;
+ read_len = 0;
+
+ /* read the length into read_len */
+ if ((ret =
+ thrift_compact_protocol_read_varint32 (cp, &read_len, error)) < 0) {
+ return -1;
+ }
+ xfer += ret;
+
+ if (cp->string_limit > 0 && read_len > cp->string_limit) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
+ "got size over limit (%d > %d)", read_len, cp->string_limit);
+ *buf = NULL;
+ *len = 0;
+ return -1;
+ }
+
+ 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 if (read_len == 0) {
+ *len = (guint32) read_len;
+ *buf = NULL;
+
+ } else {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", read_len);
+ *buf = NULL;
+ *len = 0;
+ return -1;
+ }
+
+ return xfer;
+}
+
+/* property accessor */
+void
+thrift_compact_protocol_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ ThriftCompactProtocol *tc;
+
+ THRIFT_UNUSED_VAR (pspec);
+
+ tc = THRIFT_COMPACT_PROTOCOL (object);
+
+ switch (property_id) {
+ case PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT:
+ g_value_set_int (value, tc->string_limit);
+ break;
+ case PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT:
+ g_value_set_int (value, tc->container_limit);
+ break;
+ }
+}
+
+/* property mutator */
+void
+thrift_compact_protocol_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ ThriftCompactProtocol *tc;
+
+ THRIFT_UNUSED_VAR (pspec);
+
+ tc = THRIFT_COMPACT_PROTOCOL (object);
+
+ switch (property_id) {
+ case PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT:
+ tc->string_limit = g_value_get_int (value);
+ break;
+ case PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT:
+ tc->container_limit = g_value_get_int (value);
+ break;
+ }
+}
+
+/* initialize the class */
+static void
+thrift_compact_protocol_class_init (ThriftCompactProtocolClass *klass)
+{
+ ThriftProtocolClass *cls;
+ GObjectClass *gobject_class;
+ GParamSpec *param_spec;
+
+ cls = THRIFT_PROTOCOL_CLASS (klass);
+ gobject_class = G_OBJECT_CLASS (klass);
+ param_spec = NULL;
+
+ /* setup accessors and mutators */
+ gobject_class->get_property = thrift_compact_protocol_get_property;
+ gobject_class->set_property = thrift_compact_protocol_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_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_CONTAINER_LIMIT,
+ param_spec);
+
+ cls->write_message_begin = thrift_compact_protocol_write_message_begin;
+ cls->write_message_end = thrift_compact_protocol_write_message_end;
+ cls->write_struct_begin = thrift_compact_protocol_write_struct_begin;
+ cls->write_struct_end = thrift_compact_protocol_write_struct_end;
+ cls->write_field_begin = thrift_compact_protocol_write_field_begin;
+ cls->write_field_end = thrift_compact_protocol_write_field_end;
+ cls->write_field_stop = thrift_compact_protocol_write_field_stop;
+ cls->write_map_begin = thrift_compact_protocol_write_map_begin;
+ cls->write_map_end = thrift_compact_protocol_write_map_end;
+ cls->write_list_begin = thrift_compact_protocol_write_list_begin;
+ cls->write_list_end = thrift_compact_protocol_write_list_end;
+ cls->write_set_begin = thrift_compact_protocol_write_set_begin;
+ cls->write_set_end = thrift_compact_protocol_write_set_end;
+ cls->write_bool = thrift_compact_protocol_write_bool;
+ cls->write_byte = thrift_compact_protocol_write_byte;
+ cls->write_i16 = thrift_compact_protocol_write_i16;
+ cls->write_i32 = thrift_compact_protocol_write_i32;
+ cls->write_i64 = thrift_compact_protocol_write_i64;
+ cls->write_double = thrift_compact_protocol_write_double;
+ cls->write_string = thrift_compact_protocol_write_string;
+ cls->write_binary = thrift_compact_protocol_write_binary;
+ cls->read_message_begin = thrift_compact_protocol_read_message_begin;
+ cls->read_message_end = thrift_compact_protocol_read_message_end;
+ cls->read_struct_begin = thrift_compact_protocol_read_struct_begin;
+ cls->read_struct_end = thrift_compact_protocol_read_struct_end;
+ cls->read_field_begin = thrift_compact_protocol_read_field_begin;
+ cls->read_field_end = thrift_compact_protocol_read_field_end;
+ cls->read_map_begin = thrift_compact_protocol_read_map_begin;
+ cls->read_map_end = thrift_compact_protocol_read_map_end;
+ cls->read_list_begin = thrift_compact_protocol_read_list_begin;
+ cls->read_list_end = thrift_compact_protocol_read_list_end;
+ cls->read_set_begin = thrift_compact_protocol_read_set_begin;
+ cls->read_set_end = thrift_compact_protocol_read_set_end;
+ cls->read_bool = thrift_compact_protocol_read_bool;
+ cls->read_byte = thrift_compact_protocol_read_byte;
+ cls->read_i16 = thrift_compact_protocol_read_i16;
+ cls->read_i32 = thrift_compact_protocol_read_i32;
+ cls->read_i64 = thrift_compact_protocol_read_i64;
+ cls->read_double = thrift_compact_protocol_read_double;
+ cls->read_string = thrift_compact_protocol_read_string;
+ cls->read_binary = thrift_compact_protocol_read_binary;
+}
+
+static void
+thrift_compact_protocol_init (ThriftCompactProtocol *self)
+{
+ g_queue_init (&(self->_last_field));
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.h
new file mode 100644
index 000000000..effcaadf0
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c
new file mode 100644
index 000000000..e725e1fd0
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h
new file mode 100644
index 000000000..3bf953b4c
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
new file mode 100644
index 000000000..5084ead47
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
@@ -0,0 +1,158 @@
+/*
+ * 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 <glib.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h>
+
+
+enum
+{
+ PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME = 1,
+ PROP_THRIFT_MULTIPLEXED_PROTOCOL_END
+};
+
+G_DEFINE_TYPE(ThriftMultiplexedProtocol, thrift_multiplexed_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR)
+
+
+static GParamSpec *thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_END] = { NULL, };
+
+gint32
+thrift_multiplexed_protocol_write_message_begin (ThriftMultiplexedProtocol *protocol,
+ const gchar *name, const ThriftMessageType message_type,
+ const gint32 seqid, GError **error)
+{
+ gint32 ret;
+ gchar *service_name = NULL;
+ g_return_val_if_fail (THRIFT_IS_MULTIPLEXED_PROTOCOL (protocol), -1);
+
+ ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (protocol);
+
+ if( (message_type == T_CALL || message_type == T_ONEWAY) && self->service_name != NULL) {
+ service_name = g_strdup_printf("%s%s%s", self->service_name, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, name);
+ }else{
+ service_name = g_strdup(name);
+ }
+
+ /* relay to the protocol_decorator */
+ ret = thrift_protocol_decorator_write_message_begin(protocol, service_name, message_type, seqid, error);
+
+ g_free(service_name);
+
+ return ret;
+}
+
+
+static void
+thrift_multiplexed_protocol_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME:
+ g_free(self->service_name);
+ self->service_name = g_value_dup_string (value);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+thrift_multiplexed_protocol_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME:
+ g_value_set_string (value, self->service_name);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+thrift_multiplexed_protocol_init (ThriftMultiplexedProtocol *protocol)
+{
+ protocol->service_name = NULL;
+}
+
+static void
+thrift_multiplexed_protocol_finalize (GObject *gobject)
+{
+ ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (gobject);
+
+ if (self->service_name) {
+ g_free(self->service_name);
+ self->service_name = NULL;
+ }
+
+ /* Always chain up to the parent class; as with dispose(), finalize()
+ * is guaranteed to exist on the parent's class virtual function table
+ */
+ G_OBJECT_CLASS (thrift_multiplexed_protocol_parent_class)->finalize(gobject);
+}
+
+
+/* initialize the class */
+static void
+thrift_multiplexed_protocol_class_init (ThriftMultiplexedProtocolClass *klass)
+{
+ ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ cls->write_message_begin = thrift_multiplexed_protocol_write_message_begin;
+
+ object_class->set_property = thrift_multiplexed_protocol_set_property;
+ object_class->get_property = thrift_multiplexed_protocol_get_property;
+ object_class->finalize = thrift_multiplexed_protocol_finalize;
+
+ thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME] =
+ g_param_spec_string ("service-name",
+ "Service name the protocol points to",
+ "Set the service name",
+ NULL,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+ g_object_class_install_properties (object_class,
+ PROP_THRIFT_MULTIPLEXED_PROTOCOL_END,
+ thrift_multiplexed_protocol_obj_properties);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
new file mode 100644
index 000000000..c6e08fb19
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
@@ -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_MULTIPLEXED_PROTOCOL_H
+#define _THRIFT_MULTIPLEXED_PROTOCOL_H
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_multiplexed_protocol.h
+ * \brief Multiplexed protocol implementation of a Thrift protocol. Implements the
+ * ThriftProtocol interface.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_MULTIPLEXED_PROTOCOL (thrift_multiplexed_protocol_get_type ())
+#define THRIFT_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocol))
+#define THRIFT_IS_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL))
+#define THRIFT_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass))
+#define THRIFT_IS_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL))
+#define THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass))
+
+/* constant */
+#define THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR ":"
+
+typedef struct _ThriftMultiplexedProtocol ThriftMultiplexedProtocol;
+
+
+
+/*!
+ * Thrift Multiplexed Protocol instance.
+ */
+struct _ThriftMultiplexedProtocol
+{
+ ThriftProtocolDecorator parent;
+
+ gchar *service_name;
+};
+
+typedef struct _ThriftMultiplexedProtocolClass ThriftMultiplexedProtocolClass;
+
+/*!
+ * Thrift Multiplexed Protocol class.
+ */
+struct _ThriftMultiplexedProtocolClass
+{
+ ThriftProtocolDecoratorClass parent;
+};
+
+/* used by THRIFT_TYPE_MULTIPLEXED_PROTOCOL */
+GType thrift_multiplexed_protocol_get_type (void);
+
+G_END_DECLS
+
+#endif /* _THRIFT_MULTIPLEXED_PROTOCOL_H */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c
new file mode 100644
index 000000000..6e6ae4d9a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c
@@ -0,0 +1,646 @@
+/*
+ * 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_dup_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);
+}
+
+#define THRIFT_SKIP_RESULT_OR_RETURN(_RES, _CALL) \
+ { \
+ gint32 _x = (_CALL); \
+ if (_x < 0) { return _x; } \
+ (_RES) += _x; \
+ }
+
+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:
+ {
+ gint32 result = 0;
+ gchar *name;
+ gint16 fid;
+ ThriftType ftype;
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_struct_begin (protocol, &name, error))
+ while (1)
+ {
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_field_begin (protocol, &name, &ftype,
+ &fid, error))
+ if (ftype == T_STOP)
+ {
+ break;
+ }
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_skip (protocol, ftype, error))
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_field_end (protocol, error))
+ }
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_struct_end (protocol, error))
+ return result;
+ }
+ case T_SET:
+ {
+ gint32 result = 0;
+ ThriftType elem_type;
+ guint32 i, size;
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_set_begin (protocol, &elem_type, &size,
+ error))
+ for (i = 0; i < size; i++)
+ {
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_skip (protocol, elem_type, error))
+ }
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_set_end (protocol, error))
+ return result;
+ }
+ case T_MAP:
+ {
+ gint32 result = 0;
+ ThriftType elem_type;
+ ThriftType key_type;
+ guint32 i, size;
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_map_begin (protocol, &key_type, &elem_type, &size,
+ error))
+ for (i = 0; i < size; i++)
+ {
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_skip (protocol, key_type, error))
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_skip (protocol, elem_type, error))
+ }
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_map_end (protocol, error))
+ return result;
+ }
+ case T_LIST:
+ {
+ gint32 result = 0;
+ ThriftType elem_type;
+ guint32 i, size;
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_list_begin (protocol, &elem_type, &size,
+ error))
+ for (i = 0; i < size; i++)
+ {
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_skip (protocol, elem_type, error))
+ }
+ THRIFT_SKIP_RESULT_OR_RETURN(result,
+ thrift_protocol_read_list_end (protocol, error))
+ return result;
+ }
+ default:
+ break;
+ }
+
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_INVALID_DATA,
+ "unrecognized type");
+ return -1;
+}
+
+/* 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_dispose (GObject *gobject)
+{
+ ThriftProtocol *self = THRIFT_PROTOCOL (gobject);
+
+ g_clear_object(&self->transport);
+
+ /* Always chain up to the parent class; there is no need to check if
+ * the parent class implements the dispose() virtual function: it is
+ * always guaranteed to do so
+ */
+ G_OBJECT_CLASS (thrift_protocol_parent_class)->dispose(gobject);
+}
+
+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;
+ gobject_class->dispose = thrift_protocol_dispose;
+
+ 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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.h
new file mode 100644
index 000000000..58fe5e0af
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
new file mode 100644
index 000000000..03f9420f7
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
@@ -0,0 +1,623 @@
+/*
+ * 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 <glib.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+
+G_DEFINE_TYPE(ThriftProtocolDecorator, thrift_protocol_decorator, THRIFT_TYPE_PROTOCOL)
+
+
+enum
+{
+ PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL = 1,
+ PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END
+};
+
+static GParamSpec *thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END] = { NULL, };
+
+
+
+
+
+gint32
+thrift_protocol_decorator_write_message_begin (ThriftProtocol *protocol,
+ const gchar *name,
+ const ThriftMessageType message_type,
+ const gint32 seqid, GError **error)
+{
+
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+ ThriftProtocolClass *proto = THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol);
+
+ g_debug("Concrete protocol %p | %p", (void *)self->concrete_protocol, (void *)proto);
+
+ return proto->write_message_begin (self->concrete_protocol, name,
+ message_type, seqid,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_message_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_message_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_struct_begin (ThriftProtocol *protocol, const gchar *name,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_begin (self->concrete_protocol,
+ name, error);
+}
+
+gint32
+thrift_protocol_decorator_write_struct_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_field_begin (ThriftProtocol *protocol,
+ const gchar *name,
+ const ThriftType field_type,
+ const gint16 field_id,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_begin (self->concrete_protocol,
+ name, field_type,
+ field_id, error);
+}
+
+gint32
+thrift_protocol_decorator_write_field_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_field_stop (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_stop (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_map_begin (ThriftProtocol *protocol,
+ const ThriftType key_type,
+ const ThriftType value_type,
+ const guint32 size, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_begin (self->concrete_protocol,
+ key_type, value_type,
+ size, error);
+}
+
+gint32
+thrift_protocol_decorator_write_map_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_list_begin (ThriftProtocol *protocol,
+ const ThriftType element_type,
+ const guint32 size, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_begin (self->concrete_protocol,
+ element_type, size,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_list_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_set_begin (ThriftProtocol *protocol,
+ const ThriftType element_type,
+ const guint32 size, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_begin (self->concrete_protocol,
+ element_type, size,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_set_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_bool (ThriftProtocol *protocol,
+ const gboolean value, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_bool (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_byte (ThriftProtocol *protocol, const gint8 value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_byte (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_i16 (ThriftProtocol *protocol, const gint16 value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i16 (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_i32 (ThriftProtocol *protocol, const gint32 value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i32 (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_i64 (ThriftProtocol *protocol, const gint64 value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i64 (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_double (ThriftProtocol *protocol,
+ const gdouble value, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_double (self->concrete_protocol,
+ value, error);
+}
+
+gint32
+thrift_protocol_decorator_write_string (ThriftProtocol *protocol,
+ const gchar *str, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_string (self->concrete_protocol, str,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_write_binary (ThriftProtocol *protocol, const gpointer buf,
+ const guint32 len, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_binary (self->concrete_protocol, buf,
+ len, error);
+}
+
+gint32
+thrift_protocol_decorator_read_message_begin (ThriftProtocol *protocol,
+ gchar **name,
+ ThriftMessageType *message_type,
+ gint32 *seqid, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_begin (self->concrete_protocol,
+ name, message_type,
+ seqid, error);
+}
+
+gint32
+thrift_protocol_decorator_read_message_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_struct_begin (ThriftProtocol *protocol,
+ gchar **name,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_begin (self->concrete_protocol,
+ name,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_struct_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_field_begin (ThriftProtocol *protocol,
+ gchar **name,
+ ThriftType *field_type,
+ gint16 *field_id,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_begin (self->concrete_protocol,
+ name,
+ field_type,
+ field_id,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_field_end (ThriftProtocol *protocol,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_map_begin (ThriftProtocol *protocol,
+ ThriftType *key_type,
+ ThriftType *value_type, guint32 *size,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_begin (self->concrete_protocol,
+ key_type,
+ value_type,
+ size,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_map_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_list_begin (ThriftProtocol *protocol,
+ ThriftType *element_type,
+ guint32 *size, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_begin (self->concrete_protocol,
+ element_type,
+ size, error);
+}
+
+gint32
+thrift_protocol_decorator_read_list_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_set_begin (ThriftProtocol *protocol,
+ ThriftType *element_type,
+ guint32 *size, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_begin (self->concrete_protocol,
+ element_type,
+ size, error);
+}
+
+gint32
+thrift_protocol_decorator_read_set_end (ThriftProtocol *protocol, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_end (self->concrete_protocol,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_bool (ThriftProtocol *protocol, gboolean *value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_bool (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_byte (ThriftProtocol *protocol, gint8 *value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_byte (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_i16 (ThriftProtocol *protocol, gint16 *value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i16 (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_i32 (ThriftProtocol *protocol, gint32 *value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i32 (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_i64 (ThriftProtocol *protocol, gint64 *value,
+ GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i64 (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_double (ThriftProtocol *protocol,
+ gdouble *value, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_double (self->concrete_protocol, value,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_string (ThriftProtocol *protocol,
+ gchar **str, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_string (self->concrete_protocol, str,
+ error);
+}
+
+gint32
+thrift_protocol_decorator_read_binary (ThriftProtocol *protocol, gpointer *buf,
+ guint32 *len, GError **error)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_binary (self->concrete_protocol, buf,
+ len, error);
+}
+
+
+static void
+thrift_protocol_decorator_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
+ self->concrete_protocol = g_value_dup_object (value);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+thrift_protocol_decorator_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
+ g_value_set_object (value, self->concrete_protocol);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+ThriftProtocol *
+thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol)
+{
+ ThriftProtocol *retval = NULL;
+ if(!THRIFT_IS_PROTOCOL_DECORATOR(protocol)){
+ g_warning("The type is not protocol decorator");
+ return NULL;
+ }
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR(protocol);
+ g_debug("Getting concrete protocol from %p -> %p", (void *)self, (void *)self->concrete_protocol);
+
+ return retval;
+}
+
+
+static void
+thrift_protocol_decorator_init (ThriftProtocolDecorator *protocol)
+{
+ protocol->concrete_protocol = NULL;
+}
+
+static void
+thrift_protocol_decorator_dispose (GObject *gobject)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (gobject);
+
+ g_clear_object(&self->concrete_protocol);
+
+ /* Always chain up to the parent class; there is no need to check if
+ * the parent class implements the dispose() virtual function: it is
+ * always guaranteed to do so
+ */
+ G_OBJECT_CLASS (thrift_protocol_decorator_parent_class)->dispose(gobject);
+}
+
+/* initialize the class */
+static void
+thrift_protocol_decorator_class_init (ThriftProtocolDecoratorClass *klass)
+{
+ ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = thrift_protocol_decorator_set_property;
+ object_class->get_property = thrift_protocol_decorator_get_property;
+ object_class->dispose = thrift_protocol_decorator_dispose;
+
+ thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL] =
+ g_param_spec_object ("protocol",
+ "Protocol",
+ "Set the protocol to be implemented", THRIFT_TYPE_PROTOCOL,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+ g_object_class_install_properties (object_class,
+ PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END,
+ thrift_protocol_decorator_obj_properties);
+
+ g_debug("Current decorator write_message_begin addr %p, new %p", cls->write_message_begin, thrift_protocol_decorator_write_message_begin);
+
+ cls->write_message_begin = thrift_protocol_decorator_write_message_begin;
+ cls->write_message_end = thrift_protocol_decorator_write_message_end;
+ cls->write_struct_begin = thrift_protocol_decorator_write_struct_begin;
+ cls->write_struct_end = thrift_protocol_decorator_write_struct_end;
+ cls->write_field_begin = thrift_protocol_decorator_write_field_begin;
+ cls->write_field_end = thrift_protocol_decorator_write_field_end;
+ cls->write_field_stop = thrift_protocol_decorator_write_field_stop;
+ cls->write_map_begin = thrift_protocol_decorator_write_map_begin;
+ cls->write_map_end = thrift_protocol_decorator_write_map_end;
+ cls->write_list_begin = thrift_protocol_decorator_write_list_begin;
+ cls->write_list_end = thrift_protocol_decorator_write_list_end;
+ cls->write_set_begin = thrift_protocol_decorator_write_set_begin;
+ cls->write_set_end = thrift_protocol_decorator_write_set_end;
+ cls->write_bool = thrift_protocol_decorator_write_bool;
+ cls->write_byte = thrift_protocol_decorator_write_byte;
+ cls->write_i16 = thrift_protocol_decorator_write_i16;
+ cls->write_i32 = thrift_protocol_decorator_write_i32;
+ cls->write_i64 = thrift_protocol_decorator_write_i64;
+ cls->write_double = thrift_protocol_decorator_write_double;
+ cls->write_string = thrift_protocol_decorator_write_string;
+ cls->write_binary = thrift_protocol_decorator_write_binary;
+ cls->read_message_begin = thrift_protocol_decorator_read_message_begin;
+ cls->read_message_end = thrift_protocol_decorator_read_message_end;
+ cls->read_struct_begin = thrift_protocol_decorator_read_struct_begin;
+ cls->read_struct_end = thrift_protocol_decorator_read_struct_end;
+ cls->read_field_begin = thrift_protocol_decorator_read_field_begin;
+ cls->read_field_end = thrift_protocol_decorator_read_field_end;
+ cls->read_map_begin = thrift_protocol_decorator_read_map_begin;
+ cls->read_map_end = thrift_protocol_decorator_read_map_end;
+ cls->read_list_begin = thrift_protocol_decorator_read_list_begin;
+ cls->read_list_end = thrift_protocol_decorator_read_list_end;
+ cls->read_set_begin = thrift_protocol_decorator_read_set_begin;
+ cls->read_set_end = thrift_protocol_decorator_read_set_end;
+ cls->read_bool = thrift_protocol_decorator_read_bool;
+ cls->read_byte = thrift_protocol_decorator_read_byte;
+ cls->read_i16 = thrift_protocol_decorator_read_i16;
+ cls->read_i32 = thrift_protocol_decorator_read_i32;
+ cls->read_i64 = thrift_protocol_decorator_read_i64;
+ cls->read_double = thrift_protocol_decorator_read_double;
+ cls->read_string = thrift_protocol_decorator_read_string;
+ cls->read_binary = thrift_protocol_decorator_read_binary;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h
new file mode 100644
index 000000000..13b6af238
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h
@@ -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_PROTOCOL_DECORATOR_H
+#define _THRIFT_PROTOCOL_DECORATOR_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_protocol_decorator.h
+ * \brief Multiplexed protocol implementation of a Thrift protocol. Implements the
+ * ThriftProtocol interface.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_PROTOCOL_DECORATOR (thrift_protocol_decorator_get_type ())
+#define THRIFT_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecorator))
+#define THRIFT_IS_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR))
+#define THRIFT_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass))
+#define THRIFT_IS_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL_DECORATOR))
+#define THRIFT_PROTOCOL_DECORATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass))
+
+typedef struct _ThriftProtocolDecorator ThriftProtocolDecorator;
+
+
+/*!
+ * Thrift Protocol Decorator instance.
+ */
+struct _ThriftProtocolDecorator
+{
+ ThriftProtocol parent;
+
+ ThriftProtocol *concrete_protocol;
+};
+
+typedef struct _ThriftProtocolDecoratorClass ThriftProtocolDecoratorClass;
+
+/*!
+ * Thrift Protocol Decorator class.
+ */
+struct _ThriftProtocolDecoratorClass
+{
+ ThriftProtocolClass parent;
+
+};
+
+/* used by THRIFT_TYPE_PROTOCOL_DECORATOR */
+GType thrift_protocol_decorator_get_type (void);
+
+G_END_DECLS
+
+#endif /* _THRIFT_PROTOCOL_DECORATOR_H */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.c
new file mode 100644
index 000000000..bef40876f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.c
@@ -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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.h
new file mode 100644
index 000000000..5f146dde3
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
new file mode 100644
index 000000000..22aca8a29
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
@@ -0,0 +1,192 @@
+/*
+ * 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 <glib.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/protocol/thrift_stored_message_protocol.h>
+
+
+enum
+{
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME = 1,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT, /* TODO ugly hack */
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END
+};
+
+G_DEFINE_TYPE(ThriftStoredMessageProtocol, thrift_stored_message_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR)
+
+
+static GParamSpec *thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END] = { NULL, };
+
+gint32
+thrift_stored_message_protocol_read_message_begin (ThriftProtocol *protocol,
+ gchar **name,
+ ThriftMessageType *message_type,
+ gint32 *seqid, GError **error)
+{
+ gint32 ret = 0;
+ g_return_val_if_fail (THRIFT_IS_STORED_MESSAGE_PROTOCOL (protocol), -1);
+ THRIFT_UNUSED_VAR (error);
+
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (protocol);
+
+ /* We return the stored values on construction */
+ *name = self->name;
+ *message_type = self->mtype;
+ *seqid = self->seqid;
+
+ return ret;
+}
+
+
+static void
+thrift_stored_message_protocol_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME:
+ self->name = g_value_dup_string (value);
+ break;
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE:
+ self->mtype = g_value_get_int (value);
+ break;
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID:
+ self->seqid = g_value_get_int (value);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+thrift_stored_message_protocol_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (object);
+ ThriftProtocolDecorator *decorator = THRIFT_PROTOCOL_DECORATOR (object);
+ ThriftTransport *transport=NULL;
+ switch (property_id)
+ {
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME:
+ g_value_set_string (value, self->name);
+ break;
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT:
+ /* FIXME Since we don't override properties in the decorator as it should
+ we just override the properties that we know are used */
+ g_object_get(decorator->concrete_protocol,pspec->name, &transport, NULL);
+ g_value_set_pointer (value, transport);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+thrift_stored_message_protocol_init (ThriftStoredMessageProtocol *protocol)
+{
+ protocol->name = NULL;
+}
+
+static void
+thrift_stored_message_protocol_finalize (GObject *gobject)
+{
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (gobject);
+
+ if (self->name) {
+ g_free(self->name);
+ self->name = NULL;
+ }
+
+ /* Always chain up to the parent class; as with dispose(), finalize()
+ * is guaranteed to exist on the parent's class virtual function table
+ */
+ G_OBJECT_CLASS (thrift_stored_message_protocol_parent_class)->finalize(gobject);
+}
+
+
+/* initialize the class */
+static void
+thrift_stored_message_protocol_class_init (ThriftStoredMessageProtocolClass *klass)
+{
+ ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ cls->read_message_begin = thrift_stored_message_protocol_read_message_begin;
+
+ object_class->set_property = thrift_stored_message_protocol_set_property;
+ object_class->get_property = thrift_stored_message_protocol_get_property;
+ object_class->finalize = thrift_stored_message_protocol_finalize;
+
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME] =
+ g_param_spec_string ("name",
+ "Service name the protocol points to",
+ "Set the service name",
+ NULL,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE] =
+ g_param_spec_int ("type",
+ "Message type in the wire",
+ "Set the message type in the wire",
+ T_CALL, T_ONEWAY,
+ T_CALL,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID] =
+ g_param_spec_int ("seqid",
+ "Sequence id type in the wire",
+ "Set the Sequence id in the wire",
+ G_MININT, G_MAXINT,
+ 0,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+ /* TODO Ugly hack, in theory we must override all properties from underlaying
+ protocol */
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT] =
+ g_param_spec_pointer ("transport",
+ "Transport on the underlaying implementation",
+ "Transport of decorated protocol",
+ G_PARAM_READABLE);
+
+
+
+ g_object_class_install_properties (object_class,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END,
+ thrift_stored_message_protocol_obj_properties);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h
new file mode 100644
index 000000000..88782ac36
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h
@@ -0,0 +1,78 @@
+/*
+ * 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_STORED_MESSAGE_PROTOCOL_H
+#define _THRIFT_STORED_MESSAGE_PROTOCOL_H
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_stored_message_protocol.h
+ * \brief StoredMessage protocol implementation of a pre-stored message header
+ * on Thrift protocol. Implements the ThriftProtocol interface.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_STORED_MESSAGE_PROTOCOL (thrift_stored_message_protocol_get_type ())
+#define THRIFT_STORED_MESSAGE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocol))
+#define THRIFT_IS_STORED_MESSAGE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL))
+#define THRIFT_STORED_MESSAGE_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocolClass))
+#define THRIFT_IS_STORED_MESSAGE_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL))
+#define THRIFT_STORED_MESSAGE_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocolClass))
+
+/* constant */
+#define THRIFT_STORED_MESSAGE_PROTOCOL_DEFAULT_SEPARATOR ":"
+
+typedef struct _ThriftStoredMessageProtocol ThriftStoredMessageProtocol;
+
+
+
+/*!
+ * Thrift StoredMessage Protocol instance.
+ */
+struct _ThriftStoredMessageProtocol
+{
+ ThriftProtocolDecorator parent;
+
+ gchar *name;
+ ThriftMessageType mtype;
+ gint32 seqid;
+};
+
+typedef struct _ThriftStoredMessageProtocolClass ThriftStoredMessageProtocolClass;
+
+/*!
+ * Thrift StoredMessage Protocol class.
+ */
+struct _ThriftStoredMessageProtocolClass
+{
+ ThriftProtocolDecoratorClass parent;
+};
+
+/* used by THRIFT_TYPE_STORED_MESSAGE_PROTOCOL */
+GType thrift_stored_message_protocol_get_type (void);
+
+G_END_DECLS
+
+#endif /* _THRIFT_STORED_MESSAGE_PROTOCOL_H */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.c
new file mode 100644
index 000000000..ccf9153db
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.c
@@ -0,0 +1,195 @@
+/*
+ * 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_dup_object (value);
+ break;
+ case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
+ server->server_transport = g_value_dup_object (value);
+ break;
+ case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
+ server->input_transport_factory = g_value_dup_object (value);
+ break;
+ case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
+ server->output_transport_factory = g_value_dup_object (value);
+ break;
+ case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
+ server->input_protocol_factory = g_value_dup_object (value);
+ break;
+ case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
+ server->output_protocol_factory = g_value_dup_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;
+}
+
+static void
+thrift_server_dispose (GObject *gobject)
+{
+ ThriftServer *self = THRIFT_SERVER (gobject);
+
+ g_clear_object(&self->output_protocol_factory);
+ g_clear_object(&self->input_protocol_factory);
+ g_clear_object(&self->output_transport_factory);
+ g_clear_object(&self->input_transport_factory);
+ g_clear_object(&self->server_transport);
+ g_clear_object(&self->processor);
+
+ /* Always chain up to the parent class; there is no need to check if
+ * the parent class implements the dispose() virtual function: it is
+ * always guaranteed to do so
+ */
+ G_OBJECT_CLASS (thrift_server_parent_class)->dispose(gobject);
+}
+
+/*
+ * 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;
+ gobject_class->dispose = thrift_server_dispose;
+
+ 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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.h
new file mode 100644
index 000000000..49beddcbe
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_server.h
@@ -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 */
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.c
new file mode 100644
index 000000000..22a96c7a4
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.c
@@ -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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.h
new file mode 100644
index 000000000..86b538b48
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.h
@@ -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 */
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.c
new file mode 100644
index 000000000..8de869f79
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.h
new file mode 100644
index 000000000..94a647831
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c
new file mode 100644
index 000000000..1234caef9
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.h
new file mode 100644
index 000000000..733f793cb
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_application_exception.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.c
new file mode 100644
index 000000000..f24f2a1c8
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.h
new file mode 100644
index 000000000..f4cfcb2c4
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/thrift_struct.h
@@ -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
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c
new file mode 100644
index 000000000..0ab3e9329
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c
@@ -0,0 +1,390 @@
+/*
+ * 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 <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 */
+ g_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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h
new file mode 100644
index 000000000..837f46770
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h
@@ -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
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.c
new file mode 100644
index 000000000..86050b691
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.c
@@ -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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.h
new file mode 100644
index 000000000..d43f4e4ad
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.c
new file mode 100644
index 000000000..14abff7a4
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.c
@@ -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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.h
new file mode 100644
index 000000000..0e6d5c4b3
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c
new file mode 100644
index 000000000..c54824635
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c
@@ -0,0 +1,383 @@
+/*
+ * 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 <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 */
+ g_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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h
new file mode 100644
index 000000000..95c012393
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h
@@ -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
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.c
new file mode 100644
index 000000000..e68fe0a24
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.c
@@ -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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.h
new file mode 100644
index 000000000..c3e94962f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c
new file mode 100644
index 000000000..91818e91a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c
@@ -0,0 +1,285 @@
+/*
+ * 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 <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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h
new file mode 100644
index 000000000..d5d47b390
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h
@@ -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
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h
new file mode 100644
index 000000000..ede60f172
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+/* clang-format off */
+
+#ifndef _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_
+# define _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_
+
+#ifdef _WIN32
+# define THRIFT_GET_SOCKET_ERROR ::WSAGetLastError()
+# define THRIFT_ERRNO (*_errno())
+# define THRIFT_EINPROGRESS WSAEINPROGRESS
+# define THRIFT_EAGAIN WSAEWOULDBLOCK
+# define THRIFT_EINTR WSAEINTR
+# define THRIFT_ECONNRESET WSAECONNRESET
+# define THRIFT_ENOTCONN WSAENOTCONN
+# define THRIFT_ETIMEDOUT WSAETIMEDOUT
+# define THRIFT_EWOULDBLOCK WSAEWOULDBLOCK
+# define THRIFT_EPIPE WSAECONNRESET
+# define THRIFT_NO_SOCKET_CACHING SO_EXCLUSIVEADDRUSE
+# define THRIFT_INVALID_SOCKET INVALID_SOCKET
+# define THRIFT_SOCKETPAIR thrift_socketpair
+# define THRIFT_FCNTL thrift_fcntl
+# define THRIFT_O_NONBLOCK 1
+# define THRIFT_F_GETFL 0
+# define THRIFT_F_SETFL 1
+# define THRIFT_GETTIMEOFDAY thrift_gettimeofday
+# define THRIFT_CLOSESOCKET closesocket
+# define THRIFT_CLOSE _close
+# define THRIFT_OPEN _open
+# define THRIFT_FTRUNCATE _chsize_s
+# define THRIFT_FSYNC _commit
+# define THRIFT_LSEEK _lseek
+# define THRIFT_WRITE _write
+# define THRIFT_READ _read
+# define THRIFT_FSTAT _fstat
+# define THRIFT_STAT _stat
+# ifdef _WIN32_WCE
+# define THRIFT_GAI_STRERROR(...) thrift_wstr2str(gai_strerrorW(__VA_ARGS__))
+# else
+# define THRIFT_GAI_STRERROR gai_strerrorA
+# endif
+# define THRIFT_SSIZET ptrdiff_t
+# define THRIFT_SNPRINTF _snprintf
+# define THRIFT_SLEEP_SEC thrift_sleep
+# define THRIFT_SLEEP_USEC thrift_usleep
+# define THRIFT_TIMESPEC thrift_timespec
+# define THRIFT_CTIME_R thrift_ctime_r
+# define THRIFT_POLL thrift_poll
+# if WINVER <= 0x0502 /* XP, Server2003 */
+# define THRIFT_POLLFD thrift_pollfd
+# define THRIFT_POLLIN 0x0300
+# define THRIFT_POLLOUT 0x0010
+# else /* Vista, Win7... */
+# define THRIFT_POLLFD pollfd
+# define THRIFT_POLLIN POLLIN
+# define THRIFT_POLLOUT POLLOUT
+# endif /* WINVER */
+# define THRIFT_SHUT_RDWR SD_BOTH
+#else /* not _WIN32 */
+# include <errno.h>
+# define THRIFT_GET_SOCKET_ERROR errno
+# define THRIFT_ERRNO errno
+# define THRIFT_EINTR EINTR
+# define THRIFT_EINPROGRESS EINPROGRESS
+# define THRIFT_ECONNRESET ECONNRESET
+# define THRIFT_ENOTCONN ENOTCONN
+# define THRIFT_ETIMEDOUT ETIMEDOUT
+# define THRIFT_EWOULDBLOCK EWOULDBLOCK
+# define THRIFT_EAGAIN EAGAIN
+# define THRIFT_EPIPE EPIPE
+# define THRIFT_NO_SOCKET_CACHING SO_REUSEADDR
+# define THRIFT_INVALID_SOCKET (-1)
+# define THRIFT_SOCKETPAIR socketpair
+# define THRIFT_FCNTL fcntl
+# define THRIFT_O_NONBLOCK O_NONBLOCK
+# define THRIFT_F_GETFL F_GETFL
+# define THRIFT_F_SETFL F_SETFL
+# define THRIFT_GETTIMEOFDAY gettimeofday
+# define THRIFT_CLOSESOCKET close
+# define THRIFT_CLOSE close
+# define THRIFT_OPEN open
+# define THRIFT_FTRUNCATE ftruncate
+# define THRIFT_FSYNC fsync
+# define THRIFT_LSEEK lseek
+# define THRIFT_WRITE write
+# define THRIFT_READ read
+# define THRIFT_STAT stat
+# define THRIFT_FSTAT fstat
+# define THRIFT_GAI_STRERROR gai_strerror
+# define THRIFT_SSIZET ssize_t
+# define THRIFT_SNPRINTF snprintf
+# define THRIFT_SLEEP_SEC sleep
+# define THRIFT_SLEEP_USEC usleep
+# define THRIFT_TIMESPEC timespec
+# define THRIFT_CTIME_R ctime_r
+# define THRIFT_POLL poll
+# define THRIFT_POLLFD pollfd
+# define THRIFT_POLLIN POLLIN
+# define THRIFT_POLLOUT POLLOUT
+# define THRIFT_SHUT_RDWR SHUT_RDWR
+#endif
+
+#endif /* _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
new file mode 100644
index 000000000..21ce1eee0
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
@@ -0,0 +1,307 @@
+/*
+ * 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 <sys/un.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_PATH,
+ 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() */
+ ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
+
+ const int socket_domain = tsocket->path ? PF_UNIX : AF_INET;
+
+ /* create a socket */
+ if ((tsocket->sd = socket (socket_domain, 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 (tsocket->path)
+ {
+ /* create a socket structure */
+ struct sockaddr_un pin;
+ memset (&pin, 0, sizeof(pin));
+ pin.sun_family = AF_UNIX;
+ memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1);
+
+ 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 path %s: - %s",
+ tsocket->path, strerror(errno));
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* create a address structure */
+ struct sockaddr_in pin;
+ memset (&pin, 0, sizeof(pin));
+ pin.sin_family = AF_INET;
+ pin.sin_addr.s_addr = INADDR_ANY;
+ pin.sin_port = htons(tsocket->port);
+
+ 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)
+ {
+ if (tsocket->path)
+ {
+ g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+ THRIFT_SERVER_SOCKET_ERROR_BIND,
+ "failed to bind to path %s: - %s",
+ tsocket->path, strerror(errno));
+ return FALSE;
+ }
+ else
+ {
+ 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_PATH:
+ g_value_set_string (value, socket->path);
+ 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_PATH:
+ if (socket->path) {
+ g_free(socket->path);
+ }
+ socket->path = g_strdup (g_value_get_string (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 */
+ 65535, /* 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_string ("path",
+ "path (construct)",
+ "Set the path to listen to",
+ NULL, /* default value */
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class,
+ PROP_THRIFT_SERVER_SOCKET_PATH,
+ 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;
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h
new file mode 100644
index 000000000..7710d5161
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h
@@ -0,0 +1,91 @@
+/*
+ * 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 */
+ guint port;
+ gchar *path;
+ 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
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.c
new file mode 100644
index 000000000..c25d1384f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.h
new file mode 100644
index 000000000..98a9191bd
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
new file mode 100644
index 000000000..b7b413910
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
@@ -0,0 +1,427 @@
+/*
+ * 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 <sys/un.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,
+ PROP_THRIFT_SOCKET_PATH
+};
+
+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_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_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);
+
+ if (tsocket->path) {
+ /* create a socket structure */
+ struct sockaddr_un pin;
+ memset (&pin, 0, sizeof(pin));
+ pin.sun_family = AF_UNIX;
+ memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1);
+
+ /* create the socket */
+ if ((tsocket->sd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
+ {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET,
+ "failed to create socket for path %s: - %s",
+ tsocket->path,
+ strerror(errno));
+ return FALSE;
+ }
+
+ /* open a connection */
+ if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+ {
+ thrift_socket_close(tsocket, NULL);
+ g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
+ "failed to connect to path %s: - %s",
+ tsocket->path, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* 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_list[0]))->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)
+ {
+ thrift_socket_close(transport, NULL);
+ 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_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->path != NULL)
+ {
+ g_free (socket->path);
+ }
+
+ 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;
+ case PROP_THRIFT_SOCKET_PATH:
+ g_value_set_string (value, socket->path);
+ 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:
+ if (socket->hostname) {
+ g_free(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;
+ case PROP_THRIFT_SOCKET_PATH:
+ if (socket->path) {
+ g_free(socket->path);
+ }
+ socket->path = g_strdup (g_value_get_string (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",
+ 0u, /* min */
+ 65535u, /* 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);
+
+ param_spec = g_param_spec_string ("path",
+ "path (construct)",
+ "Set the path of the remote host",
+ NULL, /* default value */
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PATH,
+ 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;
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
new file mode 100644
index 000000000..c91f52f18
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
@@ -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_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;
+ guint port;
+ gchar *path;
+ int sd;
+};
+
+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
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
new file mode 100644
index 000000000..df17fa6ee
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
@@ -0,0 +1,804 @@
+/*
+ * 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 <openssl/ssl.h>
+#include <pthread.h>
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/transport/thrift_socket.h>
+#include <thrift/c_glib/transport/thrift_ssl_socket.h>
+
+
+#if defined(WIN32)
+#define MUTEX_TYPE HANDLE
+#define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
+#define MUTEX_CLEANUP(x) CloseHandle(x)
+#define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
+#define MUTEX_UNLOCK(x) ReleaseMutex(x)
+#else
+#define MUTEX_TYPE pthread_mutex_t
+#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
+#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
+#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
+#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
+#endif
+
+#define OPENSSL_VERSION_NO_THREAD_ID 0x10000000L
+
+
+/* object properties */
+enum _ThriftSSLSocketProperties
+{
+ PROP_THRIFT_SSL_SOCKET_CONTEXT = 3,
+ PROP_THRIFT_SSL_SELF_SIGNED
+};
+
+/* To hold a global state management of openssl for all instances */
+static gboolean thrift_ssl_socket_openssl_initialized=FALSE;
+/* This array will store all of the mutexes available to OpenSSL. */
+static MUTEX_TYPE *thrift_ssl_socket_global_mutex_buf=NULL;
+
+
+/**
+ * OpenSSL uniq id function.
+ *
+ * @return thread id
+ */
+static unsigned long thrift_ssl_socket_static_id_function(void)
+{
+#if defined(WIN32)
+ return GetCurrentThreadId();
+#else
+ return ((unsigned long) pthread_self());
+#endif
+}
+
+static void thrift_ssl_socket_static_locking_callback(int mode, int n, const char* unk, int id) {
+ if (mode & CRYPTO_LOCK)
+ MUTEX_LOCK(thrift_ssl_socket_global_mutex_buf[n]);
+ else
+ MUTEX_UNLOCK(thrift_ssl_socket_global_mutex_buf[n]);
+}
+
+static int thrift_ssl_socket_static_thread_setup(void)
+{
+ int i;
+
+ thrift_ssl_socket_global_mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
+ if (!thrift_ssl_socket_global_mutex_buf)
+ return 0;
+ for (i = 0; i < CRYPTO_num_locks( ); i++)
+ MUTEX_SETUP(thrift_ssl_socket_global_mutex_buf[i]);
+ CRYPTO_set_id_callback(thrift_ssl_socket_static_id_function);
+ CRYPTO_set_locking_callback(thrift_ssl_socket_static_locking_callback);
+ return 1;
+}
+
+static int thrift_ssl_socket_static_thread_cleanup(void)
+{
+ int i;
+ if (!thrift_ssl_socket_global_mutex_buf)
+ return 0;
+ CRYPTO_set_id_callback(NULL);
+ CRYPTO_set_locking_callback(NULL);
+ for (i = 0; i < CRYPTO_num_locks( ); i++)
+ MUTEX_CLEANUP(thrift_ssl_socket_global_mutex_buf[i]);
+ free(thrift_ssl_socket_global_mutex_buf);
+ thrift_ssl_socket_global_mutex_buf = NULL;
+ return 1;
+}
+
+/*
+static void* thrift_ssl_socket_dyn_lock_create_callback(const char* unk, int id) {
+ g_print("We should create a lock\n");
+ return NULL;
+}
+
+static void thrift_ssl_socket_dyn_lock_callback(int mode, void* lock, const char* unk, int id) {
+ if (lock != NULL) {
+ if (mode & CRYPTO_LOCK) {
+ g_printf("We should lock thread %d\n");
+ } else {
+ g_printf("We should unlock thread %d\n");
+ }
+ }
+}
+
+static void thrift_ssl_socket_dyn_lock_destroy_callback(void* lock, const char* unk, int id) {
+ g_printf("We must destroy the lock\n");
+}
+ */
+
+
+G_DEFINE_TYPE(ThriftSSLSocket, thrift_ssl_socket, THRIFT_TYPE_SOCKET)
+
+
+
+/**
+ * When there's a thread context attached, we pass the SSL socket context so it
+ * can check if the error is outside SSL, on I/O for example
+ * @param socket
+ * @param error_msg
+ * @param thrift_error_no
+ * @param ssl_error
+ * @param error
+ */
+static
+void thrift_ssl_socket_get_ssl_error(ThriftSSLSocket *socket, const guchar *error_msg, guint thrift_error_no, int ssl_error, GError **error)
+{
+ unsigned long error_code;
+ char buffer[1024];
+ int buffer_size=1024;
+ gboolean first_error = TRUE;
+ int ssl_error_type = SSL_get_error(socket->ssl, ssl_error);
+ if(ssl_error_type>0){
+ switch(ssl_error_type){
+ case SSL_ERROR_SSL:
+ buffer_size-=snprintf(buffer, buffer_size, "SSL %s: ", error_msg);
+ while ((error_code = ERR_get_error()) != 0 && buffer_size>1) {
+ const char* reason = ERR_reason_error_string(error_code);
+ if(reason!=NULL){
+ if(!first_error) {
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "\n\t");
+ first_error=FALSE;
+ }
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX(%s) -> %s", error_code, reason, SSL_state_string(socket->ssl));
+ }
+ }
+ break;
+ case SSL_ERROR_SYSCALL:
+ buffer_size-=snprintf(buffer, buffer_size, "%s: ", error_msg);
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX -> %s", errno, strerror(errno));
+ break;
+ case SSL_ERROR_WANT_READ:
+ buffer_size-=snprintf(buffer, buffer_size, "%s: ", error_msg);
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX -> %s", ssl_error_type, "Error while reading from underlaying layer");
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ buffer_size-=snprintf(buffer, buffer_size, "%s: ", error_msg);
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX -> %s", ssl_error_type, "Error while writting to underlaying layer");
+ break;
+
+ }
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ thrift_error_no, "%s", buffer);
+ }
+}
+
+/**
+ * For global SSL errors
+ * @param error_msg
+ * @param thrift_error_no
+ * @param error
+ */
+static
+void thrift_ssl_socket_get_error(const guchar *error_msg, guint thrift_error_no, GError **error)
+{
+ unsigned long error_code;
+ while ((error_code = ERR_get_error()) != 0) {
+ const char* reason = ERR_reason_error_string(error_code);
+ if (reason == NULL) {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ thrift_error_no,
+ "SSL error %lX: %s", error_code, error_msg);
+ }else{
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ thrift_error_no,
+ "SSL error %lX %s: %s", error_code,reason, error_msg);
+ }
+ }
+}
+
+
+
+/* implements thrift_transport_is_open */
+gboolean
+thrift_ssl_socket_is_open (ThriftTransport *transport)
+{
+ return thrift_socket_is_open(transport);
+}
+
+/* overrides thrift_transport_peek */
+gboolean
+thrift_ssl_socket_peek (ThriftTransport *transport, GError **error)
+{
+ gboolean retval = FALSE;
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
+ if (thrift_ssl_socket_is_open (transport))
+ {
+ int rc;
+ gchar byte;
+ rc = SSL_peek(ssl_socket->ssl, &byte, 1);
+ if (rc < 0) {
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Check socket data",
+ THRIFT_SSL_SOCKET_ERROR_SSL, rc, error);
+ }
+ if (rc == 0) {
+ ERR_clear_error();
+ }
+ retval = (rc > 0);
+ }
+ return retval;
+}
+
+/* implements thrift_transport_open */
+gboolean
+thrift_ssl_socket_open (ThriftTransport *transport, GError **error)
+{
+ ERR_clear_error();
+
+ if (!thrift_socket_open(transport, error)) {
+ return FALSE;
+ }
+
+ if (!THRIFT_SSL_SOCKET_GET_CLASS(transport)->handle_handshake(transport, error)) {
+ thrift_ssl_socket_close(transport, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* implements thrift_transport_close */
+gboolean
+thrift_ssl_socket_close (ThriftTransport *transport, GError **error)
+{
+ gboolean retval = FALSE;
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET(transport);
+ if(ssl_socket!=NULL && ssl_socket->ssl) {
+ int rc = SSL_shutdown(ssl_socket->ssl);
+/* if (rc < 0) {
+ int errno_copy = THRIFT_SSL_SOCKET_ERROR_SSL;
+ }*/
+ SSL_free(ssl_socket->ssl);
+ ssl_socket->ssl = NULL;
+ ERR_remove_state(0);
+ }
+ return thrift_socket_close(transport, error);
+}
+
+/* implements thrift_transport_read */
+gint32
+thrift_ssl_socket_read (ThriftTransport *transport, gpointer buf,
+ guint32 len, GError **error)
+{
+ guint maxRecvRetries_ = 10;
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
+ guint bytes = 0;
+ guint retries = 0;
+ ThriftSocket *socket = THRIFT_SOCKET (transport);
+ g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
+
+ for (retries=0; retries < maxRecvRetries_; retries++) {
+ bytes = SSL_read(ssl_socket->ssl, buf, len);
+ if (bytes >= 0)
+ break;
+ int errno_copy = THRIFT_GET_SOCKET_ERROR;
+ if (SSL_get_error(ssl_socket->ssl, bytes) == SSL_ERROR_SYSCALL) {
+ if (ERR_get_error() == 0 && errno_copy == THRIFT_EINTR) {
+ continue;
+ }
+ }else{
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Receive error",
+ THRIFT_SSL_SOCKET_ERROR_SSL, bytes, error);
+
+ }
+ return -1;
+ }
+ return bytes;
+}
+
+/* implements thrift_transport_read_end
+ * called when write is complete. nothing to do on our end. */
+gboolean
+thrift_ssl_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_ssl_socket_write (ThriftTransport *transport, const gpointer buf,
+ const guint32 len, GError **error)
+{
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
+ gint ret = 0;
+ guint sent = 0;
+ ThriftSocket *socket = THRIFT_SOCKET (transport);
+ g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
+
+ while (sent < len)
+ {
+ ret = SSL_write (ssl_socket->ssl, (guint8 *)buf + sent, len - sent);
+ if (ret < 0)
+ {
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Send error",
+ THRIFT_SSL_SOCKET_ERROR_SSL, ret, error);
+ return FALSE;
+ }
+ sent += ret;
+ }
+
+ return sent==len;
+}
+
+/* implements thrift_transport_write_end
+ * called when write is complete. nothing to do on our end. */
+gboolean
+thrift_ssl_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_ssl_socket_flush (ThriftTransport *transport, GError **error)
+{
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
+
+ ThriftSocket *socket = THRIFT_SOCKET (transport);
+ g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
+
+ BIO* bio = SSL_get_wbio(ssl_socket->ssl);
+ if (bio == NULL) {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ THRIFT_TRANSPORT_ERROR_SEND,
+ "failed to flush, wbio returned null");
+ return FALSE;
+ }
+ if (BIO_flush(bio) != 1) {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ THRIFT_TRANSPORT_ERROR_SEND,
+ "failed to flush it returned error");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+gboolean
+thrift_ssl_socket_handle_handshake(ThriftTransport * transport, GError **error)
+{
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
+ ThriftSocket *socket = THRIFT_SOCKET (transport);
+ g_return_val_if_fail (thrift_transport_is_open (transport), FALSE);
+
+ if(THRIFT_SSL_SOCKET_GET_CLASS(ssl_socket)->create_ssl_context(transport, error)){
+ /*Context created*/
+ SSL_set_fd(ssl_socket->ssl, socket->sd);
+ int rc;
+ if(ssl_socket->server){
+ rc = SSL_accept(ssl_socket->ssl);
+ }else{
+ rc = SSL_connect(ssl_socket->ssl);
+ }
+ if (rc <= 0) {
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Error while connect/bind", THRIFT_SSL_SOCKET_ERROR_CONNECT_BIND, rc, error);
+ return FALSE;
+ }
+ }else
+ return FALSE;
+
+ return thrift_ssl_socket_authorize(transport, error);
+}
+
+gboolean
+thrift_ssl_socket_create_ssl_context(ThriftTransport * transport, GError **error)
+{
+ ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (transport);
+
+ if(socket->ctx!=NULL){
+ if(socket->ssl!=NULL) {
+ return TRUE;
+ }
+
+ socket->ssl = SSL_new(socket->ctx);
+ if (socket->ssl == NULL) {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ THRIFT_SSL_SOCKET_ERROR_TRANSPORT,
+ "Unable to create default SSL context");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+gboolean thrift_ssl_load_cert_from_file(ThriftSSLSocket *ssl_socket, const char *file_name)
+{
+ char error_buffer[255];
+ if (!thrift_ssl_socket_openssl_initialized) {
+ g_error("OpenSSL is not initialized yet");
+ return FALSE;
+ }
+ int rc = SSL_CTX_load_verify_locations(ssl_socket->ctx, file_name, NULL);
+ if (rc != 1) { /*verify authentication result*/
+ ERR_error_string_n(ERR_get_error(), error_buffer, 254);
+ g_warning("Load of certificates failed: %s!", error_buffer);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+gboolean thrift_ssl_load_cert_from_buffer(ThriftSSLSocket *ssl_socket, const char chain_certs[])
+{
+ gboolean retval = FALSE;
+ /* Load chain of certs*/
+ X509 *cacert=NULL;
+ BIO *mem = BIO_new_mem_buf(chain_certs,strlen(chain_certs));
+ X509_STORE *cert_store = SSL_CTX_get_cert_store(ssl_socket->ctx);
+
+ if(cert_store!=NULL){
+ int index = 0;
+ while ((cacert = PEM_read_bio_X509(mem, NULL, 0, NULL))!=NULL) {
+ if(cacert) {
+ X509_STORE_add_cert(cert_store, cacert);
+ X509_free(cacert);
+ cacert=NULL;
+ } /* Free immediately */
+ index++;
+ }
+ retval=TRUE;
+ }
+ BIO_free(mem);
+ return retval;
+}
+
+gboolean
+thrift_ssl_socket_authorize(ThriftTransport * transport, GError **error)
+{
+ ThriftSocket *socket = THRIFT_SOCKET (transport);
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
+ ThriftSSLSocketClass *cls = THRIFT_SSL_SOCKET_GET_CLASS(ssl_socket);
+ gboolean authorization_result = FALSE;
+
+ if(cls!=NULL && ssl_socket->ssl!=NULL){
+ int rc = SSL_get_verify_result(ssl_socket->ssl);
+ if (rc != X509_V_OK) { /* verify authentication result */
+ if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && ssl_socket->allow_selfsigned) {
+ g_debug("The certificate is a self-signed certificate and configuration allows it");
+ } else {
+ g_set_error (error,
+ THRIFT_TRANSPORT_ERROR,
+ THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED,
+ "The certificate verification failed: %s (%d)", X509_verify_cert_error_string(rc), rc);
+ return FALSE;
+ }
+ }
+
+ X509* cert = SSL_get_peer_certificate(ssl_socket->ssl);
+ if (cert == NULL) {
+ if (SSL_get_verify_mode(ssl_socket->ssl) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
+ g_set_error (error,
+ THRIFT_TRANSPORT_ERROR,
+ THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED,
+ "No certificate present. Are you connecting SSL server?");
+ return FALSE;
+ }
+ g_debug("No certificate required");
+ return TRUE;
+ }
+
+ /* certificate is present, since we don't support access manager we are done */
+ if (cls->authorize_peer == NULL) {
+ X509_free(cert);
+ g_debug("Certificate presented but we're not checking it");
+ return TRUE;
+ } else {
+ /* both certificate and access manager are present */
+ struct sockaddr_storage sa;
+ socklen_t saLength = sizeof(struct sockaddr_storage);
+ if (getpeername(socket->sd, (struct sockaddr*)&sa, &saLength) != 0) {
+ sa.ss_family = AF_UNSPEC;
+ }
+ authorization_result = cls->authorize_peer(transport, cert, &sa, error);
+ }
+ if(cert != NULL) {
+ X509_free(cert);
+ }
+ }
+
+ return authorization_result;
+}
+
+
+/* initializes the instance */
+static void
+thrift_ssl_socket_init (ThriftSSLSocket *socket)
+{
+ GError *error = NULL;
+ socket->ssl = NULL;
+ socket->ctx = thrift_ssl_socket_context_initialize(SSLTLS, &error);
+ if(socket->ctx == NULL) {
+ g_info("The SSL context was not automatically initialized with protocol %d", SSLTLS);
+ if(error!=NULL){
+ g_info("Reported reason %s", error->message);
+ g_error_free (error);
+ }
+ }
+ socket->server = FALSE;
+ socket->allow_selfsigned = FALSE;
+
+}
+
+/* destructor */
+static void
+thrift_ssl_socket_finalize (GObject *object)
+{
+ ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (object);
+ GError *error=NULL;
+ if(socket!=NULL){
+ g_debug("Instance %p destroyed", (void *)socket);
+ if(socket->ssl != NULL)
+ {
+ thrift_ssl_socket_close(THRIFT_TRANSPORT(object), &error);
+ socket->ssl=NULL;
+ }
+
+ if(socket->ctx!=NULL){
+ g_debug("Freeing the context for the instance");
+ SSL_CTX_free(socket->ctx);
+ socket->ctx=NULL;
+ }
+ }
+
+ if (G_OBJECT_CLASS (thrift_ssl_socket_parent_class)->finalize)
+ (*G_OBJECT_CLASS (thrift_ssl_socket_parent_class)->finalize) (object);
+}
+
+/* property accessor */
+void
+thrift_ssl_socket_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (object);
+ THRIFT_UNUSED_VAR (pspec);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_SSL_SOCKET_CONTEXT:
+ g_value_set_pointer (value, socket->ctx);
+ break;
+ }
+}
+
+/* property mutator */
+void
+thrift_ssl_socket_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (object);
+
+ THRIFT_UNUSED_VAR (pspec);
+ switch (property_id)
+ {
+ case PROP_THRIFT_SSL_SOCKET_CONTEXT:
+ if(socket->ctx!=NULL){
+ g_debug("Freeing the context since we are setting a new one");
+ SSL_CTX_free(socket->ctx);
+ }
+ socket->ctx = g_value_get_pointer(value); /* We copy the context */
+ break;
+
+ case PROP_THRIFT_SSL_SELF_SIGNED:
+ socket->allow_selfsigned = g_value_get_boolean(value);
+ break;
+ default:
+ g_warning("Trying to set property %i that doesn't exists!", property_id);
+ /* thrift_socket_set_property(object, property_id, value, pspec); */
+ break;
+ }
+}
+
+void
+thrift_ssl_socket_initialize_openssl(void)
+{
+ if(thrift_ssl_socket_openssl_initialized){
+ return;
+ }
+ thrift_ssl_socket_openssl_initialized=TRUE;
+ SSL_library_init();
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ ERR_load_BIO_strings();
+
+ /* Setup locking */
+ g_debug("We setup %d threads locks", thrift_ssl_socket_static_thread_setup());
+
+ /* dynamic locking
+ CRYPTO_set_dynlock_create_callback(thrift_ssl_socket_dyn_lock_create_callback);
+ CRYPTO_set_dynlock_lock_callback(thrift_ssl_socket_dyn_lock_callback);
+ CRYPTO_set_dynlock_destroy_callback(thrift_ssl_socket_dyn_lock_destroy_callback);
+ */
+}
+
+
+void thrift_ssl_socket_finalize_openssl(void)
+{
+ if (!thrift_ssl_socket_openssl_initialized) {
+ return;
+ }
+ thrift_ssl_socket_openssl_initialized = FALSE;
+
+ g_debug("We cleared %d threads locks", thrift_ssl_socket_static_thread_cleanup());
+ /* Not supported
+ CRYPTO_set_locking_callback(NULL);
+ CRYPTO_set_dynlock_create_callback(NULL);
+ CRYPTO_set_dynlock_lock_callback(NULL);
+ CRYPTO_set_dynlock_destroy_callback(NULL);
+ */
+ ERR_free_strings();
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_state(0);
+}
+
+
+/* initializes the class */
+static void
+thrift_ssl_socket_class_init (ThriftSSLSocketClass *cls)
+{
+ ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+ GParamSpec *param_spec = NULL;
+
+ g_debug("Initialization of ThriftSSLSocketClass");
+ /* setup accessors and mutators */
+ gobject_class->get_property = thrift_ssl_socket_get_property;
+ gobject_class->set_property = thrift_ssl_socket_set_property;
+ param_spec = g_param_spec_pointer ("ssl_context",
+ "SSLContext",
+ "Set the SSL context for handshake with the remote host",
+ G_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SOCKET_CONTEXT,
+ param_spec);
+ param_spec = g_param_spec_boolean ("ssl_accept_selfsigned",
+ "Accept Self Signed",
+ "Whether or not accept self signed certificate",
+ FALSE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SELF_SIGNED,
+ param_spec);
+ /* Class methods */
+ cls->handle_handshake = thrift_ssl_socket_handle_handshake;
+ cls->create_ssl_context = thrift_ssl_socket_create_ssl_context;
+
+ /* Override */
+ gobject_class->finalize = thrift_ssl_socket_finalize;
+ ttc->is_open = thrift_ssl_socket_is_open;
+ ttc->peek = thrift_ssl_socket_peek;
+ ttc->open = thrift_ssl_socket_open;
+ ttc->close = thrift_ssl_socket_close;
+ ttc->read = thrift_ssl_socket_read;
+ ttc->read_end = thrift_ssl_socket_read_end;
+ ttc->write = thrift_ssl_socket_write;
+ ttc->write_end = thrift_ssl_socket_write_end;
+ ttc->flush = thrift_ssl_socket_flush;
+}
+
+
+/*
+ * Public API
+ */
+ThriftSSLSocket*
+thrift_ssl_socket_new(ThriftSSLSocketProtocol ssl_protocol, GError **error)
+{
+ ThriftSSLSocket *thriftSSLSocket = NULL;
+ SSL_CTX *ssl_context = NULL;
+ /* Create the context */
+ if((ssl_context=thrift_ssl_socket_context_initialize(ssl_protocol, error))==NULL){
+ g_warning("We cannot initialize context for protocol %d", ssl_protocol);
+ return thriftSSLSocket;
+ }
+
+ /* FIXME if the protocol is different? */
+ thriftSSLSocket = g_object_new (THRIFT_TYPE_SSL_SOCKET, "ssl_context", ssl_context, NULL);
+ return thriftSSLSocket;
+}
+
+ThriftSSLSocket*
+thrift_ssl_socket_new_with_host(ThriftSSLSocketProtocol ssl_protocol, gchar *hostname, guint port, GError **error)
+{
+ ThriftSSLSocket *thriftSSLSocket = NULL;
+ SSL_CTX *ssl_context = NULL;
+ /* Create the context */
+ if((ssl_context=thrift_ssl_socket_context_initialize(ssl_protocol, error))==NULL){
+ /* FIXME Do error control */
+ return thriftSSLSocket;
+ }
+ /* FIXME if the protocol is different? */
+ thriftSSLSocket = g_object_new (THRIFT_TYPE_SSL_SOCKET, "ssl_context", ssl_context, "hostname", hostname, "port", port, NULL);
+ return thriftSSLSocket;
+}
+
+void thrift_ssl_socket_set_manager(ThriftSSLSocket *ssl_socket, AUTHORIZATION_MANAGER_CALLBACK callback)
+{
+ ThriftSSLSocketClass *sslSocketClass = THRIFT_SSL_SOCKET_GET_CLASS (ssl_socket);
+ if(sslSocketClass){
+ sslSocketClass->authorize_peer = callback;
+ }
+}
+
+
+SSL_CTX*
+thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GError **error)
+{
+ SSL_CTX* context = NULL;
+ switch(ssl_protocol){
+ case SSLTLS:
+ context = SSL_CTX_new(SSLv23_method());
+ break;
+#ifndef OPENSSL_NO_SSL3
+ case SSLv3:
+ context = SSL_CTX_new(SSLv3_method());
+ break;
+#endif
+ case TLSv1_0:
+ context = SSL_CTX_new(TLSv1_method());
+ break;
+ case TLSv1_1:
+ context = SSL_CTX_new(TLSv1_1_method());
+ break;
+ case TLSv1_2:
+ context = SSL_CTX_new(TLSv1_2_method());
+ break;
+ default:
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
+ "The SSL protocol is unknown for %d", ssl_protocol);
+ return NULL;
+ break;
+ }
+
+ if (context == NULL) {
+ thrift_ssl_socket_get_error("No cipher overlay", THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE, error);
+ return NULL;
+ }
+ SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY);
+
+ /* Disable horribly insecure SSLv2 and SSLv3 protocols but allow a handshake
+ with older clients so they get a graceful denial. */
+ if (ssl_protocol == SSLTLS) {
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv2);
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* THRIFT-3164 */
+ }
+
+ return context;
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
new file mode 100644
index 000000000..0ca465a0f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
@@ -0,0 +1,218 @@
+/*
+ * 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_SSL_SOCKET_H
+#define _THRIFT_SSL_SOCKET_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+#include <openssl/x509v3.h>
+#include <sys/socket.h>
+
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/transport/thrift_socket.h>
+#include <thrift/c_glib/transport/thrift_platform_socket.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_ssl_socket.h
+ * \brief SSL Socket implementation of a Thrift transport. Subclasses the
+ * ThriftSocket class. Based on plain openssl.
+ * In the future we should take a look to https://issues.apache.org/jira/browse/THRIFT-1016
+ */
+
+/* type macros */
+#define THRIFT_TYPE_SSL_SOCKET (thrift_ssl_socket_get_type ())
+#define THRIFT_SSL_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SSL_SOCKET, ThriftSSLSocket))
+#define THRIFT_IS_SSL_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SSL_SOCKET))
+#define THRIFT_SSL_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SSL_SOCKET, ThriftSSLSocketClass))
+#define THRIFT_IS_SSL_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SSL_SOCKET))
+#define THRIFT_SSL_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SSL_SOCKET, ThriftSSLSocketClass))
+
+
+/* define error/exception types */
+typedef enum
+{
+ THRIFT_SSL_SOCKET_ERROR_TRANSPORT=7,
+ THRIFT_SSL_SOCKET_ERROR_CONNECT_BIND,
+ THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
+ THRIFT_SSL_SOCKET_ERROR_SSL,
+ THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED
+} ThriftSSLSocketError;
+
+
+typedef struct _ThriftSSLSocket ThriftSSLSocket;
+
+/*!
+ * Thrift SSL Socket instance.
+ */
+struct _ThriftSSLSocket
+{
+ ThriftSocket parent;
+
+ /* private */
+ SSL *ssl;
+ SSL_CTX* ctx;
+ gboolean server;
+ gboolean allow_selfsigned;
+};
+
+typedef struct _ThriftSSLSocketClass ThriftSSLSocketClass;
+typedef gboolean (* AUTHORIZATION_MANAGER_CALLBACK) (ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error);
+
+/*!
+ * Thrift Socket class.
+ */
+struct _ThriftSSLSocketClass
+{
+ ThriftSocketClass parent;
+
+ gboolean (* handle_handshake) (ThriftTransport * transport, GError **error);
+ gboolean (* create_ssl_context) (ThriftTransport * transport, GError **error);
+ gboolean (* authorize_peer) (ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error);
+
+ /* Padding to allow adding up to 12 new virtual functions without
+ * breaking ABI. */
+ gpointer padding[12];
+};
+
+enum _ThriftSSLSocketProtocol {
+ SSLTLS = 0, /* Supports SSLv2 and SSLv3 handshake but only negotiates at TLSv1_0 or later. */
+/*SSLv2 = 1, HORRIBLY INSECURE! */
+ SSLv3 = 2, /* Supports SSLv3 only - also horribly insecure! */
+ TLSv1_0 = 3, /* Supports TLSv1_0 or later. */
+ TLSv1_1 = 4, /* Supports TLSv1_1 or later. */
+ TLSv1_2 = 5, /* Supports TLSv1_2 or later. */
+ LATEST = TLSv1_2
+};
+typedef enum _ThriftSSLSocketProtocol ThriftSSLSocketProtocol;
+
+
+/* Internal functions */
+SSL_CTX*
+thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GError **error);
+
+
+/* used by THRIFT_TYPE_SSL_SOCKET */
+GType thrift_ssl_socket_get_type (void);
+
+/* Public API */
+
+/**
+ * @brief Set a pinning manager instead of the default one.
+ *
+ * The pinning manager will be used during the SSL handshake to check certificate
+ * and pinning parameters.
+ *
+ * @param ssl_socket SSL Socket to operate on.
+ * @param callback function that will take the control while validating pinning
+ *
+ */
+void thrift_ssl_socket_set_manager(ThriftSSLSocket *ssl_socket, AUTHORIZATION_MANAGER_CALLBACK callback);
+
+/* This is the SSL API */
+/**
+ * Convenience function to create a new SSL context with the protocol specified
+ * and assign this new context to the created ThriftSSLSocket with specified host:port.
+ * @param ssl_protocol
+ * @param hostname
+ * @param port
+ * @param error
+ * @return
+ */
+ThriftSSLSocket*
+thrift_ssl_socket_new_with_host(ThriftSSLSocketProtocol ssl_protocol, gchar *hostname, guint port, GError **error);
+
+/**
+ * Convenience function to create a new SSL context with the protocol specified
+ * and assign this new context to the created ThriftSSLSocket.
+ * @param ssl_protocol
+ * @param error
+ * @return
+ */
+ThriftSSLSocket*
+thrift_ssl_socket_new(ThriftSSLSocketProtocol ssl_protocol, GError **error);
+
+/**
+ * Load a certificate chain from a PEM file.
+ * @param ssl_socket The ssl socket
+ * @param file_name The file name of the PEM certificate chain
+ * @return
+ */
+gboolean
+thrift_ssl_load_cert_from_file(ThriftSSLSocket *ssl_socket, const char *file_name);
+
+/**
+ * Load a certificate chain from memory
+ * @param ssl_socket the ssl socket
+ * @param chain_certs the buffer to load PEM from
+ * @return
+ */
+gboolean
+thrift_ssl_load_cert_from_buffer(ThriftSSLSocket *ssl_socket, const char chain_certs[]);
+
+/**
+ * Check if the ssl socket is open and ready to send and receive
+ * @param transport
+ * @return true if open
+ */
+gboolean
+thrift_ssl_socket_is_open (ThriftTransport *transport);
+
+
+/**
+ * Open connection if required and set the socket to be ready to send and receive
+ * @param transport
+ * @param error
+ * @return true if operation was correct
+ */
+gboolean
+thrift_ssl_socket_open (ThriftTransport *transport, GError **error);
+
+
+/**
+ * @brief Initialization function
+ *
+ * It will initialize OpenSSL function. This initialization will be done app
+ * wide. So if you want to initialize it by yourself you should not call it.
+ * But it means you must handle OpenSSL initialization and handle locking.
+ *
+ * It should be called before anything else.
+ *
+ *
+ */
+void
+thrift_ssl_socket_initialize_openssl(void);
+/**
+ * @brief Finalization function
+ *
+ * It clears all resources initialized in initialize function.
+ *
+ * It should be called after anything else.
+ *
+ *
+ */
+void
+thrift_ssl_socket_finalize_openssl(void);
+
+G_END_DECLS
+#endif
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c
new file mode 100644
index 000000000..9dd267143
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h
new file mode 100644
index 000000000..94bb6f507
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.c b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.c
new file mode 100644
index 000000000..a2025cf4b
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.c
@@ -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);
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.h b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.h
new file mode 100644
index 000000000..0e3da302e
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.h
@@ -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 */
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/CMakeLists.txt b/src/jaegertracing/thrift/lib/c_glib/test/CMakeLists.txt
new file mode 100644
index 000000000..318b57629
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/CMakeLists.txt
@@ -0,0 +1,202 @@
+#
+# 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
+ ${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_second_service_handler.c
+ ${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_second_service_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
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/ContainerTest.thrift b/src/jaegertracing/thrift/lib/c_glib/test/ContainerTest.thrift
new file mode 100644
index 000000000..a92a9a51c
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/ContainerTest.thrift
@@ -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();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/Makefile.am b/src/jaegertracing/thrift/lib/c_glib/test/Makefile.am
new file mode 100755
index 000000000..c99e0da83
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/Makefile.am
@@ -0,0 +1,324 @@
+#
+# 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 nostdinc
+
+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 -I$(top_builddir)/lib/c_glib/src/thrift
+AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) \
+ @GCOV_CFLAGS@
+AM_CXXFLAGS = $(AM_CFLAGS)
+AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LIBS) @GCOV_LDFLAGS@
+
+check_PROGRAMS = \
+ testserialization \
+ testapplicationexception \
+ testcontainertest \
+ testtransportsocket \
+ testtransportsslsocket \
+ 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
+
+
+testtransportsslsocket_SOURCES = testtransportsslsocket.c
+testtransportsslsocket_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_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
+
+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
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/glib.suppress b/src/jaegertracing/thrift/lib/c_glib/test/glib.suppress
new file mode 100644
index 000000000..0e0e9fe27
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/glib.suppress
@@ -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
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testapplicationexception.c b/src/jaegertracing/thrift/lib/c_glib/test/testapplicationexception.c
new file mode 100644
index 000000000..89e39e262
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testapplicationexception.c
@@ -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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testbinaryprotocol.c b/src/jaegertracing/thrift/lib/c_glib/test/testbinaryprotocol.c
new file mode 100755
index 000000000..14f4fb063
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testbinaryprotocol.c
@@ -0,0 +1,859 @@
+/*
+ * 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 g_assert () */
+#ifdef __GLIBC__
+#include <features.h>
+#define __NO_STRING_INLINES 1
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.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);
+ g_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);
+ g_assert (tsocket != NULL);
+ /* create a ThriftBinaryProtocol using the Transport */
+ protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
+ tsocket, NULL);
+ g_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 ();
+ g_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);
+ g_assert (thrift_transport_is_open (transport));
+
+ /* create a ThriftBinaryTransport */
+ tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
+ tsocket, NULL);
+ protocol = THRIFT_PROTOCOL (tb);
+ g_assert (protocol != NULL);
+
+ /* write a bunch of primitives */
+ g_assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_double (protocol,
+ TEST_DOUBLE, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_string (protocol,
+ TEST_STRING, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0);
+ g_assert (thrift_binary_protocol_write_binary (protocol, binary,
+ len, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_binary (protocol, binary,
+ len, NULL) > 0);
+
+ /* test write errors */
+ transport_write_error = 1;
+ g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE,
+ NULL) == -1);
+ g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) == -1);
+ g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) == -1);
+ g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) == -1);
+ g_assert (thrift_binary_protocol_write_double (protocol, TEST_DOUBLE,
+ NULL) == -1);
+ g_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;
+ g_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);
+ g_assert (wait (&status) == pid);
+ g_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 ();
+ g_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);
+ g_assert (thrift_transport_is_open (transport));
+
+ /* create a ThriftBinaryTransport */
+ tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
+ tsocket, NULL);
+ protocol = THRIFT_PROTOCOL (tb);
+ g_assert (protocol != NULL);
+
+ /* test structures */
+ g_assert (thrift_binary_protocol_write_struct_begin (protocol,
+ NULL, NULL) == 0);
+ g_assert (thrift_binary_protocol_write_struct_end (protocol, NULL) == 0);
+
+ g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
+ 1, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_field_end (protocol, NULL) == 0);
+
+ /* test write error */
+ transport_write_error = 1;
+ g_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;
+ g_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 */
+ g_assert (thrift_binary_protocol_write_field_stop (protocol, NULL) > 0);
+
+ /* write a map */
+ g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
+ 1, NULL) > 0);
+ g_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;
+ g_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;
+ g_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;
+ g_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 */
+ g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
+ 1, NULL) > 0);
+ g_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;
+ g_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;
+ g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
+ 1, NULL) == -1);
+ transport_write_error_at = -1;
+
+ /* test set operation s*/
+ g_assert (thrift_binary_protocol_write_set_begin (protocol, T_VOID,
+ 1, NULL) > 0);
+ g_assert (thrift_binary_protocol_write_set_end (protocol, NULL) == 0);
+
+ /* invalid version */
+ g_assert (thrift_binary_protocol_write_i32 (protocol, -1, NULL) > 0);
+
+ /* sz > 0 for a message */
+ g_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 */
+ g_assert (thrift_binary_protocol_write_message_begin (protocol, "test",
+ T_CALL, 1, NULL) > 0);
+
+ g_assert (thrift_binary_protocol_write_message_end (protocol, NULL) == 0);
+
+ /* send broken writes */
+ transport_write_error = 1;
+ g_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;
+ g_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;
+ g_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);
+ g_assert (wait (&status) == pid);
+ g_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 ();
+ g_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);
+ g_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);
+ g_assert (ft != NULL);
+ transport = THRIFT_TRANSPORT (ft);
+
+ thrift_transport_open (transport, NULL);
+ g_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);
+ g_assert (protocol != NULL);
+
+ /* write a bunch of primitives */
+ g_assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_double (protocol,
+ TEST_DOUBLE, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_string (protocol,
+ TEST_STRING, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_binary (protocol, binary,
+ len, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_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);
+ g_assert (wait (&status) == pid);
+ g_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;
+ gchar *empty_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);
+ g_assert (client != NULL);
+
+ tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
+ client, NULL);
+ protocol = THRIFT_PROTOCOL (tbp);
+
+ g_assert (thrift_binary_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_double (protocol,
+ &value_double, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
+ g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+
+ g_assert (value_boolean == TEST_BOOL);
+ g_assert (value_byte == TEST_BYTE);
+ g_assert (value_16 == TEST_I16);
+ g_assert (value_32 == TEST_I32);
+ g_assert (value_64 == TEST_I64);
+ g_assert (value_double == TEST_DOUBLE);
+ g_assert (strcmp (TEST_STRING, string) == 0);
+ g_assert (strcmp ("", empty_string) == 0);
+ g_assert (memcmp (comparator, binary, len) == 0);
+
+ g_free (string);
+ g_free (empty_string);
+ g_free (binary);
+
+ g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ g_assert (binary == NULL);
+ g_assert (len == 0);
+ g_free (binary);
+
+ transport_read_count = 0;
+ transport_read_error_at = 0;
+ g_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;
+ g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) == -1);
+ transport_read_error_at = -1;
+
+ transport_read_error = 1;
+ g_assert (thrift_binary_protocol_read_bool (protocol,
+ &value_boolean, NULL) == -1);
+ g_assert (thrift_binary_protocol_read_byte (protocol,
+ &value_byte, NULL) == -1);
+ g_assert (thrift_binary_protocol_read_i16 (protocol,
+ &value_16, NULL) == -1);
+ g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) == -1);
+ g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) == -1);
+ g_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);
+ g_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;
+ g_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;
+ g_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;
+ g_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;
+ g_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;
+ g_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 */
+ g_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;
+ g_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;
+ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+ transport_read_error = 0;
+
+ /* invalid protocol version */
+ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+
+ /* sz > 0 */
+ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) > 0);
+
+ /* read a valid message */
+ g_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;
+ g_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 */
+ g_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 */
+ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) > 0);
+ g_free (message_name);
+
+ g_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;
+ gchar *empty_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);
+ g_assert (client != NULL);
+
+ tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
+ client, NULL);
+ protocol = THRIFT_PROTOCOL (tbp);
+
+ g_assert (thrift_binary_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_double (protocol,
+ &value_double, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
+ g_assert (thrift_binary_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
+ g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+
+ g_assert (value_boolean == TEST_BOOL);
+ g_assert (value_byte == TEST_BYTE);
+ g_assert (value_16 == TEST_I16);
+ g_assert (value_32 == TEST_I32);
+ g_assert (value_64 == TEST_I64);
+ g_assert (value_double == TEST_DOUBLE);
+ g_assert (strcmp (TEST_STRING, string) == 0);
+ g_assert (strcmp ("", empty_string) == 0);
+ g_assert (memcmp (comparator, binary, len) == 0);
+
+ g_free (string);
+ g_free (empty_string);
+ g_free (binary);
+
+ g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ g_assert (binary == NULL);
+ g_assert (len == 0);
+ 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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testbufferedtransport.c b/src/jaegertracing/thrift/lib/c_glib/test/testbufferedtransport.c
new file mode 100755
index 000000000..d01806d61
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testbufferedtransport.c
@@ -0,0 +1,325 @@
+/*
+ * 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 <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);
+static void thrift_socket_server_open (const int port, int times);
+
+/* 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);
+ g_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;
+ pid_t pid;
+ int port = 51199;
+ int status;
+
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ /* child listens */
+ thrift_socket_server_open (port,1);
+ exit (0);
+ } else {
+ /* parent connects, 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);
+
+ /* create a BufferedTransport wrapper of the Socket */
+ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+ /* this shouldn't work */
+ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_is_open (transport) == TRUE);
+ g_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);
+
+ g_assert (thrift_buffered_transport_open (transport, &err) == FALSE);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+ g_error_free (err);
+ err = NULL;
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
+}
+
+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 ();
+ g_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);
+
+ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
+ g_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);
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
+}
+
+
+static void
+thrift_socket_server_open (const int port, int times)
+{
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ int i;
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
+
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+ for(i=0;i<times;i++){
+ client = thrift_server_transport_accept (transport, NULL);
+ g_assert (client != NULL);
+ thrift_socket_close (client, NULL);
+ g_object_unref (client);
+ }
+ g_object_unref (tsocket);
+}
+
+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);
+ g_assert (client != NULL);
+
+ /* read 10 bytes */
+ bytes = thrift_buffered_transport_read (client, buf, 10, NULL);
+ g_assert (bytes == 10); /* make sure we've read 10 bytes */
+ g_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 ();
+ g_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);
+ g_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);
+
+
+ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_is_open (transport));
+
+ /* recognize disconnection */
+ sleep(1);
+ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
+
+ /* write and overflow buffer */
+ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
+
+ /* write 1 and flush */
+ g_assert (thrift_buffered_transport_write (transport, buf, 1, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_flush (transport, NULL) == FALSE);
+
+ thrift_buffered_transport_close (transport, NULL);
+
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ g_assert ( wait (&status) == pid );
+ g_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 ();
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testcompactprotocol.c b/src/jaegertracing/thrift/lib/c_glib/test/testcompactprotocol.c
new file mode 100755
index 000000000..e5ad49120
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testcompactprotocol.c
@@ -0,0 +1,1293 @@
+/*
+ * 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 g_assert () */
+#if !defined(__APPLE__) && !defined(__FreeBSD__) && \
+ !defined(__OpenBSD__) && !defined(__NetBSD__)
+#include <features.h>
+#endif
+
+#ifdef __GLIBC__
+#define __NO_STRING_INLINES 1
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.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 123456789012345
+#define TEST_NI16 (-12345)
+#define TEST_NI32 (-1234567890)
+#define TEST_NI64 (-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_compact_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_COMPACT_PROTOCOL, NULL);
+ g_assert (object != NULL);
+ g_object_unref (object);
+}
+
+static void
+test_initialize (void)
+{
+ ThriftSocket *tsocket = NULL;
+ ThriftCompactProtocol *protocol = NULL;
+ ThriftSocket *temp = NULL;
+
+ /* create a ThriftTransport */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", 51188, NULL);
+ g_assert (tsocket != NULL);
+ /* create a ThriftCompactProtocol using the Transport */
+ protocol = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ tsocket, NULL);
+ g_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;
+ ThriftCompactProtocol *tc = 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 ();
+ g_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);
+ g_assert (thrift_transport_is_open (transport));
+
+ /* create a ThriftCompactTransport */
+ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ tsocket, NULL);
+ protocol = THRIFT_PROTOCOL (tc);
+ g_assert (protocol != NULL);
+
+ /* write a bunch of primitives */
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, 2, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, 2, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, 2, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, -2, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, -2, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, -2, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_double (protocol,
+ TEST_DOUBLE, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_string (protocol,
+ TEST_STRING, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0);
+ g_assert (thrift_compact_protocol_write_binary (protocol, binary,
+ len, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_binary (protocol, binary,
+ len, NULL) > 0);
+
+ /* test write errors */
+ transport_write_error = 1;
+ g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE,
+ NULL) == -1);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) == -1);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) == -1);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) == -1);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16,
+ NULL) == -1);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32,
+ NULL) == -1);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64,
+ NULL) == -1);
+ g_assert (thrift_compact_protocol_write_double (protocol, TEST_DOUBLE,
+ NULL) == -1);
+ g_assert (thrift_compact_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;
+ g_assert (thrift_compact_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);
+ g_assert (wait (&status) == pid);
+ g_assert (status == 0);
+ }
+}
+
+static void
+test_read_and_write_complex_types (void)
+{
+ int status;
+ pid_t pid;
+ ThriftSocket *tsocket = NULL;
+ ThriftTransport *transport = NULL;
+ ThriftCompactProtocol *tc = NULL;
+ ThriftProtocol *protocol = NULL;
+ int port = TEST_PORT;
+
+ /* fork a server from the client */
+ pid = fork ();
+ g_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);
+ g_assert (thrift_transport_is_open (transport));
+
+ /* create a ThriftCompactTransport */
+ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ tsocket, NULL);
+ protocol = THRIFT_PROTOCOL (tc);
+ g_assert (protocol != NULL);
+
+ /* test structures */
+ g_assert (thrift_compact_protocol_write_struct_begin (protocol,
+ NULL, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0);
+
+ /* test field state w.r.t. deltas */
+
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE, 1, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 16, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 17, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 15, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 30, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 46, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 47, NULL) == 1);
+
+ /* test fields */
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 1, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+
+ /* test field state w.r.t. structs */
+
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 1, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 16, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+
+ g_assert (thrift_compact_protocol_write_struct_begin (protocol,
+ NULL, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 17, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+
+ g_assert (thrift_compact_protocol_write_struct_begin (protocol,
+ NULL, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 18, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 19, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0);
+
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 18, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 25, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0);
+
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 17, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+
+ /* test field state w.r.t. bools */
+
+ /* deltas */
+ /* non-bool field -> bool field -> non-bool field */
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 18, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
+ 19, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL,
+ NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 20, NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ /* bool -> bool field -> bool */
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
+ 21, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL,
+ NULL) == 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+
+ /* no deltas */
+ /* non-bool field -> bool field -> non-bool field */
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 1, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
+ 1, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 1, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ /* bool -> bool field -> bool */
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
+ 1, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 1);
+ g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
+
+ /* test write error */
+ transport_write_error = 1;
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 1, NULL) == -1);
+ transport_write_error = 0;
+
+ /* test 2nd write error */
+ transport_write_count = 0;
+ transport_write_error_at = 1;
+ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
+ T_DOUBLE,
+ 1, NULL) == -1);
+ transport_write_error_at = -1;
+
+ /* test 2nd read failure on a field */
+ thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL);
+
+ /* test write_field_stop */
+ g_assert (thrift_compact_protocol_write_field_stop (protocol, NULL) > 0);
+
+ /* write a map */
+ g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE,
+ T_DOUBLE,
+ 1, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0);
+
+ /* test 1st read failure on map---nothing to do on our side */
+
+ /* test 2nd read failure on a map */
+ thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL);
+
+ /* test 1st write failure on a map */
+ transport_write_error = 1;
+ g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE,
+ T_DOUBLE,
+ 1, NULL) == -1);
+ transport_write_error = 0;
+
+ /* test 2nd write failure on a map */
+ transport_write_count = 0;
+ transport_write_error_at = 1;
+ g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE,
+ T_DOUBLE,
+ 1, NULL) == -1);
+ transport_write_error_at = -1;
+
+ /* test negative map size */
+ thrift_compact_protocol_write_varint32 (tc, -10, NULL);
+ thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL);
+
+ /* test list operations */
+ g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
+ 15, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0);
+
+ /* test 1st read failure on a small list---nothing to do on our end */
+
+ /* test 1st read failure on a big list---nothing to do on our end */
+
+ /* test 2nd read failure on a big list */
+ thrift_compact_protocol_write_byte (protocol, (gint8) 0xf0, NULL);
+
+ /* test negative list size */
+ thrift_compact_protocol_write_byte (protocol, (gint8) 0xf0, NULL);
+ thrift_compact_protocol_write_varint32 (tc, -10, NULL);
+
+ /* test first write error on a small list */
+ transport_write_error = 1;
+ g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
+ 14, NULL) == -1);
+ transport_write_error = 0;
+
+ /* test first write error on a big list */
+ transport_write_error = 1;
+ g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
+ 15, NULL) == -1);
+ transport_write_error = 0;
+
+ /* test 2nd write error on a big list */
+ transport_write_count = 0;
+ transport_write_error_at = 1;
+ g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
+ 15, NULL) == -1);
+ transport_write_error_at = -1;
+
+ /* test set operation s*/
+ g_assert (thrift_compact_protocol_write_set_begin (protocol, T_DOUBLE,
+ 1, NULL) > 0);
+ g_assert (thrift_compact_protocol_write_set_end (protocol, NULL) == 0);
+
+ /* invalid protocol */
+ g_assert (thrift_compact_protocol_write_byte (protocol, 0, NULL) > 0);
+
+ /* invalid version */
+ g_assert (thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u,
+ NULL) > 0);
+ g_assert (thrift_compact_protocol_write_byte (protocol, 0, NULL) > 0);
+
+ /* send a valid message */
+ g_assert (thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u,
+ NULL) > 0);
+ g_assert (thrift_compact_protocol_write_byte (protocol, 0x01u, NULL) > 0);
+ thrift_compact_protocol_write_varint32 (tc, 1, NULL);
+ thrift_compact_protocol_write_string (protocol, "test", NULL);
+
+ /* broken 2nd read */
+ thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL);
+
+ /* send a broken 3rd read */
+ thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL);
+ thrift_compact_protocol_write_byte (protocol, 0x01u, NULL);
+
+ /* send a broken 4th read */
+ thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL);
+ thrift_compact_protocol_write_byte (protocol, 0x01u, NULL);
+ thrift_compact_protocol_write_varint32 (tc, 1, NULL);
+
+ /* send a valid message */
+ g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
+ T_CALL, 1, NULL) > 0);
+
+ g_assert (thrift_compact_protocol_write_message_end (protocol, NULL) == 0);
+
+ /* send broken writes */
+ transport_write_error = 1;
+ g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
+ T_CALL, 1, NULL) == -1);
+ transport_write_error = 0;
+
+ transport_write_count = 0;
+ transport_write_error_at = 1;
+ g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
+ T_CALL, 1, NULL) == -1);
+ transport_write_error_at = -1;
+
+ transport_write_count = 0;
+ transport_write_error_at = 2;
+ g_assert (thrift_compact_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;
+ g_assert (thrift_compact_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);
+ g_assert (wait (&status) == pid);
+ g_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;
+ ThriftCompactProtocol *tc = 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 ();
+ g_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);
+ g_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);
+ g_assert (ft != NULL);
+ transport = THRIFT_TRANSPORT (ft);
+
+ thrift_transport_open (transport, NULL);
+ g_assert (thrift_transport_is_open (transport));
+
+ /* create a compact protocol */
+ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ transport, NULL);
+ protocol = THRIFT_PROTOCOL (tc);
+ g_assert (protocol != NULL);
+
+ /* write a bunch of primitives */
+ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL,
+ NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE,
+ NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, 2, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, 2, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, 2, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i16 (protocol, -2, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i32 (protocol, -2, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_i64 (protocol, -2, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_double (protocol,
+ TEST_DOUBLE, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_string (protocol,
+ TEST_STRING, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_binary (protocol, binary,
+ len, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_protocol_write_binary (protocol, NULL,
+ 0, NULL) > 0);
+ thrift_transport_flush (transport, NULL);
+ g_assert (thrift_compact_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 (tc);
+ g_assert (wait (&status) == pid);
+ g_assert (status == 0);
+ }
+}
+
+
+static void
+thrift_server_primitives (const int port)
+{
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ ThriftCompactProtocol *tc = NULL;
+ ThriftProtocol *protocol = NULL;
+ gboolean value_boolean = FALSE;
+ gint8 value_byte = 0,
+ zigzag_p16 = 0, zigzag_p32 = 0, zigzag_p64 = 0,
+ zigzag_n16 = 0, zigzag_n32 = 0, zigzag_n64 = 0;
+ gint16 value_16 = 0;
+ gint32 value_32 = 0;
+ gint64 value_64 = 0;
+ gint16 value_n16 = 0;
+ gint32 value_n32 = 0;
+ gint64 value_n64 = 0;
+ gdouble value_double = 0;
+ gchar *string = NULL;
+ gchar *empty_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);
+ g_assert (client != NULL);
+
+ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ client, NULL);
+ protocol = THRIFT_PROTOCOL (tc);
+
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_double (protocol,
+ &value_double, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
+ g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+
+ g_assert (value_boolean == TEST_BOOL);
+ g_assert (value_byte == TEST_BYTE);
+ g_assert (value_16 == TEST_I16);
+ g_assert (value_32 == TEST_I32);
+ g_assert (value_64 == TEST_I64);
+ g_assert (value_n16 == TEST_NI16);
+ g_assert (value_n32 == TEST_NI32);
+ g_assert (value_n64 == TEST_NI64);
+ g_assert (zigzag_p16 == 4);
+ g_assert (zigzag_p32 == 4);
+ g_assert (zigzag_p64 == 4);
+ g_assert (zigzag_n16 == 3);
+ g_assert (zigzag_n32 == 3);
+ g_assert (zigzag_n64 == 3);
+ g_assert (value_double == TEST_DOUBLE);
+ g_assert (strcmp (TEST_STRING, string) == 0);
+ g_assert (strcmp ("", empty_string) == 0);
+ g_assert (memcmp (comparator, binary, len) == 0);
+
+ g_free (string);
+ g_free (empty_string);
+ g_free (binary);
+
+ g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ g_assert (binary == NULL);
+ g_assert (len == 0);
+ g_free (binary);
+
+ transport_read_count = 0;
+ transport_read_error_at = 0;
+ g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) == -1);
+ transport_read_error_at = -1;
+
+ transport_read_count = 0;
+ transport_read_error_at = 1;
+ g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) == -1);
+ transport_read_error_at = -1;
+
+ transport_read_error = 1;
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_byte (protocol,
+ &value_byte, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_i16 (protocol,
+ &value_16, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_i16 (protocol,
+ &value_n16, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) == -1);
+ g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) == -1);
+ g_assert (thrift_compact_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 (tc);
+ g_object_unref (client);
+ g_object_unref (tsocket);
+}
+
+static void
+thrift_server_complex_types (const int port)
+{
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ ThriftCompactProtocol *tc = 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;
+ gboolean value_boolean = ! TEST_BOOL;
+ gint8 value = 0;
+ gint16 field_id = 0;
+ guint32 size = 0;
+ gint32 seqid = 0;
+ gint8 version_and_type = 0;
+ gint8 protocol_id = 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);
+ g_assert (client != NULL);
+
+ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ client, NULL);
+ protocol = THRIFT_PROTOCOL (tc);
+
+ /* test struct operations */
+
+ thrift_compact_protocol_read_struct_begin (protocol, &struct_name, NULL);
+ thrift_compact_protocol_read_struct_end (protocol, NULL);
+
+ /* test field state w.r.t. deltas */
+
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 1);
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 16);
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 17);
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_id == 15);
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 30);
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_id == 46);
+ field_id = 0;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 47);
+ field_id = 0;
+
+ /* test field operations */
+
+ thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type,
+ &field_id, NULL);
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+
+ /* test field state w.r.t. structs */
+
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_id == 1);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 16);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+
+ g_assert (thrift_compact_protocol_read_struct_begin (protocol,
+ &struct_name, NULL) == 0);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_id == 17);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+
+ g_assert (thrift_compact_protocol_read_struct_begin (protocol,
+ &struct_name, NULL) == 0);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_id == 18);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 19);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_struct_end (protocol, NULL) == 0);
+
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 18);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 25);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_struct_end (protocol, NULL) == 0);
+
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_id == 17);
+ field_id = 0;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+
+ /* test field state w.r.t. bools */
+
+ /* deltas */
+ /* non-bool field -> bool field -> non-bool field */
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_type == T_BOOL);
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) == 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ /* bool -> bool field -> bool */
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) == 1);
+ g_assert (field_type == T_BOOL);
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) == 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+
+ /* no deltas */
+ /* non-bool field -> bool field -> non-bool field */
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_type == T_BOOL);
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) == 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ /* bool -> bool field -> bool */
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
+ &field_type,
+ &field_id, NULL) > 1);
+ g_assert (field_type == T_BOOL);
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) == 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+ thrift_compact_protocol_read_field_end (protocol, NULL);
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (value_boolean == TEST_BOOL);
+ value_boolean = ! TEST_BOOL;
+
+ /* test first read error on a field */
+ transport_read_error = 1;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol,
+ &field_name, &field_type,
+ &field_id, NULL) == -1);
+ transport_read_error = 0;
+
+ /* test 2nd write failure */
+ thrift_compact_protocol_read_byte (protocol, &value, NULL);
+
+ /* test 2nd read failure on a field */
+ transport_read_count = 0;
+ transport_read_error_at = 1;
+ g_assert (thrift_compact_protocol_read_field_begin (protocol,
+ &field_name, &field_type,
+ &field_id, NULL) == -1);
+ transport_read_error_at = -1;
+
+ /* test field stop */
+ thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type,
+ &field_id, NULL);
+
+ /* test map operations */
+
+ thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type,
+ &size, NULL);
+ thrift_compact_protocol_read_map_end (protocol, NULL);
+
+ /* test 1st read failure on a map */
+ transport_read_count = 0;
+ transport_read_error_at = 0;
+ g_assert (thrift_compact_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;
+ g_assert (thrift_compact_protocol_read_map_begin (protocol,
+ &key_type, &value_type,
+ &size, NULL) == -1);
+ transport_read_error_at = -1;
+
+ /* test 1st write failure on map---nothing to do on our side */
+
+ /* test 2nd write failure */
+ thrift_compact_protocol_read_byte (protocol, &value, NULL);
+
+ /* test negative map size */
+ g_assert (thrift_compact_protocol_read_map_begin (protocol,
+ &key_type, &value_type,
+ &size, NULL) == -1);
+
+ /* test list operations */
+ thrift_compact_protocol_read_list_begin (protocol, &element_type, &size,
+ NULL);
+ thrift_compact_protocol_read_list_end (protocol, NULL);
+
+ /* test small list 1st read failure */
+ transport_read_error = 1;
+ g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type,
+ &size, NULL) == -1);
+ transport_read_error = 0;
+
+ /* test big list 1st read failure */
+ transport_read_error = 1;
+ g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type,
+ &size, NULL) == -1);
+ transport_read_error = 0;
+
+ /* test big list 2nd read failure */
+ transport_read_count = 0;
+ transport_read_error_at = 1;
+ thrift_compact_protocol_read_list_begin (protocol, &element_type, &size,
+ NULL);
+ transport_read_error_at = -1;
+
+ /* test negative list size failure */
+ thrift_compact_protocol_read_list_begin (protocol, &element_type, &size,
+ NULL);
+
+ /* test small list 1st write failure---nothing to do on our end */
+
+ /* test big list 1st write failure---nothing to do on our end */
+
+ /* test big list 2nd write failure */
+ thrift_compact_protocol_read_byte (protocol, &value, NULL);
+
+ /* test set operations */
+ thrift_compact_protocol_read_set_begin (protocol, &element_type, &size, NULL);
+ thrift_compact_protocol_read_set_end (protocol, NULL);
+
+ /* broken read */
+ transport_read_error = 1;
+ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+ transport_read_error = 0;
+
+ /* invalid protocol */
+ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+
+ /* invalid version */
+ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+
+ /* read a valid message */
+ g_assert (thrift_compact_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;
+ g_assert (thrift_compact_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 = 2;
+ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+ transport_read_error_at = -1;
+
+ /* broken 4th read on a message */
+ transport_read_count = 0;
+ transport_read_error_at = 3;
+ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) == -1);
+ transport_read_error_at = -1;
+
+ /* read a valid message */
+ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
+ &message_type, &seqid,
+ NULL) > 0);
+ g_free (message_name);
+
+ g_assert (thrift_compact_protocol_read_message_end (protocol, NULL) == 0);
+
+ /* handle 2nd write failure on a message */
+ thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL);
+
+ /* handle 3rd write failure on a message */
+ thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL);
+ thrift_compact_protocol_read_byte (protocol, &version_and_type, NULL);
+
+ /* handle 4th write failure on a message */
+ thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL);
+ thrift_compact_protocol_read_byte (protocol, &version_and_type, NULL);
+ thrift_compact_protocol_read_varint32 (tc, &seqid, NULL);
+
+ g_object_unref (client);
+ g_object_unref (tsocket);
+}
+
+static void
+thrift_server_many_frames (const int port)
+{
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ ThriftCompactProtocol *tcp = NULL;
+ ThriftProtocol *protocol = NULL;
+ ThriftServerSocket *tsocket = NULL;
+ gboolean value_boolean = FALSE;
+ gint8 value_byte = 0,
+ zigzag_p16 = 0, zigzag_p32 = 0, zigzag_p64 = 0,
+ zigzag_n16 = 0, zigzag_n32 = 0, zigzag_n64 = 0;
+ gint16 value_16 = 0;
+ gint32 value_32 = 0;
+ gint64 value_64 = 0;
+ gint16 value_n16 = 0;
+ gint32 value_n32 = 0;
+ gint64 value_n64 = 0;
+ gdouble value_double = 0;
+ gchar *string = NULL;
+ gchar *empty_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);
+ g_assert (client != NULL);
+
+ tcp = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
+ client, NULL);
+ protocol = THRIFT_PROTOCOL (tcp);
+
+ g_assert (thrift_compact_protocol_read_bool (protocol,
+ &value_boolean, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n16, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n32, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n64, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_double (protocol,
+ &value_double, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0);
+ g_assert (thrift_compact_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
+ g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+
+ g_assert (value_boolean == TEST_BOOL);
+ g_assert (value_byte == TEST_BYTE);
+ g_assert (value_16 == TEST_I16);
+ g_assert (value_32 == TEST_I32);
+ g_assert (value_64 == TEST_I64);
+ g_assert (value_n16 == TEST_NI16);
+ g_assert (value_n32 == TEST_NI32);
+ g_assert (value_n64 == TEST_NI64);
+ g_assert (zigzag_p16 == 4);
+ g_assert (zigzag_p32 == 4);
+ g_assert (zigzag_p64 == 4);
+ g_assert (zigzag_n16 == 3);
+ g_assert (zigzag_n32 == 3);
+ g_assert (zigzag_n64 == 3);
+ g_assert (value_double == TEST_DOUBLE);
+ g_assert (strcmp (TEST_STRING, string) == 0);
+ g_assert (strcmp ("", empty_string) == 0);
+ g_assert (memcmp (comparator, binary, len) == 0);
+
+ g_free (string);
+ g_free (empty_string);
+ g_free (binary);
+
+ g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ g_assert (binary == NULL);
+ g_assert (len == 0);
+ g_free (binary);
+
+ thrift_transport_read_end (client, NULL);
+ thrift_transport_close (client, NULL);
+
+ g_object_unref (tcp);
+ 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 ("/testcompactprotocol/CreateAndDestroy",
+ test_create_and_destroy);
+ g_test_add_func ("/testcompactprotocol/Initialize", test_initialize);
+ g_test_add_func ("/testcompactprotocol/ReadAndWritePrimitives",
+ test_read_and_write_primitives);
+ g_test_add_func ("/testcompactprotocol/ReadAndWriteComplexTypes",
+ test_read_and_write_complex_types);
+ g_test_add_func ("/testcompactprotocol/ReadAndWriteManyFrames",
+ test_read_and_write_many_frames);
+
+ return g_test_run ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testcontainertest.c b/src/jaegertracing/thrift/lib/c_glib/test/testcontainertest.c
new file mode 100644
index 000000000..5fc51d516
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testcontainertest.c
@@ -0,0 +1,529 @@
+/*
+ * 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_clear_object (&server);
+ g_clear_object (&protocol_factory);
+ g_clear_object (&transport_factory);
+ g_clear_object (&server_transport);
+ g_clear_object (&processor);
+ g_clear_object (&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;
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testdebugproto.c b/src/jaegertracing/thrift/lib/c_glib/test/testdebugproto.c
new file mode 100644
index 000000000..109a48b50
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testdebugproto.c
@@ -0,0 +1,941 @@
+/*
+ * 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 <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 */
+ g_assert (g_type_is_a (T_TEST_TYPE_INHERITED_CLIENT,
+ T_TEST_TYPE_SRV_CLIENT));
+
+ /* TTestInheritedClient implements TTestSrvClient's interface */
+ g_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);
+
+ g_assert (input_protocol == G_OBJECT(protocol));
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testfdtransport.c b/src/jaegertracing/thrift/lib/c_glib/test/testfdtransport.c
new file mode 100755
index 000000000..1ea89be78
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testfdtransport.c
@@ -0,0 +1,184 @@
+/*
+ * 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 <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);
+ g_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);
+ g_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 */
+ g_assert (klass->is_open (transport));
+ g_assert (klass->peek (transport, &error));
+ g_assert (klass->open (transport, &error));
+ g_assert (klass->is_open (transport));
+ g_assert (klass->peek (transport, &error));
+
+ g_assert (klass->close (transport, &error));
+ g_assert (! klass->open (transport, &error));
+ g_assert (! klass->is_open (transport));
+ g_assert (! klass->peek (transport, &error));
+
+ /* already closed */
+ g_assert (close (fd) != 0);
+ g_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);
+
+ g_assert (! klass->is_open (transport));
+ error = NULL;
+ g_assert (! klass->peek (transport, &error));
+ error = NULL;
+ g_assert (! klass->open (transport, &error));
+ error = NULL;
+ g_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);
+ g_assert (fd >= 0);
+
+ /* write */
+ transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
+ "fd", fd,
+ NULL));
+ klass = THRIFT_TRANSPORT_GET_CLASS (transport);
+ g_assert (klass->is_open (transport));
+ g_assert (klass->write (transport, (gpointer) TEST_DATA, 11, &error));
+ g_assert (klass->flush (transport, &error));
+ g_assert (klass->close (transport, &error));
+ g_object_unref (transport);
+
+ /* read */
+ fd = open(filename, O_RDONLY, S_IRUSR | S_IWUSR);
+ g_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);
+ g_assert (got > 0 && got <= want);
+ b += got;
+ want -= got;
+ }
+ g_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);
+ g_assert (got > 0 && got <= want);
+ b += got;
+ want -= got;
+ }
+ g_assert (memcmp (out_buf, TEST_DATA + 7, 4) == 0);
+
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testframedtransport.c b/src/jaegertracing/thrift/lib/c_glib/test/testframedtransport.c
new file mode 100755
index 000000000..008e61e40
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testframedtransport.c
@@ -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 <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);
+static void thrift_socket_server_open (const int port, int times);
+
+/* 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);
+ g_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;
+ pid_t pid;
+ int port = 51199;
+ int status;
+
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ /* child listens */
+ thrift_socket_server_open (port,1);
+ exit (0);
+ } else {
+ /* parent connects, 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);
+
+ /* create a BufferedTransport wrapper of the Socket */
+ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+ /* this shouldn't work */
+ g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_framed_transport_is_open (transport) == TRUE);
+ g_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);
+
+ g_assert (thrift_framed_transport_open (transport, &err) == FALSE);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+ g_error_free (err);
+ err = NULL;
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
+}
+
+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 ();
+ g_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);
+
+ g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
+ g_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);
+
+ g_assert ( wait (&status) == pid );
+ g_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_socket_server_open (const int port, int times)
+{
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ int i;
+
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
+
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+ for(i=0;i<times;i++){
+ client = thrift_server_transport_accept (transport, NULL);
+ g_assert (client != NULL);
+ thrift_socket_close (client, NULL);
+ g_object_unref (client);
+ }
+ g_object_unref (tsocket);
+}
+
+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);
+ g_assert (client != NULL);
+
+ /* read 10 bytes */
+ bytes = thrift_framed_transport_read (client, buf, 10, NULL);
+ g_assert (bytes == 10); /* make sure we've read 10 bytes */
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testmemorybuffer.c b/src/jaegertracing/thrift/lib/c_glib/test/testmemorybuffer.c
new file mode 100755
index 000000000..9fb68b93d
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testmemorybuffer.c
@@ -0,0 +1,223 @@
+/*
+ * 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 <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);
+ g_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);
+ g_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);
+ g_assert (object != NULL);
+ g_object_unref (object);
+}
+
+static void
+test_create_and_destroy_external (void)
+{
+ GObject *object = NULL;
+ GByteArray *buf = g_byte_array_new ();
+ g_assert (buf != NULL);
+ object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER,
+ "buf", buf,
+ NULL);
+ g_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);
+ g_assert (object != NULL);
+
+ g_value_init (&val, G_TYPE_POINTER);
+ g_object_get_property (object, "buf", &val);
+ buf = (GByteArray*) g_value_get_pointer (&val);
+ g_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 */
+ g_assert (thrift_memory_buffer_open (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE);
+ g_assert (thrift_memory_buffer_is_open (THRIFT_TRANSPORT (tbuffer)) == TRUE);
+ g_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);
+ g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
+ (gpointer) TEST_DATA,
+ 10, &error) == FALSE);
+ g_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);
+ g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
+ (gpointer) TEST_DATA, 10, &error) == TRUE);
+ g_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);
+ g_assert (got > 0 && got <= want);
+ g_assert (error == NULL);
+ b += got;
+ want -= got;
+ }
+ g_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) {
+ g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
+ (gpointer) TEST_DATA, 10, &error) == TRUE);
+ g_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);
+ g_assert (got > 0 && got <= want);
+ g_assert (error == NULL);
+ b += got;
+ want -= got;
+ }
+ g_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 ();
+ g_assert (buf != NULL);
+
+ tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf", buf, NULL);
+ g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer),
+ (gpointer) TEST_DATA, 10, &error) == TRUE);
+ g_assert (error == NULL);
+
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testoptionalrequired.c b/src/jaegertracing/thrift/lib/c_glib/test/testoptionalrequired.c
new file mode 100755
index 000000000..636c36d69
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testoptionalrequired.c
@@ -0,0 +1,227 @@
+/*
+ * 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 <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;
+ g_assert (s1->__isset_im_default == FALSE);
+ g_assert (s1->__isset_im_optional == FALSE);
+ write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s2), NULL, NULL);
+ g_assert (s2->__isset_im_default == TRUE);
+ g_assert (s2->__isset_im_optional == FALSE);
+ g_assert (s2->im_optional == 0);
+
+ s1->__isset_im_optional = TRUE;
+ write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s3), NULL, NULL);
+ g_assert (s3->__isset_im_default == TRUE);
+ g_assert (s3->__isset_im_optional == TRUE);
+ g_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);
+
+ g_assert (t1->__isset_im_default == FALSE);
+ g_assert (t2->__isset_im_optional == TRUE);
+ g_assert (t1->im_default == t2->im_optional);
+ g_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);
+
+ g_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);
+ g_assert (read_error != NULL);
+ g_error_free (read_error);
+
+ write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL);
+
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testserialization.c b/src/jaegertracing/thrift/lib/c_glib/test/testserialization.c
new file mode 100644
index 000000000..67d411de1
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testserialization.c
@@ -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();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testsimpleserver.c b/src/jaegertracing/thrift/lib/c_glib/test/testsimpleserver.c
new file mode 100755
index 000000000..3c6f2e80d
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testsimpleserver.c
@@ -0,0 +1,122 @@
+/*
+ * 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 <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 ();
+ g_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);
+ g_assert (wait (&status) == pid);
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/teststruct.c b/src/jaegertracing/thrift/lib/c_glib/test/teststruct.c
new file mode 100755
index 000000000..d120cbcfa
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/teststruct.c
@@ -0,0 +1,111 @@
+/*
+ * 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-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);
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testthrifttest.c b/src/jaegertracing/thrift/lib/c_glib/test/testthrifttest.c
new file mode 100755
index 000000000..23a934db9
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testthrifttest.c
@@ -0,0 +1,112 @@
+#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);
+
+ g_assert (thrift_test_handler_test_insanity (NULL, &_return, argument, &error));
+ g_assert (! indicator);
+
+ g_hash_table_unref (_return);
+ g_assert (! indicator);
+
+ g_object_unref (argument);
+ g_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 ();
+}
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testthrifttestclient.cpp b/src/jaegertracing/thrift/lib/c_glib/test/testthrifttestclient.cpp
new file mode 100644
index 000000000..20fbcdb03
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testthrifttestclient.cpp
@@ -0,0 +1,639 @@
+/*
+ * 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 (that makes sense...) */
+
+#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 <memory>
+#include <thrift/transport/TServerSocket.h>
+#include "ThriftTest.h"
+#include "ThriftTest_types.h"
+
+#include <iostream>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+using namespace apache::thrift;
+using namespace apache::thrift::concurrency;
+using namespace apache::thrift::protocol;
+using namespace apache::thrift::server;
+using namespace apache::thrift::transport;
+
+using namespace thrift::test;
+
+using std::cout;
+using std::endl;
+using std::fixed;
+using std::make_pair;
+using std::map;
+using std::set;
+using std::string;
+using std::vector;
+
+#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() = default;
+
+ void testVoid() override {
+ cout << "[C -> C++] testVoid()" << endl;
+ }
+
+ void testString(string& out, const string &thing) override {
+ cout << "[C -> C++] testString(\"" << thing << "\")" << endl;
+ out = thing;
+ }
+
+ bool testBool(const bool thing) override {
+ cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl;
+ return thing;
+ }
+ int8_t testByte(const int8_t thing) override {
+ cout << "[C -> C++] testByte(" << (int)thing << ")" << endl;
+ return thing;
+ }
+ int32_t testI32(const int32_t thing) override {
+ cout << "[C -> C++] testI32(" << thing << ")" << endl;
+ return thing;
+ }
+
+ int64_t testI64(const int64_t thing) override {
+ cout << "[C -> C++] testI64(" << thing << ")" << endl;
+ return thing;
+ }
+
+ double testDouble(const double thing) override {
+ cout.precision(6);
+ cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl;
+ return thing;
+ }
+
+ void testBinary(string& out, const string &thing) override {
+ cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl;
+ out = thing;
+ }
+
+ void testStruct(Xtruct& out, const Xtruct &thing) override {
+ 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) override {
+ 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) override {
+ 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) override {
+ 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) override {
+ 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) override {
+ 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) override {
+ cout << "[C -> C++] testEnum(" << thing << ")" << endl;
+ return thing;
+ }
+
+ UserId testTypedef(const UserId thing) override {
+ cout << "[C -> C++] testTypedef(" << thing << ")" << endl;
+ return thing; }
+
+ void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) override {
+ 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) override {
+ 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) override {
+ 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) override
+ {
+ 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) override {
+
+ 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) override {
+ 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 = nullptr;
+ ThriftBinaryProtocol *protocol = nullptr;
+ TTestThriftTestClient *client = nullptr;
+ TTestThriftTestIf *iface = nullptr;
+ GError *error = nullptr;
+ gchar *string = nullptr;
+ 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 = nullptr, *map_out = nullptr;
+ GHashTable *set_in = nullptr, *set_out = nullptr;
+ GArray *list_in = nullptr, *list_out = nullptr;
+ TTestNumberz enum_in, enum_out;
+ TTestUserId user_id_in, user_id_out;
+ GHashTable *insanity_in = nullptr;
+ TTestXtruct *xtruct1, *xtruct2;
+ TTestInsanity *insanity_out = nullptr;
+ TTestXtruct *multi_in = nullptr;
+ GHashTable *multi_map_out = nullptr;
+ TTestXception *xception = nullptr;
+ TTestXception2 *xception2 = nullptr;
+
+#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), nullptr);
+
+ assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE);
+ assert (error == nullptr);
+
+ assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE);
+ assert (strcmp (string, "test123") == 0);
+ g_free (string);
+ assert (error == nullptr);
+
+ assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE);
+ assert (byte == 5);
+ assert (error == nullptr);
+
+ assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE);
+ assert (i32 == 123);
+ assert (error == nullptr);
+
+ assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE);
+ assert (i64 == 12345);
+ assert (error == nullptr);
+
+ assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE);
+ assert (dbl == 5.6);
+ assert (error == nullptr);
+
+ xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ 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, nullptr);
+ assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE);
+ assert (error == nullptr);
+
+ xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
+ xtruct2_out->byte_thing = 1;
+ xtruct2_out->__isset_byte_thing = TRUE;
+ if (xtruct2_out->struct_thing != nullptr)
+ 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, nullptr);
+ assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE);
+ assert (error == nullptr);
+
+ g_object_unref (xtruct2_out);
+ g_object_unref (xtruct2_in);
+ g_object_unref (xtruct_in);
+
+ map_out = g_hash_table_new (nullptr, nullptr);
+ map_in = g_hash_table_new (nullptr, nullptr); 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 == nullptr);
+ g_hash_table_destroy (map_out);
+ g_hash_table_destroy (map_in);
+
+ map_out = g_hash_table_new (nullptr, nullptr);
+ map_in = g_hash_table_new (nullptr, nullptr);
+ 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 == nullptr);
+ g_hash_table_destroy (map_out);
+ g_hash_table_destroy (map_in);
+
+ set_out = g_hash_table_new (nullptr, nullptr);
+ set_in = g_hash_table_new (nullptr, nullptr);
+ 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 == nullptr);
+ 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 == nullptr);
+ 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 == nullptr);
+
+ 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 == nullptr);
+
+ map_in = g_hash_table_new (nullptr, nullptr);
+ assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE);
+ assert (error == nullptr);
+ g_hash_table_destroy (map_in);
+
+ // insanity
+ insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, nullptr);
+ insanity_out->userMap = g_hash_table_new (nullptr, nullptr);
+ g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out);
+
+ xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ 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, nullptr);
+ 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 (nullptr, nullptr);
+ 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 (nullptr, nullptr);
+ string = g_strdup ("abc123");
+ g_hash_table_insert (multi_map_out, &i16, string);
+ multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ 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 = nullptr;
+ g_object_unref (xception);
+ xception = nullptr;
+
+ assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE);
+ g_error_free (error);
+ error = nullptr;
+ assert (xception == nullptr);
+
+ assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE);
+ assert (error == nullptr);
+
+ multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", nullptr, &xception, &xception2, &error) == FALSE);
+ assert (xception->errorCode == 1001);
+ assert (xception2 == nullptr);
+ g_error_free (error);
+ error = nullptr;
+ g_object_unref (xception);
+ g_object_unref (multi_in);
+ xception = nullptr;
+ multi_in = nullptr;
+
+ multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", nullptr, &xception, &xception2, &error) == FALSE);
+ assert (xception2->errorCode == 2002);
+ assert (xception == nullptr);
+ g_error_free (error);
+ error = nullptr;
+ g_object_unref (xception2);
+ g_object_unref (multi_in);
+ xception2 = nullptr;
+ multi_in = nullptr;
+
+ multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, nullptr , nullptr, &xception, &xception2, &error) == TRUE);
+ assert (error == nullptr);
+ g_object_unref(multi_in);
+ multi_in = nullptr;
+
+ assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE);
+ assert (error == nullptr);
+
+ /* sleep to let the oneway call go through */
+ sleep (5);
+
+ thrift_transport_close (THRIFT_TRANSPORT(tsocket), nullptr);
+ 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 */
+ {
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TestHandler> testHandler(new TestHandler());
+ std::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
+ std::shared_ptr<TServerSocket> serverSocket(new TServerSocket(TEST_PORT));
+ std::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;
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testtransportsocket.c b/src/jaegertracing/thrift/lib/c_glib/test/testtransportsocket.c
new file mode 100755
index 000000000..89c61b910
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testtransportsocket.c
@@ -0,0 +1,361 @@
+/*
+ * 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 <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);
+static void thrift_socket_server_open (const int port, int times);
+/* 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);
+ g_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;
+ int port = 51199;
+ pid_t pid;
+ int status;
+
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ /* child listens */
+ thrift_socket_server_open (port, 1);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ /* open a connection and close it */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+ transport = THRIFT_TRANSPORT (tsocket);
+ thrift_socket_open (transport, NULL);
+ g_assert (thrift_socket_is_open (transport) == TRUE);
+ thrift_socket_close (transport, NULL);
+ g_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);
+ g_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;
+ g_assert (thrift_socket_open (transport, &err) == FALSE);
+ socket_error = 0;
+ g_object_unref (tsocket);
+ g_error_free (err);
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
+}
+
+static void
+test_read_and_write(void)
+{
+ ThriftSocket *tsocket = NULL;
+ ThriftTransport *transport = NULL;
+ pid_t pid;
+ int port = 51199;
+ int status;
+ guchar buf[10] = TEST_DATA; /* a buffer */
+
+ pid = fork ();
+ g_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);
+ g_assert (thrift_socket_open (transport, NULL) == TRUE);
+ g_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);
+
+ g_assert ( wait (&status) == pid );
+ g_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_open (const int port, int times)
+{
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ int i;
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
+
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+ for(i=0;i<times;i++){
+ client = thrift_server_transport_accept (transport, NULL);
+ g_assert (client != NULL);
+ thrift_socket_close (client, NULL);
+ g_object_unref (client);
+ }
+ g_object_unref (tsocket);
+}
+
+
+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);
+ g_assert (client != NULL);
+
+ /* read 10 bytes */
+ bytes = thrift_socket_read (client, buf, 10, NULL);
+ g_assert (bytes == 10); /* make sure we've read 10 bytes */
+ g_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 ();
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/test/testtransportsslsocket.c b/src/jaegertracing/thrift/lib/c_glib/test/testtransportsslsocket.c
new file mode 100644
index 000000000..3c2644d8d
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/test/testtransportsslsocket.c
@@ -0,0 +1,542 @@
+/*
+ * 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.
+ */
+#define _POSIX_C_SOURCE 200112L /* https://stackoverflow.com/questions/37541985/storage-size-of-addrinfo-isnt-known */
+
+
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.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>
+#include <thrift/c_glib/transport/thrift_ssl_socket.h>
+
+/* #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } */
+#define TEST_DATA { "GET / HTTP/1.1\n\n" }
+
+
+/* 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_ssl_socket.c"
+#undef socket
+#undef recv
+#undef send
+
+static void thrift_socket_server (const int port);
+
+/* test object creation and destruction */
+static void
+test_ssl_create_and_destroy(void)
+{
+ gchar *hostname = NULL;
+ guint port = 0;
+
+ GObject *object = NULL;
+ object = g_object_new (THRIFT_TYPE_SSL_SOCKET, NULL);
+ g_assert (object != NULL);
+ g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL);
+ g_free (hostname);
+ g_object_unref (object);
+}
+
+static void
+test_ssl_create_and_set_properties(void)
+{
+ gchar *hostname = NULL;
+ guint port = 0;
+ SSL_CTX* ssl_ctx= NULL;
+ GError *error=NULL;
+
+ GObject *object = NULL;
+ object = thrift_ssl_socket_new(SSLTLS, &error);
+ g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, "ssl_context", &ssl_ctx, NULL);
+ g_assert (ssl_ctx!=NULL);
+
+ g_free (hostname);
+ g_object_unref (object);
+}
+
+static void
+test_ssl_open_and_close_non_ssl_server(void)
+{
+ ThriftSSLSocket *tSSLSocket = NULL;
+ ThriftTransport *transport = NULL;
+ GError *error=NULL;
+ pid_t pid;
+ int non_ssl_port = 51198;
+ char errormsg[255];
+
+
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ /* child listens */
+ /* This is a non SSL server */
+ thrift_socket_server (non_ssl_port);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ /* open a connection and close it */
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", non_ssl_port, &error);
+
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
+ g_assert_cmpstr(error->message, == ,"Error while connect/bind: 68 -> Connection reset by peer");
+ g_clear_error (&error);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+ thrift_ssl_socket_close (transport, NULL);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+
+ /* test close failure */
+ THRIFT_SOCKET(tSSLSocket)->sd = -1;
+ thrift_ssl_socket_close (transport, NULL);
+ g_object_unref (tSSLSocket);
+
+ /* try a hostname lookup failure */
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", non_ssl_port, &error);
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
+ snprintf(errormsg, 255, "host lookup failed for localhost.broken:%d - Unknown host", non_ssl_port);
+ g_assert_cmpstr(error->message, ==, errormsg);
+ g_clear_error (&error);
+ g_object_unref (tSSLSocket);
+ error = NULL;
+
+ /* try an error call to socket() */
+ /*
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error);
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ socket_error = 1;
+ assert (thrift_ssl_socket_open (transport, &error) == FALSE);
+ socket_error = 0;
+ g_object_unref (tSSLSocket);
+ g_error_free (error);
+ */
+ }
+}
+
+static void
+test_ssl_write_invalid_socket(void)
+{
+ ThriftSSLSocket *tSSLSocket = NULL;
+ ThriftTransport *transport = NULL;
+ GError *error=NULL;
+ char buffer[] = "this must not break";
+
+ /* open a connection and close it */
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188+1, &error);
+
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ g_assert (thrift_ssl_socket_open (transport, NULL) == FALSE);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+
+ /* FIXME This must be tested but since the assertion inside thrift_ssl_socket_write breaks the test unit
+ it's disabled. They idea is to disable trap/coredump during this test
+ g_assert (thrift_ssl_socket_write(transport, buffer, sizeof(buffer), &error) == FALSE);
+ g_message ("write_failed_with_error: %s",
+ error != NULL ? error->message : "No");
+ g_clear_error (&error);
+ */
+ thrift_ssl_socket_close (transport, NULL);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+
+ /* test close failure */
+ THRIFT_SOCKET(tSSLSocket)->sd = -1;
+ thrift_ssl_socket_close (transport, NULL);
+ g_object_unref (tSSLSocket);
+}
+
+
+
+/**
+ * Print the common name of certificate
+ */
+unsigned char * get_cn_name(X509_NAME* const name)
+{
+ int idx = -1;
+ unsigned char *utf8 = NULL;
+
+ do
+ {
+ if(!name) break; /* failed */
+
+ idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
+ if(!(idx > -1)) break; /* failed */
+
+ X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx);
+ if(!entry) break; /* failed */
+
+ ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
+ if(!data) break; /* failed */
+
+ int length = ASN1_STRING_to_UTF8(&utf8, data);
+ if(!utf8 || !(length > 0)) break; /* failed */
+
+ } while (0);
+ return utf8;
+}
+
+/*
+ * Handle IPV4 and IPV6 addr
+ */
+void *get_in_addr(struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET)
+ return &(((struct sockaddr_in*)sa)->sin_addr);
+ return &(((struct sockaddr_in6*)sa)->sin6_addr);
+}
+
+int verify_ip(char * hostname, struct sockaddr_storage *addr)
+{
+ struct addrinfo *addr_info,*p;
+ struct addrinfo hints;
+ int res;
+ int retval = 0;
+
+
+ memset(&hints, 0, sizeof (struct addrinfo));
+ hints.ai_family = AF_UNSPEC; /* use AF_INET6 to force IPv6 */
+ hints.ai_socktype = SOCK_STREAM;
+
+
+ if ( (res = getaddrinfo(hostname, NULL, &hints, &addr_info) ) != 0)
+ {
+ /* get the host info */
+ g_error("Cannot get the host address");
+ return retval;
+ }
+ /* loop through all the results and connect to the first we can */
+ char dnshost[INET6_ADDRSTRLEN]; /* bigger addr supported IPV6 */
+ char socket_ip[INET6_ADDRSTRLEN];
+ if(inet_ntop(addr->ss_family, get_in_addr(addr), socket_ip, INET6_ADDRSTRLEN)==socket_ip){
+ g_debug("We are connected to host %s checking against certificate...", socket_ip);
+ int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0;
+ for(p = addr_info; p != NULL; p = p->ai_next) {
+ if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){
+ if(dnshost!=NULL){
+ g_info("DNS address [%i -> %s]", p->ai_addr, dnshost);
+ if(!strncmp(dnshost, socket_ip, sizeip)){
+ retval=1;
+ break; /* if we get here, we must have connected successfully */
+ }
+ }
+ }
+ }
+ }
+
+ if(addr_info)
+ freeaddrinfo(addr_info);
+
+ return retval;
+}
+
+static void
+read_from_file(char *buffer, long size, const char *file_name)
+{
+ char ch;
+ long index=0;
+ FILE *fp;
+
+ fp = fopen(file_name,"r"); /* read mode */
+
+ if( fp == NULL )
+ {
+ perror("Error while opening the file.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("The contents of %s file are :\n", file_name);
+
+ while(index<size && ( ch = fgetc(fp) ) != EOF ){
+ buffer[index++] = ch;
+ }
+
+ fclose(fp);
+}
+
+#define ISSUER_CN_PINNING "The Apache Software Foundation"
+#define SUBJECT_CN_PINNING "localhost"
+#define CERT_SERIAL_NUMBER "1"
+
+gboolean verify_certificate_sn(X509 *cert, const unsigned char *serial_number)
+{
+ gboolean retval = FALSE;
+
+ ASN1_INTEGER *serial = X509_get_serialNumber(cert);
+
+ BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL);
+ if (!bn) {
+ fprintf(stderr, "unable to convert ASN1INTEGER to BN\n");
+ return EXIT_FAILURE;
+ }
+ char *tmp = BN_bn2dec(bn);
+ if (!tmp) {
+ g_warning(stderr, "unable to convert BN to decimal string.\n");
+ BN_free(bn);
+ return EXIT_FAILURE;
+ }
+ /*
+ if (strlen(tmp) >= len) {
+ g_warn(stderr, "buffer length shorter than serial number\n");
+ BN_free(bn);
+ OPENSSL_free(tmp);
+ return EXIT_FAILURE;
+ }
+ */
+ if(!strncmp(serial_number, tmp, strlen(serial_number))){
+ retval=TRUE;
+ }else{
+ g_warning("Serial number is not valid");
+ }
+
+ BN_free(bn);
+ OPENSSL_free(tmp);
+ return retval;
+}
+
+gboolean my_access_manager(ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error)
+{
+ ThriftSSLSocket *sslSocket = THRIFT_SSL_SOCKET (transport);
+
+ g_info("Processing access to the server");
+ X509_NAME* iname = cert ? X509_get_issuer_name(cert) : NULL;
+ X509_NAME* sname = cert ? X509_get_subject_name(cert) : NULL;
+
+ /* Issuer is the authority we trust that warrants nothing useful */
+ const unsigned char * issuer = get_cn_name(iname);
+ if(issuer){
+ gboolean valid = TRUE;
+ g_info("Issuer (cn) %s", issuer);
+
+ /* Issuer pinning */
+ if(strncmp(ISSUER_CN_PINNING, issuer, strlen(ISSUER_CN_PINNING))){
+ g_warning("The Issuer of the certificate is not valid");
+ valid=FALSE;
+ }
+ OPENSSL_free(issuer);
+ if(!valid)
+ return valid;
+ }
+
+
+ /* Subject is who the certificate is issued to by the authority */
+ const unsigned char * subject = get_cn_name(sname);
+ if(subject){
+ g_info("Subject (cn) %s", subject);
+ gboolean valid = TRUE;
+
+ /* Subject pinning */
+ if(strncmp(SUBJECT_CN_PINNING, subject, strlen(SUBJECT_CN_PINNING))){
+ g_warning("The subject of the certificate is not valid");
+ valid=FALSE;
+ }
+
+ if(!valid)
+ return valid;
+
+ /* Host pinning */
+ if(verify_ip(subject, addr)){
+ g_info("Verified subject");
+ }else{
+ g_info("Cannot verify subject");
+ valid=FALSE;
+ }
+ OPENSSL_free(subject);
+
+ if(!valid)
+ return valid;
+ }
+
+ if(!verify_certificate_sn(cert, CERT_SERIAL_NUMBER)){
+ return FALSE;
+ }else{
+ g_info("Verified serial number");
+ }
+
+ return TRUE;
+
+}
+
+
+
+
+#ifdef BUILD_SERVER
+static void
+test_ssl_authorization_manager(void)
+{
+ int status=0;
+ pid_t pid;
+ ThriftSSLSocket *tSSLsocket = NULL;
+ ThriftTransport *transport = NULL;
+ /* int port = 51199; */
+ int port = 443;
+ GError *error=NULL;
+
+ guchar buf[17] = TEST_DATA; /* a buffer */
+
+/*
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ thrift_ssl_socket_server (port);
+ exit (0);
+ } else {
+ */
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ /* Test against level2 owncloud certificate */
+ tSSLsocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error);
+ thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); /* Install pinning manager */
+ /* thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem"); */
+ unsigned char cert_buffer[65534];
+ read_from_file(cert_buffer, 65534, "../../keys/client.pem");
+ if(!thrift_ssl_load_cert_from_buffer(tSSLsocket, cert_buffer)){
+ g_warning("Certificates cannot be loaded!");
+ }
+
+ transport = THRIFT_TRANSPORT (tSSLsocket);
+ g_assert (thrift_ssl_socket_open (transport, NULL) == TRUE);
+ g_assert (thrift_ssl_socket_is_open (transport));
+
+ thrift_ssl_socket_write (transport, buf, 17, NULL);
+
+ /* write fail */
+ send_error = 1;
+ /*
+ thrift_ssl_socket_write (transport, buf, 1, NULL);
+ send_error = 0;
+ thrift_ssl_socket_write_end (transport, NULL);
+ thrift_ssl_socket_flush (transport, NULL);
+ */
+ thrift_ssl_socket_close (transport, NULL);
+ g_object_unref (tSSLsocket);
+
+ /* g_assert ( wait (&status) == pid ); */
+ g_assert ( status == 0 );
+ /* } */
+}
+#endif
+
+
+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);
+ g_assert (client != NULL);
+
+ /* read 10 bytes */
+ bytes = thrift_ssl_socket_read (client, buf, 10, NULL);
+ g_assert (bytes == 10); /* make sure we've read 10 bytes */
+ g_assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */
+
+ /* failed read */
+ recv_error = 1;
+ thrift_ssl_socket_read (client, buf, 1, NULL);
+ recv_error = 0;
+
+ thrift_ssl_socket_read_end (client, NULL);
+ thrift_ssl_socket_close (client, NULL);
+ g_object_unref (tsocket);
+ g_object_unref (client);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int retval;
+#if (!GLIB_CHECK_VERSION (2, 36, 0))
+ g_type_init();
+#endif
+
+ g_test_init (&argc, &argv, NULL);
+
+ thrift_ssl_socket_initialize_openssl();
+
+ g_test_add_func ("/testtransportsslsocket/CreateAndDestroy", test_ssl_create_and_destroy);
+ g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties);
+ g_test_add_func ("/testtransportsslsocket/OpenAndCloseNonSSLServer", test_ssl_open_and_close_non_ssl_server);
+ g_test_add_func ("/testtransportsslsocket/OpenAndWriteInvalidSocket", test_ssl_write_invalid_socket);
+
+
+
+
+ retval = g_test_run ();
+
+ thrift_ssl_socket_finalize_openssl();
+
+ return retval;
+}
+
diff --git a/src/jaegertracing/thrift/lib/c_glib/thrift_c_glib.pc.in b/src/jaegertracing/thrift/lib/c_glib/thrift_c_glib.pc.in
new file mode 100644
index 000000000..568c7a25d
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/c_glib/thrift_c_glib.pc.in
@@ -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}