// Half of this file comes from contributions from Nitay Joffe (nitay@powerset.com)
// Much of the rest (almost) directly ported (or pulled) from thrift-py's fastbinary.c
// Everything else via Kevin Clark (kevin@powerset.com)
#include <stdint.h>
#include <stdbool.h>

#include <ruby.h>
#include <st.h>
#include <netinet/in.h>

// #define __DEBUG__

#ifndef HAVE_STRLCPY

static
size_t
strlcpy (char *dst, const char *src, size_t dst_sz)
{
    size_t n;

    for (n = 0; n < dst_sz; n++) {
      if ((*dst++ = *src++) == '\0')
        break;
    }

    if (n < dst_sz)
      return n;
    if (n > 0)
      *(dst - 1) = '\0';
    return n + strlen (src);
}

#endif

#define dbg() fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__)


// TODO (kevinclark): This was here from the patch/python. Not sure
// If it's actually that big a pain. Need to look into pulling
// From the right place

// Stolen out of TProtocol.h.
// It would be a huge pain to have both get this from one place.

enum TType {
  T_STOP       = 0,
  T_BOOL       = 2,
  T_BYTE       = 3,
  T_I16        = 6,
  T_I32        = 8,
  T_I64        = 10,
  T_DBL        = 4,
  T_STR        = 11,
  T_STRCT      = 12,
  T_MAP        = 13,
  T_SET        = 14,
  T_LIST       = 15
  // T_VOID       = 1,
  // T_I08        = 3,
  // T_U64        = 9,
  // T_UTF7       = 11,
  // T_UTF8       = 16,
  // T_UTF16      = 17
};

#define IS_CONTAINER(x) (x == T_MAP || x == T_SET || x == T_LIST)

// Same comment as the enum.  Sorry.
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#endif

#ifndef __BYTE_ORDER
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
#  define __BYTE_ORDER BYTE_ORDER
#  define __LITTLE_ENDIAN LITTLE_ENDIAN
#  define __BIG_ENDIAN BIG_ENDIAN
# else
#  error "Cannot determine endianness"
# endif
#endif

#if __BYTE_ORDER == __BIG_ENDIAN
# define ntohll(n) (n)
# define htonll(n) (n)
#elif __BYTE_ORDER == __LITTLE_ENDIAN
# if defined(__GNUC__) && defined(__GLIBC__)
#  include <byteswap.h>
#  define ntohll(n) bswap_64(n)
#  define htonll(n) bswap_64(n)
# else /* GNUC & GLIBC */
#  define ntohll(n) ( (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32) )
#  define htonll(n) ( (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32) )
# endif /* GNUC & GLIBC */
#else /* __BYTE_ORDER */
# error "Can't define htonll or ntohll!"
#endif


// -----------------------------------------------------------------------------
// Cached interned strings and such
// -----------------------------------------------------------------------------

static VALUE class_tbpa;
static VALUE m_thrift;
static VALUE rb_cSet;
static ID type_sym;
static ID class_sym;
static ID key_sym;
static ID value_sym;
static ID element_sym;
static ID name_sym;
static ID fields_id;
static ID consume_bang_id;
static ID string_buffer_id;
static ID borrow_id;
static ID keys_id;
static ID entries_id;

static const uint32_t VERSION_MASK = 0xffff0000;
static const uint32_t VERSION_1 = 0x80010000;

// -----------------------------------------------------------------------------
// Structs so I don't have to keep calling rb_hash_aref
// -----------------------------------------------------------------------------

// { :type => field[:type],
//   :class => field[:class],
//   :key => field[:key],
//   :value => field[:value],
//   :element => field[:element] }

struct _thrift_map;
struct _field_spec;

typedef union {
  VALUE class;
  struct _thrift_map* map;
  struct _field_spec* element;
} container_data;

typedef struct _field_spec {
  int type;
  char* name;
  container_data data;
} field_spec;

typedef struct _thrift_map {
  field_spec* key;
  field_spec* value; 
} thrift_map;


