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 */