THRIFT-582 C(c_glib) implementation of Thrift

Patch: Anatol Pomozov and Michael Lum


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1027933 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/c_glib/src/processor/thrift_processor.c b/lib/c_glib/src/processor/thrift_processor.c
new file mode 100644
index 0000000..c5d4034
--- /dev/null
+++ b/lib/c_glib/src/processor/thrift_processor.c
@@ -0,0 +1,50 @@
+#include "thrift.h"
+#include "processor/thrift_processor.h"
+
+/* forward declarations */
+static void thrift_processor_class_init (ThriftProcessorClass *cls);
+
+/* define ThriftProcessorClass's type */
+GType
+thrift_processor_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftProcessorClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_processor_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftProcessor),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "ThriftProcessor",
+                                   &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+/* 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;
+}
+
+gboolean 
+thrift_processor_process (ThriftProcessor *processor, ThriftProtocol *in,
+                          ThriftProtocol *out)
+{
+  return THRIFT_PROCESSOR_GET_CLASS (processor)->process (processor, in, out);
+}
+
diff --git a/lib/c_glib/src/processor/thrift_processor.h b/lib/c_glib/src/processor/thrift_processor.h
new file mode 100644
index 0000000..cc0b006
--- /dev/null
+++ b/lib/c_glib/src/processor/thrift_processor.h
@@ -0,0 +1,59 @@
+#ifndef _THRIFT_PROCESSOR_H
+#define _THRIFT_PROCESSOR_H
+
+#include <glib-object.h>
+
+#include "protocol/thrift_protocol.h"
+
+/*! \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);
+};
+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);
+
+#endif /* _THRIFT_PROCESSOR_H */
diff --git a/lib/c_glib/src/protocol/thrift_binary_protocol.c b/lib/c_glib/src/protocol/thrift_binary_protocol.c
new file mode 100644
index 0000000..afedc9e
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_binary_protocol.c
@@ -0,0 +1,983 @@
+#include <string.h>
+#include <stdio.h>
+
+#include "thrift.h"
+#include "protocol/thrift_protocol.h"
+#include "protocol/thrift_binary_protocol.h"
+
+/* forward declarations */
+static guint64 thrift_bitwise_cast_guint64 (gdouble v);
+static gdouble thrift_bitwise_cast_gdouble (guint64 v);
+static void thrift_binary_protocol_class_init (ThriftProtocolClass *cls);
+
+gint32 thrift_binary_protocol_write_message_begin (ThriftProtocol *protocol, 
+           const gchar *name, const ThriftMessageType message_type,
+           const gint32 seqid, GError **error);
+gint32 thrift_binary_protocol_write_message_end (ThriftProtocol *protocol,
+                                                 GError **error);
+gint32 thrift_binary_protocol_write_struct_begin (ThriftProtocol *protocol,
+                                                  const gchar *name,
+                                                  GError **error);
+gint32 thrift_binary_protocol_write_struct_end (ThriftProtocol *protocol,
+                                                GError **error);
+gint32 thrift_binary_protocol_write_field_begin (ThriftProtocol *protocol,
+                                                 const gchar *name,
+                                                 const ThriftType field_type,
+                                                 const gint16 field_id,
+                                                 GError **error);
+gint32 thrift_binary_protocol_write_field_end (ThriftProtocol *protocol,
+                                               GError **error);
+gint32 thrift_binary_protocol_write_field_stop (ThriftProtocol *protocol,
+                                                GError **error);
+gint32 thrift_binary_protocol_write_map_begin (ThriftProtocol *protocol,
+                                               const ThriftType key_type,
+                                               const ThriftType value_type,
+                                               const guint32 size,
+                                               GError **error);
+gint32 thrift_binary_protocol_write_map_end (ThriftProtocol *protocol,
+                                             GError **error);
+gint32 thrift_binary_protocol_write_list_begin (ThriftProtocol *protocol,
+                                                const ThriftType element_type,
+                                                const guint32 size, 
+                                                GError **error);
+gint32 thrift_binary_protocol_write_list_end (ThriftProtocol *protocol,
+                                              GError **error);
+gint32 thrift_binary_protocol_write_set_begin (ThriftProtocol *protocol,
+                                               const ThriftType element_type,
+                                               const guint32 size, 
+                                               GError **error);
+gint32 thrift_binary_protocol_write_set_end (ThriftProtocol *protocol,
+                                             GError **error);
+gint32 thrift_binary_protocol_write_bool (ThriftProtocol *protocol,
+                                          const gboolean value, GError **error);
+gint32 thrift_binary_protocol_write_byte (ThriftProtocol *protocol,
+                                          const gint8 value, GError **error);
+gint32 thrift_binary_protocol_write_i16 (ThriftProtocol *protocol,
+                                         const gint16 value, GError **error);
+gint32 thrift_binary_protocol_write_i32 (ThriftProtocol *protocol,
+                                         const gint32 value, GError **error);
+gint32 thrift_binary_protocol_write_i64 (ThriftProtocol *protocol,
+                                         const gint64 value, GError **error);
+gint32 thrift_binary_protocol_write_double (ThriftProtocol *protocol,
+                                            const gdouble value,
+                                            GError **error);
+gint32 thrift_binary_protocol_write_string (ThriftProtocol *protocol,
+                                            const gchar *str, GError **error);
+gint32 thrift_binary_protocol_write_binary (ThriftProtocol *protocol,
+                                            const gpointer buf,
+                                            const guint32 len, GError **error);
+gint32 thrift_binary_protocol_read_message_begin (
+           ThriftProtocol *protocol, gchar **name,
+           ThriftMessageType *message_type, gint32 *seqid, GError **error);
+gint32 thrift_binary_protocol_read_message_end (ThriftProtocol *protocol,
+                                                GError **error);
+gint32 thrift_binary_protocol_read_struct_begin (ThriftProtocol *protocol,
+                                                 gchar **name,
+                                                 GError **error);
+gint32 thrift_binary_protocol_read_struct_end (ThriftProtocol *protocol,
+                                               GError **error);
+gint32 thrift_binary_protocol_read_field_begin (ThriftProtocol *protocol,
+                                                gchar **name,
+                                                ThriftType *field_type,
+                                                gint16 *field_id,
+                                                GError **error);
+gint32 thrift_binary_protocol_read_field_end (ThriftProtocol *protocol,
+                                              GError **error);
+gint32 thrift_binary_protocol_read_map_begin (ThriftProtocol *protocol,
+                                              ThriftType *key_type,
+                                              ThriftType *value_type,
+                                              guint32 *size,
+                                              GError **error);
+gint32 thrift_binary_protocol_read_map_end (ThriftProtocol *protocol,
+                                            GError **error);
+gint32 thrift_binary_protocol_read_list_begin (ThriftProtocol *protocol,
+                                               ThriftType *element_type,
+                                               guint32 *size, GError **error);
+gint32 thrift_binary_protocol_read_list_end (ThriftProtocol *protocol,
+                                             GError **error);
+gint32 thrift_binary_protocol_read_set_begin (ThriftProtocol *protocol,
+                                              ThriftType *element_type,
+                                              guint32 *size, GError **error);
+gint32 thrift_binary_protocol_read_set_end (ThriftProtocol *protocol,
+                                            GError **error);
+gint32 thrift_binary_protocol_read_bool (ThriftProtocol *protocol,
+                                         gboolean *value, GError **error);
+gint32 thrift_binary_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
+                                         GError **error);
+gint32 thrift_binary_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
+                                        GError **error);
+gint32 thrift_binary_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
+                                        GError **error);
+gint32 thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
+                                        GError **error);
+gint32 thrift_binary_protocol_read_double (ThriftProtocol *protocol,
+                                           gdouble *value, GError **error);
+gint32 thrift_binary_protocol_read_string (ThriftProtocol *protocol,
+                                           gchar **str, GError **error);
+gint32 thrift_binary_protocol_read_binary (ThriftProtocol *protocol,
+                                           gpointer *buf, guint32 *len,
+                                           GError **error);
+
+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;
+}
+
+GType
+thrift_binary_protocol_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftBinaryProtocolClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_binary_protocol_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftBinaryProtocol),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_PROTOCOL,
+                                   "ThriftBinaryProtocolType",
+                                   &info, 0);
+  }
+
+  return type;
+}
+
+/* initialize the class */
+static void
+thrift_binary_protocol_class_init (ThriftProtocolClass *cls)
+{
+  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;
+}
+
+gint32
+thrift_binary_protocol_write_message_begin (ThriftProtocol *protocol,
+    const gchar *name, const ThriftMessageType message_type,
+    const gint32 seqid, GError **error)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 version = (THRIFT_BINARY_PROTOCOL_VERSION_1)
+                   | ((gint32) message_type);
+  gint32 ret;
+  gint32 xfer = 0;
+
+  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)
+{
+  THRIFT_UNUSED_VAR (name);
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 ret;
+  gint32 xfer = 0;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 ret;
+  gint32 xfer = 0;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); 
+
+  gint32 ret;
+  gint32 xfer = 0;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  guint8 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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint16 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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint64 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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  guint64 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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  guint32 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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gint32 xfer = 0;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 ret;
+  gint32 xfer = 0;
+  gint32 sz;
+
+  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)
+{
+  THRIFT_UNUSED_VAR (name);
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 ret;
+  gint32 xfer = 0;
+  gint8 type;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 ret;
+  gint32 xfer = 0;
+  gint8 k, v;
+  gint32 sizei;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+
+  gint32 ret;
+  gint32 xfer = 0;
+  gint8 e;
+  gint32 sizei;
+
+  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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gpointer b[1];
+
+  if ((ret = 
+       thrift_transport_read (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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gpointer b[1];
+
+  if ((ret =
+       thrift_transport_read (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)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gpointer b[2];
+
+  if ((ret =
+       thrift_transport_read (protocol->transport,
+                              b, 2, error)) < 0)
+  {
+    return -1;
+  }
+  *value = *(gint16 *) b;
+  *value = g_ntohs (*value);
+  return ret;
+}
+
+gint32
+thrift_binary_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
+                                 GError **error)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gpointer b[4];
+
+  if ((ret =
+       thrift_transport_read (protocol->transport,
+                              b, 4, error)) < 0)
+  {
+    return -1;
+  }
+  *value = *(gint32 *) b;
+  *value = g_ntohl (*value);
+  return ret;
+}
+
+gint32
+thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
+                                 GError **error)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gpointer b[8];
+
+  if ((ret =
+       thrift_transport_read (protocol->transport,
+                              b, 8, error)) < 0)
+  {
+    return -1;
+  }
+  *value = *(gint64 *) b;
+  *value = GUINT64_FROM_BE (*value);
+  return ret;
+}
+
+gint32
+thrift_binary_protocol_read_double (ThriftProtocol *protocol,
+                                    gdouble *value, GError **error)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gpointer b[8];
+
+  if ((ret =
+       thrift_transport_read (protocol->transport,
+                              b, 8, error)) < 0)
+  {
+    return -1;
+  }
+  guint64 bits = *(guint64 *) b;
+  bits = GUINT64_FROM_BE (bits);
+  *value = thrift_bitwise_cast_gdouble (bits);
+  return ret;
+}
+
+gint32
+thrift_binary_protocol_read_string (ThriftProtocol *protocol,
+                                    gchar **str, GError **error)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  guint32 len;
+  gint32 ret;
+  gint32 xfer = 0;
+  gint32 read_len = 0;
+
+  /* read the length into read_len */
+  if ((ret =
+       thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
+  {
+    return -1;
+  }
+  xfer += ret;
+
+  if (read_len > 0)
+  {
+    /* allocate the memory for the string */
+    len = (guint32) read_len + 1; // space for null terminator
+    *str = g_new0 (gchar, len);
+    if ((ret =
+         thrift_transport_read (protocol->transport,
+                                *str, read_len, error)) < 0)
+    {
+      g_free (*str);
+      *str = NULL;
+      len = 0;
+      return -1;
+    }
+    xfer += ret;
+  } else {
+    *str = NULL;
+  }
+
+  return xfer;
+}
+
+gint32
+thrift_binary_protocol_read_binary (ThriftProtocol *protocol,
+                                    gpointer *buf, guint32 *len,
+                                    GError **error)
+{
+  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
+  gint32 ret;
+  gint32 xfer = 0;
+  gint32 read_len = 0;
+ 
+  /* 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 (protocol->transport,
+                                *buf, *len, error)) < 0)
+    {
+      g_free (*buf);
+      *buf = NULL;
+      *len = 0;
+      return -1;
+    }
+    xfer += ret;
+  } else {
+    *buf = NULL;
+  }
+
+  return xfer;
+}
+
+
diff --git a/lib/c_glib/src/protocol/thrift_binary_protocol.h b/lib/c_glib/src/protocol/thrift_binary_protocol.h
new file mode 100644
index 0000000..461c524
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_binary_protocol.h
@@ -0,0 +1,55 @@
+#ifndef _THRIFT_BINARY_PROTOCOL_H
+#define _THRIFT_BINARY_PROTOCOL_H
+
+#include <glib-object.h>
+
+#include "protocol/thrift_protocol.h"
+#include "transport/thrift_transport.h"
+
+/*! \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
+
+/*!
+ * Thrift Binary Protocol instance.
+ */
+struct _ThriftBinaryProtocol
+{
+  ThriftProtocol parent;
+};
+typedef struct _ThriftBinaryProtocol ThriftBinaryProtocol;
+
+/*!
+ * Thrift Binary Protocol class.
+ */
+struct _ThriftBinaryProtocolClass
+{
+  ThriftProtocolClass parent;
+};
+typedef struct _ThriftBinaryProtocolClass ThriftBinaryProtocolClass;
+
+/* used by THRIFT_TYPE_BINARY_PROTOCOL */
+GType thrift_binary_protocol_get_type (void);
+
+#endif /* _THRIFT_BINARY_PROTOCOL_H */
diff --git a/lib/c_glib/src/protocol/thrift_binary_protocol_factory.c b/lib/c_glib/src/protocol/thrift_binary_protocol_factory.c
new file mode 100644
index 0000000..a3b4373
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_binary_protocol_factory.c
@@ -0,0 +1,58 @@
+
+#include "thrift.h"
+#include "protocol/thrift_binary_protocol.h"
+#include "protocol/thrift_binary_protocol_factory.h"
+
+/* forward declarations */
+static void thrift_binary_protocol_factory_class_init (ThriftProtocolFactoryClass *cls);
+
+ThriftProtocol *thrift_binary_protocol_factory_get_protocol (ThriftProtocolFactory *factory, ThriftTransport *transport);
+
+GType
+thrift_binary_protocol_factory_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftBinaryProtocolFactoryClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_binary_protocol_factory_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftBinaryProtocolFactory),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_PROTOCOL_FACTORY,
+                                   "ThriftBinaryProtocolFactoryType",
+                                   &info, 0);
+  }
+
+  return type;
+}
+
+static void
+thrift_binary_protocol_factory_class_init (ThriftProtocolFactoryClass *cls)
+{
+  cls->get_protocol = thrift_binary_protocol_factory_get_protocol;
+}
+
+ThriftProtocol *
+thrift_binary_protocol_factory_get_protocol (ThriftProtocolFactory *factory,
+                                             ThriftTransport *transport)
+{
+  THRIFT_UNUSED_VAR (factory);
+
+  ThriftBinaryProtocol *tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
+                                           "transport", transport, NULL);
+
+  return THRIFT_PROTOCOL (tb);
+}
+
+
diff --git a/lib/c_glib/src/protocol/thrift_binary_protocol_factory.h b/lib/c_glib/src/protocol/thrift_binary_protocol_factory.h
new file mode 100644
index 0000000..ae4ae40
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_binary_protocol_factory.h
@@ -0,0 +1,46 @@
+#ifndef _THRIFT_BINARY_PROTOCOL_FACTORY_H
+#define _THRIFT_BINARY_PROTOCOL_FACTORY_H
+
+#include <glib-object.h>
+
+#include "protocol/thrift_protocol_factory.h"
+
+/* 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))
+
+struct _ThriftBinaryProtocolFactory
+{
+  ThriftProtocolFactory parent;
+};
+typedef struct _ThriftBinaryProtocolFactory ThriftBinaryProtocolFactory;
+
+struct _ThriftBinaryProtocolFactoryClass
+{
+  ThriftProtocolFactoryClass parent;
+};
+typedef struct _ThriftBinaryProtocolFactoryClass 
+               ThriftBinaryProtocolFactoryClass;
+
+/* used by THRIFT_TYPE_BINARY_PROTOCOL_FACTORY */
+GType thrift_binary_protocol_factory_get_type (void);
+
+#endif /* _THRIFT_BINARY_PROTOCOL_FACTORY_H */
diff --git a/lib/c_glib/src/protocol/thrift_protocol.c b/lib/c_glib/src/protocol/thrift_protocol.c
new file mode 100644
index 0000000..8ea54b6
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_protocol.c
@@ -0,0 +1,604 @@
+#include "thrift.h"
+#include "protocol/thrift_protocol.h"
+#include "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
+};
+
+/* forward declarations */
+static void thrift_protocol_instance_init (ThriftProtocol *protocol);
+static void thrift_protocol_class_init (ThriftProtocolClass *cls);
+void thrift_protocol_get_property (GObject *object, guint property_id,
+                                   GValue *value, GParamSpec *pspec);
+void thrift_protocol_set_property (GObject *object, guint property_id,
+                                   const GValue *value, GParamSpec *pspec);
+
+/* define ThriftProtocolInterface's type */
+GType
+thrift_protocol_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info = {
+      sizeof (ThriftProtocolClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_protocol_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftProtocol),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_protocol_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "ThriftProtocol",
+                                   &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+static void
+thrift_protocol_instance_init (ThriftProtocol *protocol)
+{
+  protocol->transport = NULL;
+}
+
+static void
+thrift_protocol_class_init (ThriftProtocolClass *cls)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+
+  gobject_class->get_property = thrift_protocol_get_property;
+  gobject_class->set_property = thrift_protocol_set_property;
+
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_PROTOCOL_TRANSPORT,
+      g_param_spec_object ("transport", "Transport", "Thrift Transport",
+                           THRIFT_TYPE_TRANSPORT,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  cls->write_message_begin = thrift_protocol_write_message_begin;
+  cls->write_message_end = thrift_protocol_write_message_end;
+  cls->write_struct_begin = thrift_protocol_write_struct_begin;
+  cls->write_struct_end = thrift_protocol_write_struct_end;
+  cls->write_field_begin = thrift_protocol_write_field_begin;
+  cls->write_field_end = thrift_protocol_write_field_end;
+  cls->write_field_stop = thrift_protocol_write_field_stop;
+  cls->write_map_begin = thrift_protocol_write_map_begin;
+  cls->write_map_end = thrift_protocol_write_map_end;
+  cls->write_list_begin = thrift_protocol_write_list_begin;
+  cls->write_list_end = thrift_protocol_write_list_end;
+  cls->write_set_begin = thrift_protocol_write_set_begin;
+  cls->write_set_end = thrift_protocol_write_set_end;
+  cls->write_bool = thrift_protocol_write_bool;
+  cls->write_byte = thrift_protocol_write_byte;
+  cls->write_i16 = thrift_protocol_write_i16;
+  cls->write_i32 = thrift_protocol_write_i32;
+  cls->write_i64 = thrift_protocol_write_i64;
+  cls->write_double = thrift_protocol_write_double;
+  cls->write_string = thrift_protocol_write_string;
+  cls->write_binary = thrift_protocol_write_binary;
+  cls->read_message_begin = thrift_protocol_read_message_begin;
+  cls->read_message_end = thrift_protocol_read_message_end;
+  cls->read_struct_begin = thrift_protocol_read_struct_begin;
+  cls->read_struct_end = thrift_protocol_read_struct_end;
+  cls->read_field_begin = thrift_protocol_read_field_begin;
+  cls->read_field_end = thrift_protocol_read_field_end;
+  cls->read_map_begin = thrift_protocol_read_map_begin;
+  cls->read_map_end = thrift_protocol_read_map_end;
+  cls->read_list_begin = thrift_protocol_read_list_begin;
+  cls->read_set_begin = thrift_protocol_read_set_begin;
+  cls->read_set_end = thrift_protocol_read_set_end;
+  cls->read_bool = thrift_protocol_read_bool;
+  cls->read_byte = thrift_protocol_read_byte;
+  cls->read_i16 = thrift_protocol_read_i16;
+  cls->read_i32 = thrift_protocol_read_i32;
+  cls->read_i64 = thrift_protocol_read_i64;
+  cls->read_double = thrift_protocol_read_double;
+  cls->read_string = thrift_protocol_read_string;
+  cls->read_binary = thrift_protocol_read_binary;
+}
+
+void
+thrift_protocol_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
+{
+  ThriftProtocol *protocol = THRIFT_PROTOCOL (object);
+
+  THRIFT_UNUSED_VAR (pspec);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_PROTOCOL_TRANSPORT:
+      g_value_set_object (value, protocol->transport);
+      break;
+  }
+}
+
+void
+thrift_protocol_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
+{
+
+  ThriftProtocol *protocol = THRIFT_PROTOCOL (object);
+
+  THRIFT_UNUSED_VAR (pspec);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_PROTOCOL_TRANSPORT:
+      protocol->transport = g_value_get_object (value);
+      break;
+  }
+}
+
+
+gint32
+thrift_protocol_write_message_begin (ThriftProtocol *protocol, 
+                                     const gchar *name, 
+                                     const ThriftMessageType message_type,
+                                     const gint32 seqid, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_message_begin
+                                                   (protocol, name,
+                                                    message_type, seqid,
+                                                    error);
+}
+
+gint32
+thrift_protocol_write_message_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_message_end (protocol,
+                                                                  error);
+}
+
+gint32
+thrift_protocol_write_struct_begin (ThriftProtocol *protocol, const gchar *name,
+                                    GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_struct_begin (protocol,
+                                                   name, error);
+}
+
+gint32
+thrift_protocol_write_struct_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_struct_end (protocol,
+                                                                 error);
+}
+
+gint32
+thrift_protocol_write_field_begin (ThriftProtocol *protocol,
+                                   const gchar *name,
+                                   const ThriftType field_type,
+                                   const gint16 field_id,
+                                   GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_begin (protocol,
+                                                   name, field_type,
+                                                   field_id, error);
+}
+
+gint32
+thrift_protocol_write_field_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_end (protocol,
+                                                                error);
+}
+
+gint32
+thrift_protocol_write_field_stop (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_stop (protocol,
+                                                                 error);
+}
+
+gint32
+thrift_protocol_write_map_begin (ThriftProtocol *protocol,
+                                 const ThriftType key_type,
+                                 const ThriftType value_type,
+                                 const guint32 size, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_map_begin (protocol,
+                                                   key_type, value_type,
+                                                   size, error);
+}
+
+gint32
+thrift_protocol_write_map_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_map_end (protocol,
+                                                              error);
+}
+
+gint32
+thrift_protocol_write_list_begin (ThriftProtocol *protocol,
+                                  const ThriftType element_type,
+                                  const guint32 size, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_list_begin (protocol,
+                                                   element_type, size,
+                                                   error);
+}
+
+gint32
+thrift_protocol_write_list_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_list_end (protocol,
+                                                               error);
+}
+
+gint32
+thrift_protocol_write_set_begin (ThriftProtocol *protocol,
+                                 const ThriftType element_type,
+                                 const guint32 size, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_set_begin (protocol,
+                                                   element_type, size,
+                                                   error);
+}
+
+gint32
+thrift_protocol_write_set_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_set_end (protocol,
+                                                              error);
+}
+
+gint32
+thrift_protocol_write_bool (ThriftProtocol *protocol,
+                            const gboolean value, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_bool (protocol, value,
+                                                           error);
+}
+
+gint32
+thrift_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
+                            GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_byte (protocol, value,
+                                                           error);
+}
+
+gint32
+thrift_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
+                           GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i16 (protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
+                           GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i32 (protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
+                           GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i64 (protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_write_double (ThriftProtocol *protocol,
+                              const gdouble value, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_double (protocol,
+                                                             value, error);
+}
+
+gint32
+thrift_protocol_write_string (ThriftProtocol *protocol,
+                              const gchar *str, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_string (protocol, str,
+                                                             error);
+}
+
+gint32
+thrift_protocol_write_binary (ThriftProtocol *protocol, const gpointer buf,
+                              const guint32 len, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_binary (protocol, buf,
+                                                             len, error);
+}
+
+gint32 
+thrift_protocol_read_message_begin (ThriftProtocol *protocol,
+                                    gchar **name,
+                                    ThriftMessageType *message_type,
+                                    gint32 *seqid, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_message_begin (protocol,
+                                                   name, message_type,
+                                                   seqid, error);
+}
+
+gint32 
+thrift_protocol_read_message_end (ThriftProtocol *protocol,
+                                  GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_message_end (protocol,
+                                                                 error);
+}
+
+gint32 
+thrift_protocol_read_struct_begin (ThriftProtocol *protocol,
+                                   gchar **name,
+                                   GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_struct_begin (protocol,
+                                                                  name,
+                                                                  error);
+}
+
+gint32
+thrift_protocol_read_struct_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_struct_end (protocol,
+                                                                error);
+}
+
+gint32 
+thrift_protocol_read_field_begin (ThriftProtocol *protocol,
+                                  gchar **name,
+                                  ThriftType *field_type,
+                                  gint16 *field_id,
+                                  GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_field_begin (protocol,
+                                                                 name,
+                                                                 field_type,
+                                                                 field_id,
+                                                                 error);
+}
+
+gint32 
+thrift_protocol_read_field_end (ThriftProtocol *protocol,
+                                GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_field_end (protocol,
+                                                               error);
+}
+
+gint32 
+thrift_protocol_read_map_begin (ThriftProtocol *protocol,
+                                ThriftType *key_type,
+                                ThriftType *value_type, guint32 *size,
+                                GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_map_begin (protocol,
+                                                               key_type,
+                                                               value_type,
+                                                               size,
+                                                               error); 
+}
+
+gint32 
+thrift_protocol_read_map_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_map_end (protocol,
+                                                             error);
+}
+
+gint32 
+thrift_protocol_read_list_begin (ThriftProtocol *protocol,
+                                 ThriftType *element_type,
+                                 guint32 *size, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_list_begin (protocol,
+                                                                element_type,
+                                                                size, error);
+}
+
+gint32
+thrift_protocol_read_list_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_list_end (protocol,
+                                                              error);
+}
+
+gint32
+thrift_protocol_read_set_begin (ThriftProtocol *protocol,
+                                ThriftType *element_type,
+                                guint32 *size, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_set_begin (protocol,
+                                                               element_type,
+                                                               size, error);
+}
+
+gint32
+thrift_protocol_read_set_end (ThriftProtocol *protocol, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_set_end (protocol,
+                                                             error);
+}
+
+gint32
+thrift_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
+                           GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_bool (protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
+                           GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_byte (protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
+                          GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i16 (protocol, value,
+                                                         error);
+}
+
+gint32
+thrift_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
+                          GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i32 (protocol, value,
+                                                         error);
+}
+
+gint32
+thrift_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
+                          GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i64 (protocol, value,
+                                                         error);
+}
+
+gint32
+thrift_protocol_read_double (ThriftProtocol *protocol,
+                             gdouble *value, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_double (protocol, value,
+                                                            error);
+}
+
+gint32
+thrift_protocol_read_string (ThriftProtocol *protocol,
+                             gchar **str, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_string (protocol, str,
+                                                            error);
+}
+
+gint32
+thrift_protocol_read_binary (ThriftProtocol *protocol, gpointer *buf, 
+                             guint32 *len, GError **error)
+{
+  return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_binary (protocol, buf,
+                                                            len, error);
+}
+
+gint32
+thrift_protocol_skip (ThriftProtocol *protocol, ThriftType type, GError **error)
+{
+  switch (type)
+  {
+    case T_BOOL:
+      {
+        gboolean boolv;
+        return thrift_protocol_read_bool (protocol, &boolv, error);
+      }
+    case T_BYTE:
+      {
+        gint8 bytev;
+        return thrift_protocol_read_byte (protocol, &bytev, error);
+      }
+
+    case T_I16:
+      {
+        gint16 i16;
+        return thrift_protocol_read_i16 (protocol, &i16, error);
+      }
+    case T_I32:
+      {
+        gint32 i32;
+        return thrift_protocol_read_i32 (protocol, &i32, error);
+      }
+    case T_I64:
+      {
+        gint64 i64;
+        return thrift_protocol_read_i64 (protocol, &i64, error);
+      }
+    case T_DOUBLE:
+      {
+        gdouble dub;
+        return thrift_protocol_read_double (protocol, &dub, error);
+      }
+    case T_STRING:
+      {
+        gpointer data;
+        guint32 len;
+        gint32 ret = thrift_protocol_read_binary (protocol, &data, &len, error);
+        g_free (data);
+        return ret;
+      }
+    case T_STRUCT:
+      {
+        guint32 result = 0;
+        gchar *name;
+        gint16 fid;
+        ThriftType ftype;
+        result += thrift_protocol_read_struct_begin (protocol, &name, error);
+
+        while (1)
+        {
+          result += thrift_protocol_read_field_begin (protocol, &name, &ftype,
+                                                      &fid, error);
+          if (ftype == T_STOP)
+          {
+            break;
+          }
+          result += thrift_protocol_skip (protocol, ftype, error);
+          result += thrift_protocol_read_field_end (protocol, error);
+        }
+        result += thrift_protocol_read_struct_end (protocol, error);
+        return result;
+      }
+    case T_MAP:
+      {
+        guint32 result = 0;
+        ThriftType elem_type;
+        guint32 i, size;
+        result += thrift_protocol_read_set_begin (protocol, &elem_type, &size,
+                                                  error);
+        for (i = 0; i < size; i++)
+        {
+          result += thrift_protocol_skip (protocol, elem_type, error);
+        }
+        result += thrift_protocol_read_set_end (protocol, error);
+        return result;
+      }
+    case T_LIST:
+      {
+        guint32 result = 0;
+        ThriftType elem_type;
+        guint32 i, size;
+        result += thrift_protocol_read_list_begin (protocol, &elem_type, &size,
+                                                   error);
+        for (i = 0; i < size; i++)
+        {
+          result += thrift_protocol_skip (protocol, elem_type, error);
+        }
+        result += thrift_protocol_read_list_end (protocol, error);
+        return result;
+      }
+    default:
+      return 0;
+  }
+}
+
+/* define the GError domain for Thrift protocols */
+GQuark
+thrift_protocol_error_quark (void)
+{
+  return g_quark_from_static_string (THRIFT_PROTOCOL_ERROR_DOMAIN);
+}
+
diff --git a/lib/c_glib/src/protocol/thrift_protocol.h b/lib/c_glib/src/protocol/thrift_protocol.h
new file mode 100644
index 0000000..0340a60
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_protocol.h
@@ -0,0 +1,324 @@
+#ifndef _THRIFT_PROTOCOL_H
+#define _THRIFT_PROTOCOL_H
+
+#include <glib-object.h>
+
+#include "transport/thrift_transport.h"
+
+/**
+ * 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.
+ */
+enum _ThriftType {
+  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
+};
+typedef enum _ThriftType ThriftType;
+
+/**
+ * Enumerated definition of the message types that the Thrift protocol
+ * supports.
+ */
+enum _ThriftMessageType {
+  T_CALL      = 1,
+  T_REPLY     = 2,
+  T_EXCEPTION = 3,
+  T_ONEWAY    = 4
+};
+typedef enum _ThriftMessageType ThriftMessageType;
+
+/*! \file thrift_protocol.h
+ *  \brief Abstract class for Thrift protocol implementations.
+ */
+
+/* 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))
+
+/*!
+ * Thrift Protocol object
+ */
+struct _ThriftProtocol
+{
+  GObject parent;
+
+  /* protected */
+  ThriftTransport *transport;
+};
+typedef struct _ThriftProtocol ThriftProtocol;
+
+/*!
+ * 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);
+};
+typedef struct _ThriftProtocolClass ThriftProtocolClass;
+
+/* 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
+} ThriftProtocolError;
+
+/* define an error domain for GError to use */
+GQuark thrift_protocol_error_quark (void);
+#define THRIFT_PROTOCOL_ERROR (thrift_protocol_error_quark ())
+
+#endif /* _THRIFT_PROTOCOL_H */
diff --git a/lib/c_glib/src/protocol/thrift_protocol_factory.c b/lib/c_glib/src/protocol/thrift_protocol_factory.c
new file mode 100644
index 0000000..53b468d
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_protocol_factory.c
@@ -0,0 +1,50 @@
+#include "thrift.h"
+#include "protocol/thrift_protocol_factory.h"
+
+/* forward declarations */
+static void thrift_protocol_factory_class_init (ThriftProtocolFactoryClass *cls);
+ThriftProtocol *thrift_protocol_factory_get_protocol(ThriftProtocolFactory *factory, ThriftTransport *transport);
+
+
+/* define ThriftProtocolFactoryInterface's type */
+GType
+thrift_protocol_factory_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info = {
+      sizeof (ThriftProtocolFactoryClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_protocol_factory_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftProtocolFactory),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "ThriftProtocolFactory",
+                                   &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+static void
+thrift_protocol_factory_class_init (ThriftProtocolFactoryClass *cls)
+{
+  cls->get_protocol = thrift_protocol_factory_get_protocol;
+}
+
+ThriftProtocol *
+thrift_protocol_factory_get_protocol(ThriftProtocolFactory *factory,
+                                     ThriftTransport *transport)
+{
+  return THRIFT_PROTOCOL_FACTORY_GET_CLASS (factory)->get_protocol (factory,
+                                                                    transport);
+}
+
diff --git a/lib/c_glib/src/protocol/thrift_protocol_factory.h b/lib/c_glib/src/protocol/thrift_protocol_factory.h
new file mode 100644
index 0000000..d153255
--- /dev/null
+++ b/lib/c_glib/src/protocol/thrift_protocol_factory.h
@@ -0,0 +1,57 @@
+#ifndef _THRIFT_PROTOCOL_FACTORY_H
+#define _THRIFT_PROTOCOL_FACTORY_H
+
+#include <glib-object.h>
+
+#include "transport/thrift_transport.h"
+#include "protocol/thrift_protocol.h"
+
+/*! \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))
+
+/*!
+ * Thrift Protocol Factory object
+ */
+struct _ThriftProtocolFactory
+{
+  GObject parent;
+};
+typedef struct _ThriftProtocolFactory ThriftProtocolFactory;
+
+/*!
+ * Thrift Protocol Factory class
+ */
+struct _ThriftProtocolFactoryClass
+{
+  GObjectClass parent;
+
+  ThriftProtocol *(*get_protocol) (ThriftProtocolFactory *factory,
+                                   ThriftTransport *transport);
+};
+typedef struct _ThriftProtocolFactoryClass ThriftProtocolFactoryClass;
+
+/* 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);
+
+#endif /* _THRIFT_PROTOCOL_FACTORY_H */
diff --git a/lib/c_glib/src/server/thrift_server.c b/lib/c_glib/src/server/thrift_server.c
new file mode 100644
index 0000000..c7e6c1f
--- /dev/null
+++ b/lib/c_glib/src/server/thrift_server.c
@@ -0,0 +1,192 @@
+#include "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
+};
+
+/* forward declarations */
+static void thrift_server_instance_init (ThriftServer *server);
+static void thrift_server_class_init (ThriftServerClass *cls);
+void thrift_server_get_property (GObject *object, guint property_id,
+                                 GValue *value, GParamSpec *pspec);
+void thrift_server_set_property (GObject *object, guint property_id,
+                                 const GValue *value, GParamSpec *pspec);
+
+
+/* define ThriftServerClass's type */
+GType
+thrift_server_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftServerClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_server_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftServer),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_server_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "ThriftServer",
+                                   &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+/* instance initializer for Thrift Server */
+static void
+thrift_server_instance_init (ThriftServer *server)
+{
+  server->processor = NULL;
+  server->server_transport = NULL;
+  server->input_transport_factory = NULL;
+  server->output_transport_factory = NULL;
+  server->input_protocol_factory = NULL;
+  server->output_protocol_factory = NULL;
+}
+
+/* class initializer for ThriftServer
+ * TODO: implement ServerEventHandler as a GClosure
+ */
+static void
+thrift_server_class_init (ThriftServerClass *cls)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+
+  gobject_class->get_property = thrift_server_get_property;
+  gobject_class->set_property = thrift_server_set_property;
+
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_SERVER_PROCESSOR,
+      g_param_spec_object ("processor", "Processor", "Thrift Processor",
+                           THRIFT_TYPE_PROCESSOR,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_SERVER_SERVER_TRANSPORT,
+      g_param_spec_object ("server_transport", "Server Transport",
+                           "Thrift Server Transport",
+                           THRIFT_TYPE_SERVER_TRANSPORT,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY,
+      g_param_spec_object ("input_transport_factory", "Input Transport Factory",
+                           "Thrift Server Input Transport Factory",
+                           THRIFT_TYPE_TRANSPORT_FACTORY,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY,
+      g_param_spec_object ("output_transport_factory",
+                           "Output Transport Factory",
+                           "Thrift Server Output Transport Factory",
+                           THRIFT_TYPE_TRANSPORT_FACTORY,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY,
+      g_param_spec_object ("input_protocol_factory", "Input Protocol Factory",
+                           "Thrift Server Input Protocol Factory",
+                           THRIFT_TYPE_PROTOCOL_FACTORY,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (gobject_class,
+      PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY,
+      g_param_spec_object ("output_protocol_factory", "Output Protocol Factory",
+                           "Thrift Server Output Protocol Factory",
+                           THRIFT_TYPE_PROTOCOL_FACTORY,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  /* set these as virtual methods to be implemented by a subclass */
+  cls->serve = thrift_server_serve;
+  cls->stop = thrift_server_stop;
+}
+
+void
+thrift_server_get_property (GObject *object, guint property_id,
+                            GValue *value, GParamSpec *pspec)
+{
+  ThriftServer *server = THRIFT_SERVER (object);
+
+  THRIFT_UNUSED_VAR (pspec);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_SERVER_PROCESSOR:
+      g_value_set_object (value, server->processor);
+      break;
+    case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
+      g_value_set_object (value, server->server_transport);
+      break;
+    case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
+      g_value_set_object (value, server->input_transport_factory);
+      break;
+    case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
+      g_value_set_object (value, server->output_transport_factory);
+      break;
+    case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
+      g_value_set_object (value, server->input_protocol_factory);
+      break;
+    case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
+      g_value_set_object (value, server->output_protocol_factory);
+      break;
+  }
+}
+
+void
+thrift_server_set_property (GObject *object, guint property_id,
+                            const GValue *value, GParamSpec *pspec)
+{
+  ThriftServer *server = THRIFT_SERVER (object);
+
+  THRIFT_UNUSED_VAR (pspec);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_SERVER_PROCESSOR:
+      server->processor = g_value_get_object (value);
+      break;
+    case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
+      server->server_transport = g_value_get_object (value);
+      break;
+    case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
+      server->input_transport_factory = g_value_get_object (value);
+      break;
+    case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
+      server->output_transport_factory = g_value_get_object (value);
+      break;
+    case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
+      server->input_protocol_factory = g_value_get_object (value);
+      break;
+    case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
+      server->output_protocol_factory = g_value_get_object (value);
+      break;
+  }
+}
+
+void
+thrift_server_serve (ThriftServer *server)
+{
+  THRIFT_SERVER_GET_CLASS (server)->serve (server);
+}
+
+void
+thrift_server_stop (ThriftServer *server)
+{
+  THRIFT_SERVER_GET_CLASS (server)->stop (server);
+}
+
diff --git a/lib/c_glib/src/server/thrift_server.h b/lib/c_glib/src/server/thrift_server.h
new file mode 100644
index 0000000..2bbe95b
--- /dev/null
+++ b/lib/c_glib/src/server/thrift_server.h
@@ -0,0 +1,75 @@
+#ifndef _THRIFT_SERVER_H
+#define _THRIFT_SERVER_H
+
+#include <glib-object.h>
+
+#include "processor/thrift_processor.h"
+#include "transport/thrift_server_transport.h"
+#include "transport/thrift_transport_factory.h"
+#include "protocol/thrift_protocol_factory.h"
+
+/*! \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))
+
+/*!
+ * 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 _ThriftServer ThriftServer;
+
+/*!
+ * Thrift Server class
+ */
+struct _ThriftServerClass
+{
+  GObjectClass parent;
+
+  /* vtable */
+  void (*serve) (ThriftServer *server);
+  void (*stop) (ThriftServer *server);
+};
+typedef struct _ThriftServerClass ThriftServerClass;
+
+/* used by THRIFT_TYPE_SERVER */
+GType thrift_server_get_type (void); 
+
+/*!
+ * Processes the request.
+ * \public \memberof ThriftServerClass
+ */
+void thrift_server_serve (ThriftServer *server);
+
+/*!
+ * Stop handling requests.
+ */
+void thrift_server_stop (ThriftServer *server);
+
+#endif /* _THRIFT_SERVER_H */
+
diff --git a/lib/c_glib/src/server/thrift_simple_server.c b/lib/c_glib/src/server/thrift_simple_server.c
new file mode 100644
index 0000000..1957928
--- /dev/null
+++ b/lib/c_glib/src/server/thrift_simple_server.c
@@ -0,0 +1,133 @@
+
+#include "server/thrift_simple_server.h"
+#include "transport/thrift_transport_factory.h"
+#include "protocol/thrift_protocol_factory.h"
+#include "protocol/thrift_binary_protocol_factory.h"
+
+static void thrift_simple_server_instance_init (ThriftServer *server);
+static void thrift_simple_server_class_init (ThriftServerClass *cls);
+
+/* forward declarations */
+void thrift_simple_server_serve (ThriftServer *server);
+void thrift_simple_server_stop (ThriftServer *server);
+
+GType
+thrift_simple_server_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftSimpleServerClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_simple_server_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftSimpleServer),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_simple_server_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_SERVER,
+                                   "ThriftSimpleServerType",
+                                   &info, 0);
+  }
+
+  return type;
+}
+
+static void
+thrift_simple_server_instance_init (ThriftServer *server)
+{
+  (THRIFT_SIMPLE_SERVER (server))->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 (ThriftServerClass *cls)
+{
+  cls->serve = thrift_simple_server_serve;
+  cls->stop = thrift_simple_server_stop;
+}
+
+void
+thrift_simple_server_serve (ThriftServer *server)
+{
+  g_return_if_fail (THRIFT_IS_SIMPLE_SERVER (server));
+
+  ThriftTransport *t = NULL;
+  ThriftTransport *input_transport = NULL, *output_transport = NULL;
+  ThriftProtocol *input_protocol = NULL, *output_protocol = NULL;
+  ThriftSimpleServer *tss = THRIFT_SIMPLE_SERVER (server);
+
+  THRIFT_SERVER_TRANSPORT_GET_CLASS (server->server_transport)
+      ->listen (server->server_transport, NULL);
+
+  tss->running = TRUE;
+  while (tss->running == TRUE)
+  {
+    t = thrift_server_transport_accept (server->server_transport, NULL);
+    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, t);
+    output_protocol =
+        THRIFT_PROTOCOL_FACTORY_GET_CLASS (server->output_protocol_factory)
+            ->get_protocol (server->output_protocol_factory, t);
+
+    while (THRIFT_PROCESSOR_GET_CLASS (server->processor)
+               ->process (server->processor, input_protocol, output_protocol))
+    {
+      // TODO: implement transport peek ()
+    }
+
+    // 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); 
+}
+
+void
+thrift_simple_server_stop (ThriftServer *server)
+{
+  g_return_if_fail (THRIFT_IS_SIMPLE_SERVER (server));
+  (THRIFT_SIMPLE_SERVER (server))->running = FALSE;
+}
+
+
diff --git a/lib/c_glib/src/server/thrift_simple_server.h b/lib/c_glib/src/server/thrift_simple_server.h
new file mode 100644
index 0000000..137f623
--- /dev/null
+++ b/lib/c_glib/src/server/thrift_simple_server.h
@@ -0,0 +1,53 @@
+#ifndef _THRIFT_SIMPLE_SERVER_H
+#define _THRIFT_SIMPLE_SERVER_H
+
+#include <glib-object.h>
+
+#include "server/thrift_server.h"
+
+/*! \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))
+
+/**
+ * Thrift Simple Server instance.
+ */
+struct _ThriftSimpleServer
+{
+  ThriftServer parent;
+
+  /* private */
+  volatile gboolean running;
+};
+typedef struct _ThriftSimpleServer ThriftSimpleServer;
+
+/**
+ * Thrift Simple Server class.
+ */
+struct _ThriftSimpleServerClass
+{
+  ThriftServerClass parent;
+};
+typedef struct _ThriftSimpleServerClass ThriftSimpleServerClass;
+
+/* used by THRIFT_TYPE_SIMPLE_SERVER */
+GType thrift_simple_server_get_type (void);
+
+#endif /* _THRIFT_SIMPLE_SERVER_H */
+
diff --git a/lib/c_glib/src/thrift.c b/lib/c_glib/src/thrift.c
new file mode 100644
index 0000000..18a36aa
--- /dev/null
+++ b/lib/c_glib/src/thrift.c
@@ -0,0 +1,13 @@
+#include "thrift.h"
+
+/**
+ * GHashTable callback to add keys to a GList.
+ */
+void
+thrift_hash_table_get_keys (gpointer key, gpointer value, gpointer user_data)
+{
+  THRIFT_UNUSED_VAR (value);
+  GList **list = (GList **) user_data;
+  *list = g_list_append (*list, key);
+}
+
diff --git a/lib/c_glib/src/thrift.h b/lib/c_glib/src/thrift.h
new file mode 100644
index 0000000..59db6fd
--- /dev/null
+++ b/lib/c_glib/src/thrift.h
@@ -0,0 +1,18 @@
+#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);
+
+#endif // #ifndef _THRIFT_THRIFT_H
diff --git a/lib/c_glib/src/thrift_application_exception.c b/lib/c_glib/src/thrift_application_exception.c
new file mode 100644
index 0000000..fa57a81
--- /dev/null
+++ b/lib/c_glib/src/thrift_application_exception.c
@@ -0,0 +1,192 @@
+#include "thrift_application_exception.h"
+#include "protocol/thrift_protocol.h"
+
+/* forward declarations */
+void thrift_application_exception_instance_init (ThriftApplicationException *object);
+void thrift_application_exception_class_init (ThriftStructClass *cls);
+gint32 thrift_application_exception_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error);
+gint32 thrift_application_exception_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error);
+
+GType
+thrift_application_exception_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo type_info =
+    {
+      sizeof (ThriftApplicationExceptionClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_application_exception_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftApplicationException),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_application_exception_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_STRUCT,
+                                   "ThriftApplicationExceptionType",
+                                   &type_info, 0);
+  }
+  return type;
+}
+
+void
+thrift_application_exception_instance_init (ThriftApplicationException *object)
+{
+  object->type = 0;
+  object->__isset_type = FALSE;
+  object->message = NULL;
+  object->__isset_message = FALSE;
+}
+
+void
+thrift_application_exception_class_init (ThriftStructClass *cls)
+{
+  cls->read = thrift_application_exception_read;
+  cls->write = thrift_application_exception_write;
+}
+
+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);
+}
+
diff --git a/lib/c_glib/src/thrift_application_exception.h b/lib/c_glib/src/thrift_application_exception.h
new file mode 100644
index 0000000..8639df2
--- /dev/null
+++ b/lib/c_glib/src/thrift_application_exception.h
@@ -0,0 +1,67 @@
+#ifndef _THRIFT_APPLICATION_EXCEPTION_H
+#define _THRIFT_APPLICATION_EXCEPTION_H
+
+#include <glib-object.h>
+#include "thrift_struct.h"
+
+/*! \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))
+
+struct _ThriftApplicationException
+{
+  ThriftStruct parent;
+
+  /* public */
+  gint32 type;
+  gboolean __isset_type;
+  gchar *message;
+  gboolean __isset_message;
+};
+typedef struct _ThriftApplicationException ThriftApplicationException;
+
+struct _ThriftApplicationExceptionClass
+{
+  ThriftStructClass parent;
+};
+typedef struct _ThriftApplicationExceptionClass ThriftApplicationExceptionClass;
+
+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
+} ThriftApplicationExceptionError;
+
+/* define error domain for GError */
+GQuark thrift_application_exception_error_quark (void);
+#define THRIFT_APPLICATION_EXCEPTION_ERROR (thrift_application_exception_error_quark ())
+
+#endif /* _THRIFT_APPLICATION_EXCEPTION_H */
diff --git a/lib/c_glib/src/thrift_struct.c b/lib/c_glib/src/thrift_struct.c
new file mode 100644
index 0000000..3f73c38
--- /dev/null
+++ b/lib/c_glib/src/thrift_struct.c
@@ -0,0 +1,55 @@
+#include "thrift_struct.h"
+
+static void
+thrift_struct_class_init (ThriftStructClass *cls)
+{
+  ThriftStructClass *c = THRIFT_STRUCT_CLASS (cls);
+  c->read = thrift_struct_read;
+  c->write = thrift_struct_write;
+}
+
+GType
+thrift_struct_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo type_info =
+      {
+        sizeof (ThriftStructClass),
+        NULL, /* base_init */
+        NULL, /* base finalize */
+        (GClassInitFunc) thrift_struct_class_init,
+        NULL, /* class finalize */
+        NULL, /* class data */
+        sizeof (ThriftStruct),
+        0, /* n_preallocs */
+        NULL, /* instance_init */
+        NULL, /* value_table */
+      };
+
+    type = g_type_register_static (G_TYPE_OBJECT,
+                                   "ThriftStructType",
+                                   &type_info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+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);
+}
+
diff --git a/lib/c_glib/src/thrift_struct.h b/lib/c_glib/src/thrift_struct.h
new file mode 100644
index 0000000..f3e6060
--- /dev/null
+++ b/lib/c_glib/src/thrift_struct.h
@@ -0,0 +1,50 @@
+#ifndef THRIFT_STRUCT_H
+#define THRIFT_STRUCT_H
+
+#include <glib-object.h>
+
+#include "protocol/thrift_protocol.h"
+
+#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))
+
+/* struct */
+struct _ThriftStruct
+{
+  GObject parent;
+
+  /* private */
+};
+typedef struct _ThriftStruct ThriftStruct;
+
+struct _ThriftStructClass
+{
+  GObjectClass parent;
+
+  /* public */
+  gint32 (*read) (ThriftStruct *object, ThriftProtocol *protocol,
+                  GError **error);
+  gint32 (*write) (ThriftStruct *object, ThriftProtocol *protocol,
+                   GError **error);
+};
+typedef struct _ThriftStructClass ThriftStructClass;
+
+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);
+
+#endif
diff --git a/lib/c_glib/src/transport/thrift_buffered_transport.c b/lib/c_glib/src/transport/thrift_buffered_transport.c
new file mode 100644
index 0000000..45ea31c
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_buffered_transport.c
@@ -0,0 +1,406 @@
+#include <assert.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "thrift.h"
+#include "transport/thrift_transport.h"
+#include "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
+};
+
+/* forward declarations */
+static void thrift_buffered_transport_instance_init (ThriftBufferedTransport *self);
+static void thrift_buffered_transport_class_init (ThriftBufferedTransportClass *cls);
+
+
+gboolean thrift_buffered_transport_is_open (ThriftTransport *transport);
+gboolean thrift_buffered_transport_open (ThriftTransport *transport,
+                                         GError **error);
+gboolean thrift_buffered_transport_close (ThriftTransport *transport,
+                                          GError **error);
+gint32 thrift_buffered_transport_read (ThriftTransport *transport, gpointer buf,
+                                       guint32 len, GError **error);
+gboolean thrift_buffered_transport_read_end (ThriftTransport *transport,
+                                             GError **error);
+gint32 thrift_buffered_transport_read_slow (ThriftTransport *transport,
+                                            gpointer buf, guint32 len,
+                                            GError **error);
+gboolean thrift_buffered_transport_write (ThriftTransport *transport,
+                                          const gpointer buf,
+                                          const guint32 len, GError **error);
+gboolean thrift_buffered_transport_write_end (ThriftTransport *transport,
+                                              GError **error);
+gint32 thrift_buffered_transport_write_slow (ThriftTransport *transport, 
+                                             gpointer buf, guint32 len, 
+                                             GError **error);
+gboolean thrift_buffered_transport_flush (ThriftTransport *transport,
+                                          GError **error);
+
+GType
+thrift_buffered_transport_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftBufferedTransportClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_buffered_transport_class_init,
+      NULL, /* class finalize */
+      NULL, /* class data */
+      sizeof (ThriftBufferedTransport),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_buffered_transport_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_TRANSPORT,
+                                   "ThriftBufferedTransport", &info, 0);
+  }
+
+  return type;
+}
+
+/* initializes the instance */
+static void
+thrift_buffered_transport_instance_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)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object);
+
+  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)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object);
+
+  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)
+{
+  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);
+
+
+  ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
+
+  gobject_class->finalize = thrift_buffered_transport_finalize;
+  ttc->is_open = thrift_buffered_transport_is_open;
+  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;
+}
+
+/* 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);
+}
+
+/* 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);
+}
+
+/* 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;
+}
+
+/* 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);
+  guint32 want = len;
+  guint32 got = 0;
+  guchar tmpdata[t->r_buf_size];
+  guint32 have = t->r_buf->len;
+
+  // we shouldn't hit this unless the buffer doesn't have enough to read
+  assert (t->r_buf->len < want);
+
+  // first copy what we have in our buffer.
+  if (have > 0)
+  {
+    memcpy (buf, t->r_buf, t->r_buf->len);
+    want -= t->r_buf->len;
+    t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len);
+  }
+
+  // if the buffer is still smaller than what we want to read, then just
+  // read it directly.  otherwise, fill the buffer and then give out
+  // enough to satisfy the read.
+  if (t->r_buf_size < want)
+  {
+    got += THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
+                                                            tmpdata,
+                                                            want,
+                                                            error);
+
+    // copy the data starting from where we left off
+    memcpy (buf + have, tmpdata, got);
+    return got + have; 
+  } else {
+    got += THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
+                                                            tmpdata,
+                                                            t->r_buf_size,
+                                                            error);
+    t->r_buf = g_byte_array_append (t->r_buf, tmpdata, got);
+    
+    // hand over what we have up to what the caller wants
+    guint32 give = want < t->r_buf->len ? want : t->r_buf->len;
+
+
+    memcpy (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_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;
+}
+
+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->len) || (have_bytes == 0))
+  {
+    if (have_bytes > 0)
+    {
+      THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
+                                                        t->w_buf->data,
+                                                        have_bytes,
+                                                        error);
+    }
+    THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
+                                                      buf, len, error);
+    if (t->w_buf->len > 0)
+    {
+      t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len);
+    }
+
+    return TRUE;
+  }
+
+  t->w_buf = g_byte_array_append (t->w_buf, buf, space);
+  THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
+                                                    t->w_buf->data,
+                                                    t->w_buf->len,
+                                                    error);
+
+  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, buf+space, len-space);
+
+  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
+    THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
+                                                      t->w_buf->data,
+                                                      t->w_buf->len,
+                                                      error);
+    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;
+}
+
+
diff --git a/lib/c_glib/src/transport/thrift_buffered_transport.h b/lib/c_glib/src/transport/thrift_buffered_transport.h
new file mode 100644
index 0000000..6b0b17e
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_buffered_transport.h
@@ -0,0 +1,61 @@
+#ifndef _THRIFT_BUFFERED_TRANSPORT_H
+#define _THRIFT_BUFFERED_TRANSPORT_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "transport/thrift_transport.h"
+
+/*! \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))
+
+/*!
+ * 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 _ThriftBufferedTransport ThriftBufferedTransport;
+
+/*!
+ * ThriftBufferedTransport class.
+ */
+struct _ThriftBufferedTransportClass
+{
+  ThriftTransportClass parent;
+};
+typedef struct _ThriftBufferedTransportClass ThriftBufferedTransportClass;
+
+/* used by THRIFT_TYPE_BUFFERED_TRANSPORT */
+GType thrift_buffered_transport_get_type (void);
+
+#endif
diff --git a/lib/c_glib/src/transport/thrift_framed_transport.c b/lib/c_glib/src/transport/thrift_framed_transport.c
new file mode 100644
index 0000000..de9cb00
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_framed_transport.c
@@ -0,0 +1,397 @@
+#include <assert.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "thrift.h"
+#include "transport/thrift_transport.h"
+#include "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
+};
+
+/* forward declarations */
+static void thrift_framed_transport_instance_init (ThriftFramedTransport *self);
+static void thrift_framed_transport_class_init (ThriftFramedTransportClass *cls);
+
+
+gboolean thrift_framed_transport_is_open (ThriftTransport *transport);
+gboolean thrift_framed_transport_open (ThriftTransport *transport,
+                                       GError **error);
+gboolean thrift_framed_transport_close (ThriftTransport *transport,
+                                        GError **error);
+gint32 thrift_framed_transport_read (ThriftTransport *transport, gpointer buf,
+                                     guint32 len, GError **error);
+gboolean thrift_framed_transport_read_end (ThriftTransport *transport,
+                                           GError **error);
+gint32 thrift_framed_transport_read_slow (ThriftTransport *transport,
+                                          gpointer buf, guint32 len,
+                                          GError **error);
+gboolean thrift_framed_transport_read_frame (ThriftTransport *transport,
+                                             GError **error);
+gboolean thrift_framed_transport_write (ThriftTransport *transport,
+                                        const gpointer buf,
+                                        const guint32 len, GError **error);
+gboolean thrift_framed_transport_write_end (ThriftTransport *transport,
+                                            GError **error);
+gint32 thrift_framed_transport_write_slow (ThriftTransport *transport, 
+                                           gpointer buf, guint32 len, 
+                                           GError **error);
+gboolean thrift_framed_transport_flush (ThriftTransport *transport,
+                                        GError **error);
+
+GType
+thrift_framed_transport_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftFramedTransportClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_framed_transport_class_init,
+      NULL, /* class finalize */
+      NULL, /* class data */
+      sizeof (ThriftFramedTransport),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_framed_transport_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_TRANSPORT,
+                                   "ThriftFramedTransport", &info, 0);
+  }
+
+  return type;
+}
+
+/* initializes the instance */
+static void
+thrift_framed_transport_instance_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)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object);
+
+  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)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object);
+
+  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)
+{
+  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);
+
+
+  ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
+
+  gobject_class->finalize = thrift_framed_transport_finalize;
+  ttc->is_open = thrift_framed_transport_is_open;
+  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;
+}
+
+/* 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);
+}
+
+/* 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);
+}
+
+/* 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;
+}
+
+/* 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;
+
+  // we shouldn't hit this unless the buffer doesn't have enough to read
+  assert (t->r_buf->len < want);
+
+  // first copy what we have in our buffer, if there is anything left
+  if (have > 0)
+  {
+    memcpy (buf, t->r_buf, t->r_buf->len);
+    want -= t->r_buf->len;
+    t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len);
+  }
+
+  // read a frame of input and buffer it
+  thrift_framed_transport_read_frame (transport, error);
+
+  // 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 (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);
+}
+
+/* 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);
+  gint32 sz, bytes;
+
+  /* read the size */
+  THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
+                                                   (guint32 *) &sz,
+                                                   sizeof (sz), error);
+  sz = ntohl (sz);
+
+  /* create a buffer to hold the data and read that much data */
+  guchar tmpdata[sz];
+  bytes = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
+                                                           tmpdata,
+                                                           sz - sizeof (sz),
+                                                           error);
+
+  /* add the data to the buffer */
+  g_byte_array_append (t->r_buf, tmpdata, bytes);
+
+  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;
+}
+
+gboolean
+thrift_framed_transport_write_slow (ThriftTransport *transport, gpointer buf,
+                                    guint32 len, GError **error)
+{
+  THRIFT_UNUSED_VAR (error);
+  ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
+
+  // append the data to the buffer and we're done
+  g_byte_array_append (t->w_buf, buf, len);
+
+  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;
+
+  // 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) sz_hbo);
+
+  // copy the size of the frame and then the frame itself
+  guchar tmpdata[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;
+}
+
+
diff --git a/lib/c_glib/src/transport/thrift_framed_transport.h b/lib/c_glib/src/transport/thrift_framed_transport.h
new file mode 100644
index 0000000..d859b97
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_framed_transport.h
@@ -0,0 +1,61 @@
+#ifndef _THRIFT_FRAMED_TRANSPORT_H
+#define _THRIFT_FRAMED_TRANSPORT_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "transport/thrift_transport.h"
+
+/*! \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))
+
+/*!
+ * 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 _ThriftFramedTransport ThriftFramedTransport;
+
+/*!
+ * ThriftFramedTransport class.
+ */
+struct _ThriftFramedTransportClass
+{
+  ThriftTransportClass parent;
+};
+typedef struct _ThriftFramedTransportClass ThriftFramedTransportClass;
+
+/* used by THRIFT_TYPE_FRAMED_TRANSPORT */
+GType thrift_framed_transport_get_type (void);
+
+#endif
diff --git a/lib/c_glib/src/transport/thrift_memory_buffer.c b/lib/c_glib/src/transport/thrift_memory_buffer.c
new file mode 100644
index 0000000..34a4dfa
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_memory_buffer.c
@@ -0,0 +1,260 @@
+#include <assert.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "thrift.h"
+#include "transport/thrift_transport.h"
+#include "transport/thrift_memory_buffer.h"
+
+/* object properties */
+enum _ThriftMemoryBufferProperties
+{
+  PROP_0,
+  PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE,
+};
+
+/* forward declarations */
+static void thrift_memory_buffer_instance_init (ThriftMemoryBuffer *self);
+static void thrift_memory_buffer_class_init (ThriftMemoryBufferClass *cls);
+
+
+gboolean thrift_memory_buffer_is_open (ThriftTransport *transport);
+gboolean thrift_memory_buffer_open (ThriftTransport *transport,
+                                    GError **error);
+gboolean thrift_memory_buffer_close (ThriftTransport *transport,
+                                     GError **error);
+gint32 thrift_memory_buffer_read (ThriftTransport *transport, gpointer buf,
+                                  guint32 len, GError **error);
+gboolean thrift_memory_buffer_read_end (ThriftTransport *transport,
+                                        GError **error);
+gboolean thrift_memory_buffer_write (ThriftTransport *transport,
+                                     const gpointer buf,
+                                     const guint32 len, GError **error);
+gboolean thrift_memory_buffer_write_end (ThriftTransport *transport,
+                                         GError **error);
+gboolean thrift_memory_buffer_flush (ThriftTransport *transport,
+                                     GError **error);
+
+GType
+thrift_memory_buffer_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftMemoryBufferClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_memory_buffer_class_init,
+      NULL, /* class finalize */
+      NULL, /* class data */
+      sizeof (ThriftMemoryBuffer),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_memory_buffer_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_TRANSPORT,
+                                   "ThriftMemoryBuffer", &info, 0);
+  }
+
+  return type;
+}
+
+/* initializes the instance */
+static void
+thrift_memory_buffer_instance_init (ThriftMemoryBuffer *transport)
+{
+  transport->buf = g_byte_array_new ();
+}
+
+/* destructor */
+static void
+thrift_memory_buffer_finalize (GObject *object)
+{
+  ThriftMemoryBuffer *transport = THRIFT_MEMORY_BUFFER (object);
+
+  if (transport->buf != NULL)
+  {
+    g_byte_array_free (transport->buf, TRUE);
+  }
+  transport->buf = NULL;
+}
+
+/* property accessor */
+void
+thrift_memory_buffer_get_property (GObject *object, guint property_id,
+                                   GValue *value, GParamSpec *pspec)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftMemoryBuffer *transport = THRIFT_MEMORY_BUFFER (object);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE:
+      g_value_set_uint (value, transport->buf_size);
+      break;
+  }
+}
+
+/* property mutator */
+void
+thrift_memory_buffer_set_property (GObject *object, guint property_id,
+                                   const GValue *value, GParamSpec *pspec)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftMemoryBuffer *transport = THRIFT_MEMORY_BUFFER (object);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE:
+      transport->buf_size = g_value_get_uint (value);
+      break;
+  }
+}
+
+/* initializes the class */
+static void
+thrift_memory_buffer_class_init (ThriftMemoryBufferClass *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 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_MEMORY_BUFFER_BUFFER_SIZE,
+                                   param_spec);
+
+  ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
+
+  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;
+}
+
+/* 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)
+{
+  THRIFT_UNUSED_VAR (error);
+  ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport);
+  guint32 give = len; 
+
+  /* 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)
+{
+  THRIFT_UNUSED_VAR (error);
+
+  ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport);
+
+  /* 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;
+}
+
+
diff --git a/lib/c_glib/src/transport/thrift_memory_buffer.h b/lib/c_glib/src/transport/thrift_memory_buffer.h
new file mode 100644
index 0000000..7529d1f
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_memory_buffer.h
@@ -0,0 +1,55 @@
+#ifndef _THRIFT_MEMORY_BUFFER_H
+#define _THRIFT_MEMORY_BUFFER_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "transport/thrift_transport.h"
+
+/*! \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))
+
+/*!
+ * ThriftMemoryBuffer instance.
+ */
+struct _ThriftMemoryBuffer
+{
+  ThriftTransport parent;
+
+  /* private */
+  GByteArray *buf;
+  guint32 buf_size;
+};
+typedef struct _ThriftMemoryBuffer ThriftMemoryBuffer;
+
+/*!
+ * ThriftMemoryBuffer class.
+ */
+struct _ThriftMemoryBufferClass
+{
+  ThriftTransportClass parent;
+};
+typedef struct _ThriftMemoryBufferClass ThriftMemoryBufferClass;
+
+/* used by THRIFT_TYPE_MEMORY_BUFFER */
+GType thrift_memory_buffer_get_type (void);
+
+#endif
diff --git a/lib/c_glib/src/transport/thrift_server_socket.c b/lib/c_glib/src/transport/thrift_server_socket.c
new file mode 100644
index 0000000..fe11648
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_server_socket.c
@@ -0,0 +1,272 @@
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "thrift.h"
+#include "transport/thrift_socket.h"
+#include "transport/thrift_transport.h"
+#include "transport/thrift_server_transport.h"
+#include "transport/thrift_server_socket.h"
+
+/* object properties */
+enum _ThriftServerSocketProperties
+{
+  PROP_0,
+  PROP_THRIFT_SERVER_SOCKET_PORT,
+  PROP_THRIFT_SERVER_SOCKET_BACKLOG
+};
+
+/* define the GError domain string */
+#define THRIFT_SERVER_SOCKET_ERROR_DOMAIN "thrift-server-socket-error-quark"
+
+/* for errors coming from socket() and connect() */
+extern int errno;
+
+/* forward declarations */
+static void thrift_server_socket_instance_init (ThriftServerSocket *self);
+static void thrift_server_socket_class_init (ThriftServerSocketClass *cls);
+
+gboolean thrift_server_socket_listen (ThriftServerTransport *transport,
+                                      GError **error);
+ThriftTransport *thrift_server_socket_accept (ThriftServerTransport *transport,
+                                              GError **error);
+gboolean thrift_server_socket_close (ThriftServerTransport *transport,
+                                     GError **error);
+
+GType
+thrift_server_socket_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftServerSocketClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_server_socket_class_init,
+      NULL, /* class finalize */
+      NULL, /* class data */
+      sizeof (ThriftServerSocket),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_server_socket_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_SERVER_TRANSPORT,
+                                   "ThriftServerSocket", &info, 0);
+  }
+
+  return type;
+}
+
+/* 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_instance_init (ThriftServerSocket *socket)
+{
+  socket->sd = 0;
+}
+
+/* destructor */
+static void
+thrift_server_socket_finalize (GObject *object)
+{
+  ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
+
+  if (socket->sd != 0)
+  {
+    close (socket->sd);
+  }
+  socket->sd = 0;
+}
+
+/* property accessor */
+void
+thrift_server_socket_get_property (GObject *object, guint property_id,
+                                   GValue *value, GParamSpec *pspec)
+{
+  ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_SERVER_SOCKET_PORT:
+      g_value_set_uint (value, socket->port);
+      break;
+    case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
+      g_value_set_uint (value, socket->backlog);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+/* property mutator */
+void
+thrift_server_socket_set_property (GObject *object, guint property_id,
+                                   const GValue *value, GParamSpec *pspec)
+{
+  ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_SERVER_SOCKET_PORT:
+      socket->port = g_value_get_uint (value);
+      break;
+    case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
+      socket->backlog = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+/* initializes the class */
+static void
+thrift_server_socket_class_init (ThriftServerSocketClass *cls)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+  GParamSpec *param_spec = NULL;
+
+  /* setup accessors and mutators */
+  gobject_class->get_property = thrift_server_socket_get_property;
+  gobject_class->set_property = thrift_server_socket_set_property;
+
+  param_spec = g_param_spec_uint ("port",
+                                  "port (construct)",
+                                  "Set the port to listen to",
+                                  0, /* min */
+                                  65534, /* max */
+                                  9090, /* default by convention */
+                                  G_PARAM_CONSTRUCT_ONLY |
+                                  G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_SERVER_SOCKET_PORT, 
+                                   param_spec);
+
+  param_spec = g_param_spec_uint ("backlog",
+                                  "backlog (construct)",
+                                  "Set the accept backlog",
+                                  0, /* max */
+                                  65534, /* max */
+                                  1024, /* default */
+                                  G_PARAM_CONSTRUCT_ONLY |
+                                  G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_SERVER_SOCKET_BACKLOG,
+                                   param_spec);
+
+  gobject_class->finalize = thrift_server_socket_finalize;
+
+  ThriftServerTransportClass *tstc = THRIFT_SERVER_TRANSPORT_CLASS (cls);
+  tstc->listen = thrift_server_socket_listen;
+  tstc->accept = thrift_server_socket_accept;
+  tstc->close = thrift_server_socket_close;
+}
+
+gboolean
+thrift_server_socket_listen (ThriftServerTransport *transport, GError **error)
+{
+  int enabled = 1; /* for setsockopt() */
+  struct sockaddr_in pin;
+  ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
+
+  /* create a address structure */
+  memset (&pin, 0, sizeof(pin));
+  pin.sin_family = AF_INET;
+  pin.sin_addr.s_addr = INADDR_ANY;
+  pin.sin_port = htons(tsocket->port);
+
+  /* create a socket */
+  if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
+  {
+    g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, 
+                 THRIFT_SERVER_SOCKET_ERROR_SOCKET,
+                 "failed to create socket - %s", strerror (errno));
+    return FALSE;
+  }
+
+  if (setsockopt(tsocket->sd, SOL_SOCKET, SO_REUSEADDR, &enabled,
+                 sizeof(enabled)) == -1)
+  {
+    g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+                 THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT,
+                 "unable to set SO_REUSEADDR - %s", strerror(errno));
+    return FALSE;
+  }
+
+  /* bind to the socket */
+  if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+  {
+    g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, 
+                 THRIFT_SERVER_SOCKET_ERROR_BIND,
+                 "failed to bind to port %d - %s", 
+                 tsocket->port, strerror(errno));
+    return FALSE;
+  } 
+
+  if (listen(tsocket->sd, tsocket->backlog) == -1)
+  {
+    g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+                 THRIFT_SERVER_SOCKET_ERROR_LISTEN,
+                 "failed to listen to port %d - %s",
+                 tsocket->port, strerror(errno));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+ThriftTransport *
+thrift_server_socket_accept (ThriftServerTransport *transport, GError **error)
+{
+  int sd = 0;
+  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 = 0;
+
+  return TRUE;
+}
+
diff --git a/lib/c_glib/src/transport/thrift_server_socket.h b/lib/c_glib/src/transport/thrift_server_socket.h
new file mode 100644
index 0000000..c56bd84
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_server_socket.h
@@ -0,0 +1,73 @@
+#ifndef _THRIFT_SERVER_SOCKET_H
+#define _THRIFT_SERVER_SOCKET_H
+
+#include <glib-object.h>
+
+#include "thrift_server_transport.h"
+
+/*! \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))
+
+/*!
+ * Thrift ServerSocket instance.
+ */
+struct _ThriftServerSocket
+{
+  ThriftServerTransport parent;
+
+  /* private */
+  gshort port;
+  gshort backlog;
+  int sd;
+  guint8 *buf;
+  guint32 buf_size;
+  guint32 buf_len;
+};
+typedef struct _ThriftServerSocket ThriftServerSocket;
+
+/*!
+ * Thrift ServerSocket class.
+ */
+struct _ThriftServerSocketClass
+{
+  ThriftServerTransportClass parent;
+};
+typedef struct _ThriftServerSocketClass ThriftServerSocketClass;
+
+/* 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 ())
+
+#endif
diff --git a/lib/c_glib/src/transport/thrift_server_transport.c b/lib/c_glib/src/transport/thrift_server_transport.c
new file mode 100644
index 0000000..89cbaf3
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_server_transport.c
@@ -0,0 +1,70 @@
+#include "thrift.h"
+#include "transport/thrift_transport.h"
+#include "transport/thrift_server_transport.h"
+
+/* forward declarations */
+static void thrift_server_transport_class_init (ThriftServerTransportClass *c);
+
+/* define ThriftTransportClass type */
+GType
+thrift_server_transport_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftServerTransportClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_server_transport_class_init, 
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftServerTransport),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT,
+                                   "ThriftServerTransport",
+                                   &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+/* 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;
+}
+
+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/lib/c_glib/src/transport/thrift_server_transport.h b/lib/c_glib/src/transport/thrift_server_transport.h
new file mode 100644
index 0000000..a74fca0
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_server_transport.h
@@ -0,0 +1,72 @@
+#ifndef _THRIFT_SERVER_TRANSPORT_H
+#define _THRIFT_SERVER_TRANSPORT_H
+
+#include <glib-object.h>
+
+#include "thrift_transport.h"
+
+/*! \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))
+
+struct _ThriftServerTransport
+{
+  GObject parent;
+};
+typedef struct _ThriftServerTransport ThriftServerTransport;
+
+/*!
+ * 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);
+};
+typedef struct _ThriftServerTransportClass ThriftServerTransportClass;
+
+/* 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);
+
+#endif /* _THRIFT_SERVER_TRANSPORT_H */
diff --git a/lib/c_glib/src/transport/thrift_socket.c b/lib/c_glib/src/transport/thrift_socket.c
new file mode 100644
index 0000000..951ae90
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_socket.c
@@ -0,0 +1,334 @@
+#include <errno.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "thrift.h"
+#include "transport/thrift_transport.h"
+#include "transport/thrift_socket.h"
+
+/* object properties */
+enum _ThriftSocketProperties
+{
+  PROP_0,
+  PROP_THRIFT_SOCKET_HOSTNAME,
+  PROP_THRIFT_SOCKET_PORT
+};
+
+/* for errors coming from socket() and connect() */
+extern int errno;
+
+/* forward declarations */
+static void thrift_socket_instance_init (ThriftSocket *self);
+static void thrift_socket_class_init (ThriftSocketClass *cls);
+
+gboolean thrift_socket_is_open (ThriftTransport *transport);
+gboolean thrift_socket_open (ThriftTransport *transport, GError **error);
+gboolean thrift_socket_close (ThriftTransport *transport, GError **error);
+gint32 thrift_socket_read (ThriftTransport *transport, gpointer buf,
+                           guint32 len, GError **error);
+gboolean thrift_socket_read_end (ThriftTransport *transport, GError **error);
+gboolean thrift_socket_write (ThriftTransport *transport, const gpointer buf,
+                              const guint32 len, GError **error);
+gboolean thrift_socket_write_end (ThriftTransport *transport, GError **error);
+gboolean thrift_socket_flush (ThriftTransport *transport, GError **error);
+
+GType
+thrift_socket_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftSocketClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_socket_class_init,
+      NULL, /* class finalize */
+      NULL, /* class data */
+      sizeof (ThriftSocket),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) thrift_socket_instance_init,
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (THRIFT_TYPE_TRANSPORT,
+                                   "ThriftSocket", &info, 0);
+  }
+
+  return type;
+}
+
+/* initializes the instance */
+static void
+thrift_socket_instance_init (ThriftSocket *socket)
+{
+  socket->sd = 0;
+}
+
+/* destructor */
+static void
+thrift_socket_finalize (GObject *object)
+{
+  ThriftSocket *socket = THRIFT_SOCKET (object);
+
+  if (socket->hostname != NULL)
+  {
+    g_free (socket->hostname);
+  }
+  socket->hostname = NULL;
+
+  if (socket->sd != 0)
+  {
+    close (socket->sd);
+  }
+  socket->sd = 0;
+}
+
+/* property accessor */
+void
+thrift_socket_get_property (GObject *object, guint property_id,
+                            GValue *value, GParamSpec *pspec)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftSocket *socket = THRIFT_SOCKET (object);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_SOCKET_HOSTNAME:
+      g_value_set_string (value, socket->hostname);
+      break;
+    case PROP_THRIFT_SOCKET_PORT:
+      g_value_set_uint (value, socket->port);
+      break;
+  }
+}
+
+/* property mutator */
+void
+thrift_socket_set_property (GObject *object, guint property_id,
+                            const GValue *value, GParamSpec *pspec)
+{
+  THRIFT_UNUSED_VAR (pspec);
+  ThriftSocket *socket = THRIFT_SOCKET (object);
+
+  switch (property_id)
+  {
+    case PROP_THRIFT_SOCKET_HOSTNAME:
+      socket->hostname = g_strdup (g_value_get_string (value));
+      break;
+    case PROP_THRIFT_SOCKET_PORT:
+      socket->port = g_value_get_uint (value);
+      break;
+  }
+}
+
+/* initializes the class */
+static void
+thrift_socket_class_init (ThriftSocketClass *cls)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+  GParamSpec *param_spec = NULL;
+
+  /* setup accessors and mutators */
+  gobject_class->get_property = thrift_socket_get_property;
+  gobject_class->set_property = thrift_socket_set_property;
+
+  param_spec = g_param_spec_string ("hostname",
+                                    "hostname (construct)",
+                                    "Set the hostname of the remote host",
+                                    "localhost", /* default value */
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_HOSTNAME, 
+                                   param_spec);
+
+  param_spec = g_param_spec_uint ("port",
+                                  "port (construct)",
+                                  "Set the port of the remote host",
+                                  0, /* min */
+                                  65534, /* max */
+                                  9090, /* default by convention */
+                                  G_PARAM_CONSTRUCT_ONLY |
+                                  G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PORT, 
+                                   param_spec);
+
+  ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
+
+  gobject_class->finalize = thrift_socket_finalize;
+  ttc->is_open = thrift_socket_is_open;
+  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;
+}
+
+/* implements thrift_transport_is_open */
+gboolean
+thrift_socket_is_open (ThriftTransport *transport)
+{
+  ThriftSocket *socket = THRIFT_SOCKET (transport);
+  return socket->sd != 0;
+}
+
+/* implements thrift_transport_open */
+gboolean
+thrift_socket_open (ThriftTransport *transport, GError **error)
+{
+  struct hostent *hp = NULL;
+  struct sockaddr_in pin;
+
+  ThriftSocket *tsocket = THRIFT_SOCKET (transport);
+  g_return_val_if_fail (tsocket->sd == 0, FALSE);
+
+  /* lookup the destination host */
+  if ((hp = gethostbyname (tsocket->hostname)) == NULL)
+  {
+    /* 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 (h_errno));
+    return FALSE;
+  }
+
+  /* create a socket structure */
+  memset (&pin, 0, sizeof(pin));
+  pin.sin_family = AF_INET;
+  pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
+  pin.sin_port = htons (tsocket->port); 
+
+  /* create the socket */
+  if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
+  {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET,
+                 "failed to create socket for host %s:%d - %s",
+                 tsocket->hostname, tsocket->port,
+                 strerror(errno));
+    return FALSE;
+  }
+
+  /* open a connection */
+  if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+  {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
+                 "failed to connect to host %s:%d - %s",
+                 tsocket->hostname, tsocket->port, strerror(errno));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/* implements thrift_transport_close */
+gboolean
+thrift_socket_close (ThriftTransport *transport, GError **error)
+{
+  ThriftSocket *socket = THRIFT_SOCKET (transport);
+
+  if (close (socket->sd) == -1)
+  {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE,
+                 "unable to close socket - %s",
+                 strerror(errno));
+    return FALSE;
+  }
+
+  socket->sd = 0;
+  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, buf, len, 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 != 0, FALSE);
+
+  while (sent < len)
+  {
+    ret = send (socket->sd, 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;
+}
+
+
diff --git a/lib/c_glib/src/transport/thrift_socket.h b/lib/c_glib/src/transport/thrift_socket.h
new file mode 100644
index 0000000..5fc2402
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_socket.h
@@ -0,0 +1,56 @@
+#ifndef _THRIFT_SOCKET_H
+#define _THRIFT_SOCKET_H
+
+#include <glib-object.h>
+
+#include "transport/thrift_transport.h"
+
+/*! \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))
+
+/*!
+ * Thrift Socket instance.
+ */
+struct _ThriftSocket
+{
+  ThriftTransport parent;
+
+  /* private */
+  gchar *hostname;
+  gshort port;
+  int sd;
+  guint8 *buf;
+  guint32 buf_size;
+  guint32 buf_len;
+};
+typedef struct _ThriftSocket ThriftSocket;
+
+/*!
+ * Thrift Socket class.
+ */
+struct _ThriftSocketClass
+{
+  ThriftTransportClass parent;
+};
+typedef struct _ThriftSocketClass ThriftSocketClass;
+
+/* used by THRIFT_TYPE_SOCKET */
+GType thrift_socket_get_type (void);
+
+#endif
diff --git a/lib/c_glib/src/transport/thrift_transport.c b/lib/c_glib/src/transport/thrift_transport.c
new file mode 100644
index 0000000..9c57a75
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_transport.c
@@ -0,0 +1,114 @@
+#include "thrift.h"
+#include "transport/thrift_transport.h"
+
+/* define the GError domain string */
+#define THRIFT_TRANSPORT_ERROR_DOMAIN "thrift-transport-error-quark"
+
+/* forward declarations */
+static void thrift_transport_class_init (ThriftTransportClass *cls);
+
+/* define ThriftTransportInterface's type */
+GType
+thrift_transport_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info =
+    {
+      sizeof (ThriftTransportClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_transport_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftTransport),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "ThriftTransport",
+                                   &info, G_TYPE_FLAG_ABSTRACT);
+  }
+
+  return type;
+}
+
+/* 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;
+}
+
+gboolean 
+thrift_transport_is_open (ThriftTransport *transport)
+{
+  return THRIFT_TRANSPORT_GET_CLASS (transport)->is_open (transport);
+}
+
+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);
+}
+
+/* define the GError domain for Thrift transports */
+GQuark
+thrift_transport_error_quark (void)
+{
+  return g_quark_from_static_string (THRIFT_TRANSPORT_ERROR_DOMAIN);
+}
+
diff --git a/lib/c_glib/src/transport/thrift_transport.h b/lib/c_glib/src/transport/thrift_transport.h
new file mode 100644
index 0000000..18edc4d
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_transport.h
@@ -0,0 +1,135 @@
+#ifndef _THRIFT_TRANSPORT_H
+#define _THRIFT_TRANSPORT_H
+
+#include <glib-object.h>
+
+/*! \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))
+
+/*!
+ * Thrift Protocol object
+ */
+struct _ThriftTransport
+{
+  GObject parent;
+};
+typedef struct _ThriftTransport ThriftTransport;
+
+/*!
+ * Thrift Transport class
+ */
+struct _ThriftTransportClass
+{
+  GObjectClass parent;
+
+  /* vtable */
+  gboolean (*is_open) (ThriftTransport *transport); 
+  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);
+};
+typedef struct _ThriftTransportClass ThriftTransportClass;
+
+/* 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);
+
+/*!
+ * 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);
+
+/* 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 ())
+
+
+#endif /* _THRIFT_TRANSPORT_H */
diff --git a/lib/c_glib/src/transport/thrift_transport_factory.c b/lib/c_glib/src/transport/thrift_transport_factory.c
new file mode 100644
index 0000000..6f0199f
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_transport_factory.c
@@ -0,0 +1,51 @@
+#include "thrift.h"
+#include "transport/thrift_transport_factory.h"
+
+/* forward declaration s*/
+static void thrift_transport_factory_class_init (ThriftTransportFactoryClass *cls);
+ThriftTransport *thrift_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport);
+
+GType
+thrift_transport_factory_get_type (void)
+{
+  static GType type = 0;
+
+  if (type == 0)
+  {
+    static const GTypeInfo info = {
+      sizeof (ThriftTransportFactoryClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) thrift_transport_factory_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (ThriftTransportFactory),
+      0, /* n_preallocs */
+      NULL, /* instance_init */
+      NULL, /* value_table */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "ThriftTransportFactory",
+                                   &info, 0);
+  }
+
+  return type;
+}
+
+static void
+thrift_transport_factory_class_init (ThriftTransportFactoryClass *cls)
+{
+  cls->get_transport = thrift_transport_factory_get_transport;
+}
+
+/* builds a transport from the base transport. */
+ThriftTransport *
+thrift_transport_factory_get_transport (ThriftTransportFactory *factory,
+                                        ThriftTransport *transport)
+{
+  THRIFT_UNUSED_VAR (factory);
+  return transport;
+}
+
+
+
diff --git a/lib/c_glib/src/transport/thrift_transport_factory.h b/lib/c_glib/src/transport/thrift_transport_factory.h
new file mode 100644
index 0000000..d987a80
--- /dev/null
+++ b/lib/c_glib/src/transport/thrift_transport_factory.h
@@ -0,0 +1,55 @@
+#ifndef _THRIFT_TRANSPORT_FACTORY_H
+#define _THRIFT_TRANSPORT_FACTORY_H
+
+#include <glib-object.h>
+
+#include "thrift_transport.h"
+
+/*! \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))
+
+/* Thrift Transport Factory instance */
+struct _ThriftTransportFactory
+{
+  GObject parent;
+};
+typedef struct _ThriftTransportFactory ThriftTransportFactory;
+
+/* Thrift Transport Factory class */
+struct _ThriftTransportFactoryClass
+{
+  GObjectClass parent;
+
+  /* vtable */
+  ThriftTransport *(*get_transport) (ThriftTransportFactory *factory,
+                                     ThriftTransport *transport);
+};
+typedef struct _ThriftTransportFactoryClass ThriftTransportFactoryClass;
+
+/* 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);
+
+
+#endif /* _THRIFT_TRANSPORT_FACTORY_H */