static void free_field_spec(field_spec* spec) {
  switch(spec->type) {
    case T_LIST:
    case T_SET:
      free_field_spec(spec->data.element);
      break;
    
    case T_MAP:
      free_field_spec(spec->data.map->key);
      free_field_spec(spec->data.map->value);
      free(spec->data.map);
      break;
  }
  
  free(spec);
}

// Parses a ruby field spec into a C struct
//
// Simple fields look like:
// { :name => .., :type => .. }
// Structs add the :class attribute
// Maps adds :key and :value attributes, field specs
// Lists and Sets add an :element, a field spec
static field_spec* parse_field_spec(VALUE field_data) {
  int type = NUM2INT(rb_hash_aref(field_data, type_sym));
  VALUE name = rb_hash_aref(field_data, name_sym);
  field_spec* spec = (field_spec *) malloc(sizeof(field_spec));

#ifdef __DEBUG__ // No need for this in prod since I set all the fields
  bzero(spec, sizeof(field_spec));
#endif

  spec->type = type;
  
  if (Qnil != name) {
    spec->name = StringValuePtr(name);
  } else {
    spec->name = NULL;
  }
  
  switch(type) {
    case T_STRCT: {
      spec->data.class = rb_hash_aref(field_data, class_sym);
      break;
    }
    
    case T_MAP: {
      VALUE key_fields = rb_hash_aref(field_data, key_sym);
      VALUE value_fields = rb_hash_aref(field_data, value_sym);
      thrift_map* map = (thrift_map *) malloc(sizeof(thrift_map));
      
      map->key = parse_field_spec(key_fields);
      map->value = parse_field_spec(value_fields);
      spec->data.map = map;
      
      break;
    }
    
    case T_LIST: 
    case T_SET:
    {
      VALUE list_fields = rb_hash_aref(field_data, element_sym);
      spec->data.element = parse_field_spec(list_fields);
      break;
    }
  }
  
  return spec;
}


// -----------------------------------------------------------------------------
// Serialization routines
// -----------------------------------------------------------------------------


// write_*(VALUE buf, ...) takes a value and adds it to a Ruby string buffer,
// in network order
static void write_byte(VALUE buf, int8_t val) {
  rb_str_buf_cat(buf, (char*)&val, sizeof(int8_t));
}

static void write_i16(VALUE buf, int16_t val) {
  int16_t net = (int16_t)htons(val);
  rb_str_buf_cat(buf, (char*)&net, sizeof(int16_t));
}

static void write_i32(VALUE buf, int32_t val) {
  int32_t net = (int32_t)htonl(val);
  rb_str_buf_cat(buf, (char*)&net, sizeof(int32_t));
}

static void write_i64(VALUE buf, int64_t val) {
  int64_t net = (int64_t)htonll(val);
  rb_str_buf_cat(buf, (char*)&net, sizeof(int64_t));
}

static void write_double(VALUE buf, double dub) {
  // Unfortunately, bitwise_cast doesn't work in C.  Bad C!
  union {
    double f;
    int64_t t;
  } transfer;
  transfer.f = dub;
  write_i64(buf, transfer.t);
}

static void write_string(VALUE buf, char* str) {
  int32_t len = strlen(str);
  write_i32(buf, len);
  rb_str_buf_cat2(buf, str);
}

// Some functions macro'd out because they're nops for the binary protocol
// but placeholders were desired in case things change
#define write_struct_begin(buf)
#define write_struct_end(buf)

static void write_field_begin(VALUE buf, char* name, int type, int fid) {
#ifdef __DEBUG__
  fprintf(stderr, "Writing field beginning: %s %d %d\n", name, type, fid);
#endif

  write_byte(buf, (int8_t)type);
  write_i16(buf, (int16_t)fid);
}

#define write_field_end(buf)

static void write_field_stop(VALUE buf) {
  write_byte(buf, T_STOP);
}

