THRIFT-3706: Implement multiplexed protocol client and test client for c_glib; test server for java; integrate into crosstest
Client: c_glib
This closes #1191
This closes #1199
diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am
index b66c89b..8e7bf88 100755
--- a/lib/c_glib/Makefile.am
+++ b/lib/c_glib/Makefile.am
@@ -35,8 +35,10 @@
src/thrift/c_glib/processor/thrift_processor.c \
src/thrift/c_glib/processor/thrift_dispatch_processor.c \
src/thrift/c_glib/protocol/thrift_protocol.c \
+ src/thrift/c_glib/protocol/thrift_protocol_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_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 \
@@ -67,11 +69,13 @@
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_compact_protocol_factory.h \
+ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
include_transportdir = $(include_thriftdir)/transport
include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
new file mode 100644
index 0000000..86f8097
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
@@ -0,0 +1,187 @@
+/*
+ * 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_SEPARATOR,
+ 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);
+ ThriftMultiplexedProtocolClass *multiplexClass = THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(self);
+ ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (multiplexClass);
+
+ if( (message_type == T_CALL || message_type == T_ONEWAY) && self->service_name != NULL) {
+ service_name = g_strdup_printf("%s%s%s", self->service_name, self->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:
+ if(self->service_name!=NULL)
+ g_free (self->service_name);
+ self->service_name= g_value_dup_string (value);
+ break;
+
+ case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR:
+ if(self->separator!=NULL)
+ g_free (self->separator);
+ self->separator= 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;
+
+ case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR:
+ g_value_set_string (value, self->separator);
+ 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)
+{
+ // THRIFT_UNUSED_VAR (protocol);
+ protocol->separator = g_strdup (THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR);
+ protocol->service_name = NULL;
+}
+
+static void
+thrift_multiplexed_protocol_finalize (ThriftMultiplexedProtocol *protocol)
+{
+ if(protocol->separator){
+ g_free(protocol->separator);
+ protocol->separator = NULL;
+ }
+ if(protocol->service_name){
+ g_free(protocol->service_name);
+ protocol->service_name = NULL;
+ }
+ /* 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
+ */
+ /* This fails, why? G_OBJECT_CLASS (protocol)->finalize(protocol); */
+}
+
+
+/* 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);
+
+ g_debug("Current Multiplexed write_message_begin addr %p, new %p", cls->write_message_begin, thrift_multiplexed_protocol_write_message_begin);
+ 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 /* default value */,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR] =
+ g_param_spec_string ("separator",
+ "Separator for service name and pointer",
+ "Set service name separator",
+ NULL /* default value */,
+ G_PARAM_READWRITE);
+
+ g_object_class_install_properties (object_class,
+ PROP_THRIFT_MULTIPLEXED_PROTOCOL_END,
+ thrift_multiplexed_protocol_obj_properties);
+}
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
new file mode 100644
index 0000000..58d86ce
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.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_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))
+
+/* version numbers */
+#define THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR ":"
+
+typedef struct _ThriftMultiplexedProtocol ThriftMultiplexedProtocol;
+
+
+
+/*!
+ * Thrift Multiplexed Protocol instance.
+ */
+struct _ThriftMultiplexedProtocol
+{
+ ThriftProtocolDecorator parent;
+
+ gchar *service_name;
+ gchar *separator;
+};
+
+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/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
new file mode 100644
index 0000000..1844795
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
@@ -0,0 +1,651 @@
+/*
+ * 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_info("Concrete protocol %p | %p", self->concrete_protocol, 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);
+ g_info("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object));
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
+ // FIXME We must finalize it first
+ //g_clear_object (&self->concrete_protocol);
+ self->concrete_protocol=g_value_get_pointer (value);
+ g_info("Setting concrete protocol %p to %p in %s",self, self->concrete_protocol, g_type_name(G_TYPE_FROM_INSTANCE(object)));
+ // We must get the transport and set it on base class.
+
+ 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);
+ g_info("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object));
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
+ g_value_set_pointer (value, self->concrete_protocol);
+
+ /* But we must also set our */
+
+ 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_info("Getting concrete protocol from %X -> %X", self, self->concrete_protocol);
+
+ return retval;
+}
+
+
+static void
+thrift_protocol_decorator_init (ThriftProtocolDecorator *protocol)
+{
+ protocol->concrete_protocol = NULL;
+}
+
+
+
+static void
+thrift_protocol_decorator_dispose (ThriftProtocolDecorator *protocol)
+{
+ ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+ /* dispose() might be called multiple times, so we must guard against
+ * calling g_object_unref() on an invalid GObject by setting the member
+ * NULL; g_clear_object() does this for us.
+ */
+ if(self->concrete_protocol!=NULL)
+ g_clear_object (&self->concrete_protocol);
+}
+
+static void
+thrift_protocol_decorator_finalize (ThriftProtocolDecorator *protocol)
+{
+
+// /*
+// * Chain the concrete protocol finalize
+// */
+// if(protocol->concrete_protocol!=NULL){
+// G_OBJECT_CLASS (protocol->concrete_protocol)->finalize(protocol->concrete_protocol);
+// }
+ /* Always chain up to the parent class; there is no need to check if
+ * the parent class implements the finalize() virtual function: it is
+ * always guaranteed to do so
+ */
+ G_OBJECT_CLASS (protocol)->finalize(protocol);
+}
+
+/* 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->finalize = thrift_protocol_decorator_finalize;
+ object_class->dispose = thrift_protocol_decorator_dispose;
+
+ thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL] =
+ g_param_spec_pointer ("protocol",
+ "Protocol",
+ "Set the protocol to be implemented",
+ (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_info("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/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h
new file mode 100644
index 0000000..8eb6bac
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.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_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 Multiplexed Protocol instance.
+ */
+struct _ThriftProtocolDecorator
+{
+ ThriftProtocol parent;
+
+ ThriftProtocol *concrete_protocol;
+};
+
+typedef struct _ThriftProtocolDecoratorClass ThriftProtocolDecoratorClass;
+
+/*!
+ * Thrift Multiplexed Protocol class.
+ */
+struct _ThriftProtocolDecoratorClass
+{
+ ThriftProtocolClass parent;
+
+};
+
+/* used by THRIFT_TYPE_PROTOCOL_DECORATOR */
+GType thrift_protocol_decorator_get_type (void);
+
+
+ThriftProtocol *
+thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol);
+
+
+G_END_DECLS
+
+#endif /* _THRIFT_PROTOCOL_DECORATOR_H */