static void write_map_begin(VALUE buf, int8_t ktype, int8_t vtype, int32_t sz) {
  write_byte(buf, ktype);
  write_byte(buf, vtype);
  write_i32(buf, sz);
}

#define write_map_end(buf);

static void write_list_begin(VALUE buf, int type, int sz) {
  write_byte(buf, type);
  write_i32(buf, sz);
}

#define write_list_end(buf)

static void write_set_begin(VALUE buf, int type, int sz) {
  write_byte(buf, type);
  write_i32(buf, sz);
}

#define write_set_end(buf)

static void binary_encoding(VALUE buf, VALUE obj, int type);

// Handles container types: Map, Set, List
static void write_container(VALUE buf, VALUE value, field_spec* spec) {
  int sz, i;
  
  switch(spec->type) {
    case T_MAP: {
      VALUE keys;
      VALUE key;
      VALUE val;
      
      keys = rb_funcall(value, keys_id, 0);
      
      sz = RARRAY(keys)->len;
      
      write_map_begin(buf, spec->data.map->key->type, spec->data.map->value->type, sz);
      
      for (i = 0; i < sz; i++) {
        key = rb_ary_entry(keys, i);
        val = rb_hash_aref(value, key);
        
        if (IS_CONTAINER(spec->data.map->key->type)) {
          write_container(buf, key, spec->data.map->key);
        } else {
          binary_encoding(buf, key, spec->data.map->key->type);
        }
        
        if (IS_CONTAINER(spec->data.map->value->type)) {
          write_container(buf, val, spec->data.map->value);
        } else {
          binary_encoding(buf, val, spec->data.map->value->type);
        }
      }
      
      write_map_end(buf);

      break;
    }
    
    case T_LIST: {
      sz = RARRAY(value)->len;
      
      write_list_begin(buf, spec->data.element->type, sz);
      for (i = 0; i < sz; ++i) {
        if (IS_CONTAINER(spec->data.element->type)) {
          write_container(buf, rb_ary_entry(value, i), spec->data.element);
        } else {
          binary_encoding(buf, rb_ary_entry(value, i), spec->data.element->type);
        }
      }
      write_list_end(buf);
      break;
    }

    case T_SET: {
      VALUE items;

      if (TYPE(value) == T_ARRAY) {
        items = value;
      } else {        
        if (rb_cSet == CLASS_OF(value)) {
          items = rb_funcall(value, entries_id, 0);
        } else {
          Check_Type(value, T_HASH);
          items = rb_funcall(value, keys_id, 0);
        }
      }

      sz = RARRAY(items)->len;
      
      write_set_begin(buf, spec->data.element->type, sz);
      
      for (i = 0; i < sz; i++) {
        if (IS_CONTAINER(spec->data.element->type)) {
          write_container(buf, rb_ary_entry(items, i), spec->data.element);
        } else {
          binary_encoding(buf, rb_ary_entry(items, i), spec->data.element->type);
        }
      }
      
      write_set_end(buf);
      break;
    }
  }
}

// Takes the field id, data to be encoded, buffer and enclosing object
// to be encoded. buf and obj passed as a ruby array for rb_hash_foreach.
// TODO(kevinclark): See if they can be passed individually to avoid object
// creation
static int encode_field(VALUE fid, VALUE data, VALUE ary) {
  field_spec *spec = parse_field_spec(data);
  
  VALUE buf = rb_ary_entry(ary, 0);
  VALUE obj = rb_ary_entry(ary, 1);
  char name_buf[128];
  
  name_buf[0] = '@';
  strlcpy(&name_buf[1], spec->name, sizeof(name_buf) - 1);
  
  VALUE value = rb_ivar_get(obj, rb_intern(name_buf));
  
  if (Qnil == value) {
    free_field_spec(spec);
    return 0;
  }
     
  write_field_begin(buf, spec->name, spec->type, NUM2INT(fid));
  
  if (IS_CONTAINER(spec->type)) {
    write_container(buf, value, spec);
  } else {
    binary_encoding(buf, value, spec->type);
  }
  write_field_end(buf);
  
  free_field_spec(spec);
  
  return 0;
}

// -----------------------------------------------------------------------------
// TFastBinaryProtocol's main encoding loop
// -----------------------------------------------------------------------------

static void binary_encoding(VALUE buf, VALUE obj, int type) {
#ifdef __DEBUG__
  rb_p(rb_str_new2("Encoding binary (buf, obj, type)"));
  rb_p(rb_inspect(buf));
  rb_p(rb_inspect(obj));
  rb_p(rb_inspect(INT2FIX(type)));
#endif

  switch(type) {
    case T_BOOL:
      if RTEST(obj) {
        write_byte(buf, 1);
      }
      else {
        write_byte(buf, 0);
      }
      
      break;
    
    case T_BYTE:
      write_byte(buf, NUM2INT(obj));
      break;
    
    case T_I16:
      write_i16(buf, NUM2INT(obj));
      break;
    
    case T_I32:
      write_i32(buf, NUM2INT(obj));
      break;
    
    case T_I64:
      write_i64(buf, rb_num2ll(obj));
      break;
    
    case T_DBL:
      write_double(buf, NUM2DBL(obj));
      break;

    case T_STR:
      write_string(buf, StringValuePtr(obj));
      break;
          
    case T_STRCT: {
      // rb_hash_foreach has to take args as a ruby array
      VALUE args = rb_ary_new3(2, buf, obj);
      VALUE fields = rb_const_get(CLASS_OF(obj), fields_id);
      
      write_struct_begin(buf);
      
      rb_hash_foreach(fields, encode_field, args);
      
      write_field_stop(buf);
      write_struct_end(buf);
      break;
    }
    
    default: {
      rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", type);
    }
  }
}

// obj is always going to be a TSTRCT
static VALUE tbpa_encode_binary(VALUE self, VALUE obj) {
  VALUE buf = rb_str_buf_new(1024);
  binary_encoding(buf, obj, T_STRCT);
  return buf;
}


// -----------------------------------------------------------------------------
// Read stuff
// -----------------------------------------------------------------------------

typedef struct {
  char* name;
  int8_t type;
  int16_t id;
} field_header;

typedef struct {
  int8_t key_type;
  int8_t val_type;
  int num_entries;
} map_header;

typedef struct {
  int8_t type;
  int num_elements;
} list_header;

typedef list_header set_header;

typedef struct {
  char* data;
  int pos;
  int len;
  VALUE trans;
} decode_buffer;

typedef struct {
  char* ptr;
  int len;
} thrift_string;

#define read_struct_begin(buf)
#define read_struct_end(buf)

// This prototype is required to be able to run a call through rb_protect
// which rescues from ruby exceptions
static VALUE protectable_consume(VALUE args) {
  VALUE trans = rb_ary_entry(args, 0);
  VALUE size = rb_ary_entry(args, 1);
  
  return rb_funcall(trans, consume_bang_id, 1, size);
}

// Clears size bytes from the transport's string buffer
static bool consume(decode_buffer* buf, int32_t size) {
  if (size != 0) {
    VALUE ret;
    VALUE args = rb_ary_new3(2, buf->trans, INT2FIX(size));
    int status = 0;
    
    ret = rb_protect(protectable_consume, args, &status);
    
    if (status) {
      return false;
    } else {
      return true;
    }
  }
  
  // Nothing to consume, we're all good
  return true;
}

// This prototype is required to be able to run a call through rb_protect
// which rescues from ruby exceptions
static VALUE protectable_borrow(VALUE args) {
  VALUE trans = rb_ary_entry(args, 0);
  
  switch(RARRAY(args)->len) {
    case 1:
      return rb_funcall(trans, borrow_id, 0);
    
    case 2: {
      VALUE size = rb_ary_entry(args, 1);
      return rb_funcall(trans, borrow_id, 1, size);
    }
  }
  
  return Qnil;
}

// Calls into the transport to get the available string buffer
static bool borrow(decode_buffer* buf, int32_t size, VALUE* dst) {
  int status = 0;
  VALUE args;
  
  if (size == 0) {
    args = rb_ary_new3(1, buf->trans);
  } else {
    args = rb_ary_new3(2, buf->trans, INT2FIX(size));
  }

  *dst = rb_protect(protectable_borrow, args, &status);
  
  return (status == 0);
}

// Refills the buffer by calling borrow. If buf->pos is nonzero that number of bytes
// is cleared through consume.
//
// returns: 0 on success, non-zero on failure. On error buf is unchanged.
static int fill_buffer(decode_buffer* buf, int32_t req_len) {
  VALUE refill;
  
  if (!consume(buf, buf->pos)) {
    return -1;
  }

  if (!borrow(buf, req_len, &refill)) {
    return -2;
  }
  
  buf->data = StringValuePtr(refill);
  buf->len = RSTRING(refill)->len;
  buf->pos = 0;
  
  return 0;
}


// read_bytes pulls a number of bytes (size) from the buffer, refilling if needed,
// and places them in dst. This should _always_ be used used when reading from the buffer
// or buffered transports will be upset with you.
static bool read_bytes(decode_buffer* buf, void* dst, size_t size) {
  int avail = (buf->len - buf->pos);
  
  if (size <= avail) {
    memcpy(dst, buf->data + buf->pos, size);
    buf->pos += size;
  } else {
    
    if (avail > 0) {
      // Copy what we can
      memcpy(dst, buf->data + buf->pos, avail);
      buf->pos += avail;
    }

    if (fill_buffer(buf, size - avail) < 0) {
      return false;
    }
    
    memcpy(dst + avail, buf->data, size - avail);
    buf->pos += size - avail;
  }
  
  return true;
}

// -----------------------------------------------------------------------------
// Helpers for grabbing specific types from the buffer
// -----------------------------------------------------------------------------

static bool read_byte(decode_buffer* buf, int8_t* data) {
  return read_bytes(buf, data, sizeof(int8_t));
}

static bool read_int16(decode_buffer* buf, int16_t* data) {
  bool success = read_bytes(buf, data, sizeof(int16_t));
  *data = ntohs(*data);
  
  return success;
}

static bool read_int32(decode_buffer* buf, int32_t* data) {
  bool success = read_bytes(buf, data, sizeof(int32_t));
  *data = ntohl(*data);
  
  return success;
}

static bool read_int64(decode_buffer* buf, int64_t* data) {
  bool success = read_bytes(buf, data, sizeof(int64_t));
  *data = ntohll(*data);
  
  return success;
}

static bool read_double(decode_buffer* buf, double* data) {
  return read_int64(buf, (int64_t*)data);
}

static bool read_string(decode_buffer* buf, VALUE* data) {
  int len;
  
  if (!read_int32(buf, &len)) {
    return false;
  }
  
  if (buf->len - buf->pos >= len) {
    *data = rb_str_new(buf->data + buf->pos, len);
    buf->pos += len;
  } 
  else {
    char* str;
    
    if ((str = (char*) malloc(len)) == NULL) {
      return false;
    }
    
    if (!read_bytes(buf, str, len)) {
      free(str);
      return false;
    }
    
    *data = rb_str_new(str, len);
    
    free(str);
  }
  
  return true;
}

static bool read_field_begin(decode_buffer* buf, field_header* header) {
#ifdef __DEBUG__ // No need for this in prod since I set all the fields
  bzero(header, sizeof(field_header));
#endif

  header->name = NULL;
  
  if (!read_byte(buf, &header->type)) {
    return false;
  }
  
  if (header->type == T_STOP) {
    header->id = 0;
  } else {
    if (!read_int16(buf, &header->id)) {
      return false;
    }
  }
  
  return true;
}

#define read_field_end(buf)

static bool read_map_begin(decode_buffer* buf, map_header* header) {
#ifdef __DEBUG__ // No need for this in prod since I set all the fields
  bzero(header, sizeof(map_header));
#endif
  
  return (read_byte(buf, &header->key_type) && 
          read_byte(buf, &header->val_type) &&
          read_int32(buf, &header->num_entries));
}

#define read_map_end(buf)

static bool read_list_begin(decode_buffer* buf, list_header* header) {
#ifdef __DEBUG__ // No need for this in prod since I set all the fields
  bzero(header, sizeof(list_header));
#endif
  
  if (!read_byte(buf, &header->type) || !read_int32(buf, &header->num_elements)) {
    return false;
  } else {
    return true;
  }
}

#define read_list_end(buf)

#define read_set_begin read_list_begin
#define read_set_end read_list_end


// High level reader function with ruby type coercion
static bool read_type(int type, decode_buffer* buf, VALUE* dst) {
  switch(type) {
    case T_BOOL: {
      int8_t byte;
      
      if (!read_byte(buf, &byte)) {
        return false;
      }
      
      if (0 == byte) {
        *dst = Qfalse;
      } else {
        *dst = Qtrue;
      }
      
      break;
    }
    
    case T_BYTE: {
      int8_t byte;

      if (!read_byte(buf, &byte)) {
        return false;
      }

      *dst = INT2FIX(byte);
      break;
    }
    
    case T_I16: {
      int16_t i16;
      
      if (!read_int16(buf, &i16)) {
        return false;
      }
      
      *dst = INT2FIX(i16);
      break;
    }

    case T_I32: {
      int32_t i32;
      
      if (!read_int32(buf, &i32)) {
        return false;
      }
      
      *dst = INT2NUM(i32);
      break;
    }

    case T_I64: {
      int64_t i64;
      
      if (!read_int64(buf, &i64)) {
        return false;
      }
      
      *dst = rb_ll2inum(i64);
      break;
    }
    
    case T_DBL: {
      double dbl;
      
      if (!read_double(buf, &dbl)) {
        return false;
      }
      
      *dst = rb_float_new(dbl);
      break;
    }

    case T_STR: {
      VALUE str;
      
      if (!read_string(buf, &str)) {
        return false;
      }
      
      *dst = str;
      break;
    }
  }
  
  return true;
}

// TODO(kevinclark): Now that read_string does a malloc,
// This maybe could be modified to avoid that, and the type coercion

// Read the bytes but don't do anything with the value
static bool skip_type(int type, decode_buffer* buf) {
  switch (type) {
    case T_STRCT:
      read_struct_begin(buf);
      while (true) {
        field_header header;

        if (!read_field_begin(buf, &header)) {
          return false;
        }

        if (header.type == T_STOP) {
          break;
        }

        if (!skip_type(header.type, buf)) {
          return false;
        }

        read_field_end(buf);
      }
      read_struct_end(buf);

      break;

    case T_MAP: {
      int i;
      map_header header;

      if (!read_map_begin(buf, &header)) {
        return false;
      }

      for (i = 0; i < header.num_entries; ++i) {
        if (!skip_type(header.key_type, buf)) {
          return false;
        }
        if (!skip_type(header.val_type, buf)) {
          return false;
        }
      }

      read_map_end(buf);
      break;
    }

    case T_SET: {
      int i;
      set_header header;

      if (!read_set_begin(buf, &header)) {
        return false;
      }

      for (i = 0; i < header.num_elements; ++i) {
        if (!skip_type(header.type, buf)) {
          return false;
        }
      }

      read_set_end(buf);
      break;
    }

    case T_LIST: {
      int i;
      list_header header;

      if (!read_list_begin(buf, &header)) {
        return false;
      }

      for (i = 0; i < header.num_elements; ++i) {
        if (!skip_type(header.type, buf)) {
          return false;
        }
      }

      read_list_end(buf);
      break;
    }

    default: {
      VALUE v;
      if (!read_type(type, buf, &v)) {
        return false;
      }
    }
  }

  return true;
}


static VALUE read_struct(VALUE obj, decode_buffer* buf);

// Read the right thing from the buffer given the field spec
// and return the ruby object
static bool read_field(decode_buffer* buf, field_spec* spec, VALUE* dst) {
  switch (spec->type) {
    case T_STRCT: {
      VALUE obj = rb_class_new_instance(0, NULL, spec->data.class);
      
      *dst = read_struct(obj, buf);
      break;
    }
    
    case T_MAP: {
      map_header hdr;
      VALUE hsh;
      int i;
      
      read_map_begin(buf, &hdr); 
      hsh = rb_hash_new();
      
      for (i = 0; i < hdr.num_entries; ++i) {
        VALUE key, val;
        
        if (!read_field(buf, spec->data.map->key, &key)) {
          return false;
        }
        
        if (!read_field(buf, spec->data.map->value, &val)) {
          return false;
        }
        
        rb_hash_aset(hsh, key, val);
      }
      
      read_map_end(buf);
      
      *dst = hsh;
      break;
    }
    
    case T_LIST: {
      list_header hdr;
      VALUE arr, element;
      int i;
      
      read_list_begin(buf, &hdr);
      arr = rb_ary_new2(hdr.num_elements);
      
      for (i = 0; i < hdr.num_elements; ++i) {
        if (!read_field(buf, spec->data.element, &element)) {
          return false;
        }

        rb_ary_push(arr, element);
      }
      
      read_list_end(buf);
      
      *dst = arr;
      break;
    }
    
    case T_SET: {
      VALUE items, item;
      set_header hdr;
      int i;
      
      read_set_begin(buf, &hdr);
      items = rb_ary_new2(hdr.num_elements);
      
      for (i = 0; i < hdr.num_elements; ++i) {
        if (!read_field(buf, spec->data.element, &item)) {
          return false;
        }
        
        rb_ary_push(items, item);
      }
      
      *dst = rb_class_new_instance(1, &items, rb_cSet);
      break;
    }
    
    
    default:
      return read_type(spec->type, buf, dst);
  }
  
  return true;
}

static void handle_read_error() {
  // If it was an exception, reraise
  if (!NIL_P(ruby_errinfo)) {
    rb_exc_raise(ruby_errinfo);
  } else {
    // Something else went wrong, no idea what would call this yet
    // So far, the only thing to cause failures underneath is ruby
    // exceptions. Follow up on this regularly -- Kevin Clark (TODO)
    rb_raise(rb_eStandardError, "[BUG] Something went wrong in the field reading, but not a ruby exception");
  }
}

// Fill in the instance variables in an object (thrift struct)
// from the decode buffer
static VALUE read_struct(VALUE obj, decode_buffer* buf) {
  VALUE field;
  field_header f_header;
  VALUE value = Qnil;
  VALUE fields = rb_const_get(CLASS_OF(obj), fields_id);
  field_spec* spec;
  char name_buf[128];
    
  read_struct_begin(buf);
  
  while(true) {
    if (!read_field_begin(buf, &f_header)) {
      handle_read_error();
    }
    
    if (T_STOP == f_header.type) {
      break;
    }
    
    field = rb_hash_aref(fields, INT2FIX(f_header.id));
    
    if (NIL_P(field)) {
      if (!skip_type(f_header.type, buf)) {
        handle_read_error();
        return Qnil;
      }
    } 
    else {
      spec = parse_field_spec(field);

      if (spec->type != f_header.type) {
        if (!skip_type(spec->type, buf)) {
          free_field_spec(spec);
          handle_read_error();
          return Qnil;
        }
      } else {
        // Read busted somewhere (probably borrow/consume), bail
        if (!read_field(buf, spec, &value)) {
          free_field_spec(spec);
          handle_read_error();
          return Qnil;
        }
        
        name_buf[0] = '@';
        strlcpy(&name_buf[1], spec->name, sizeof(name_buf) - 1);
        
        rb_iv_set(obj, name_buf, value);
      }
      
      free_field_spec(spec);
    }
    
    read_field_end(buf);
  }
  
  read_struct_end(buf);
  
  return obj;
}


// Takes an object and transport, and decodes the values in the transport's
// buffer to fill the object.
static VALUE tbpa_decode_binary(VALUE self, VALUE obj, VALUE transport) {
  decode_buffer buf;
  VALUE ret_val;

  buf.pos = 0;    // This needs to be set so an arbitrary number of bytes isn't consumed
  buf.trans = transport;       // We need to hold this so the buffer can be refilled
  
  if (fill_buffer(&buf, 0) < 0) {
    handle_read_error();
    return Qnil;
  }

#ifdef __DEBUG__
  rb_p(rb_str_new2("Running decode binary with data:"));
  rb_p(rb_inspect(rb_str_new2(buf.data)));
#endif
 
  ret_val = read_struct(obj, &buf);
  
  // Consume whatever was read
  consume(&buf, buf.pos);
  
  return ret_val;
}

// -----------------------------------------------------------------------------
// These methods are used by the thrift library and need to handled
// seperately from encode and decode
// -----------------------------------------------------------------------------

// Read the message header and return it as a ruby array
static VALUE tbpa_read_message_begin(VALUE self) {
  decode_buffer buf;
  int32_t version, seqid;
  int8_t type;
  VALUE name;
  
  VALUE trans = rb_iv_get(self, "@trans");
  
  buf.pos = 0;              // This needs to be set so fill_buffer doesn't consume
  buf.trans = trans;        // We need to hold this so the buffer can be refilled
  

  if (fill_buffer(&buf, 0) < 0 || !read_int32(&buf, &version)) {
    // Consume whatever was read
    consume(&buf, buf.pos);
    handle_read_error();
    return Qnil;
  }
  
  if ((version & VERSION_MASK) != VERSION_1) {
    VALUE tprotocol_exception = rb_const_get(rb_cObject, rb_intern("TProtocolException"));
    VALUE exception = rb_funcall(tprotocol_exception, rb_intern("new"), 2, rb_const_get(tprotocol_exception, rb_intern("BAD_VERSION")), rb_str_new2("Missing version identifier"));
    rb_raise(exception, "");
  }
  
  type = version & 0x000000ff;
  
  if (!read_string(&buf, &name) || !read_int32(&buf, &seqid)) {
    // Consume whatever was read
    consume(&buf, buf.pos);
    handle_read_error();
    return Qnil;
  }
  
  // Consume whatever was read
  if (consume(&buf, buf.pos) < 0) {
    handle_read_error();
    return Qnil;
  }
  
  return rb_ary_new3(3, name, INT2FIX(type), INT2FIX(seqid));
}

void Init_binaryprotocolaccelerated()
{
  m_thrift = rb_const_get(rb_cObject, rb_intern("Thrift"));
  VALUE class_tbinproto = rb_const_get(m_thrift, rb_intern("BinaryProtocol"));
  class_tbpa = rb_define_class_under(m_thrift, "BinaryProtocolAccelerated", class_tbinproto);
  type_sym = ID2SYM(rb_intern("type"));
  class_sym = ID2SYM(rb_intern("class"));
  key_sym = ID2SYM(rb_intern("key"));
  value_sym = ID2SYM(rb_intern("value"));
  name_sym = ID2SYM(rb_intern("name"));
  fields_id = rb_intern("FIELDS");
  element_sym = ID2SYM(rb_intern("element"));
  consume_bang_id = rb_intern("consume!");
  string_buffer_id = rb_intern("string_buffer");
  borrow_id = rb_intern("borrow");
  keys_id = rb_intern("keys");
  entries_id = rb_intern("entries");
  rb_cSet = rb_const_get(rb_cObject, rb_intern("Set"));
  
  // For fast access
  rb_define_method(class_tbpa, "encode_binary", tbpa_encode_binary, 1);
  rb_define_method(class_tbpa, "decode_binary", tbpa_decode_binary, 2);
  rb_define_method(class_tbpa, "read_message_begin", tbpa_read_message_begin, 0);
  
}
