Update Thrift CPP libraries to work with new generated source, change underlying buffers to use uint8_t* instead of std::string

Summary: Major overhaul to the CPP libraries.

Reviewed By: aditya

Test Plan: Again, keep an eye out for the unit tests commit

Notes: Initial perf tests show that Thrift is not only more robust than Pillar, but its implementation is actually around 10-20% faster. We can do about 10 RPC function calls with small data payloads in under 2ms. THAT IS FAST. THAT IS THRIFTY.




git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664714 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/protocol/TProtocol.h b/lib/cpp/protocol/TProtocol.h
index 1f2e0c8..fe2d6ef 100644
--- a/lib/cpp/protocol/TProtocol.h
+++ b/lib/cpp/protocol/TProtocol.h
@@ -1,14 +1,42 @@
 #ifndef T_PROTOCOL_H
 #define T_PROTOCOL_H
 
+#include <netinet/in.h>
 #include <sys/types.h>
 #include <string>
 #include <map>
 
+#include "transport/TTransport.h"
+
+#define ntohll(x) (((uint64_t)(ntohl((int)((x << 32) >> 32))) << 32) | (uint32_t)ntohl(((int)(x >> 32))))
+
+#define htonll(x) ntohll(x)
+
 /** Forward declaration for TProtocol */
 struct TBuf;
 
 /**
+ * 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 TType {
+  T_STOP       = 1,
+  T_BYTE       = 2,
+  T_U16        = 3,
+  T_I16        = 4,
+  T_U32        = 5,
+  T_I32        = 6,
+  T_U64        = 7,
+  T_I64        = 8,
+  T_STRING     = 9,
+  T_STRUCT     = 10,
+  T_MAP        = 11,
+  T_SET        = 12,
+  T_LIST       = 13
+};
+
+/**
  * Abstract class for a thrift protocol driver. These are all the methods that
  * a protocol must implement. Essentially, there must be some way of reading
  * and writing all the base types, plus a mechanism for writing out structs
@@ -25,64 +53,211 @@
   virtual ~TProtocol() {}
 
   /**
-   * Function call serialization.
+   * Writing functions.
    */
 
-  virtual std::string
-    readFunction(TBuf& buf) const = 0;
-  virtual std::string
-    writeFunction(const std::string& name, const std::string& args) const = 0;
+  virtual uint32_t writeStructBegin   (TTransport*    out,
+                                       const std::string& name)   const = 0;
+
+  virtual uint32_t writeStructEnd     (TTransport*    out)        const = 0;
+
+  virtual uint32_t writeFieldBegin    (TTransport*    out,
+                                       const std::string& name,
+                                       const TType    fieldType,
+                                       const uint16_t fieldId)    const = 0;
+
+  virtual uint32_t writeFieldEnd      (TTransport*    out)        const = 0;
+
+  virtual uint32_t writeFieldStop     (TTransport*    out)        const = 0;
+                                      
+  virtual uint32_t writeMapBegin      (TTransport*    out,
+                                       const TType    keyType,
+                                       const TType    valType,
+                                       const uint32_t size)       const = 0;
+
+  virtual uint32_t writeMapEnd        (TTransport*    out)        const = 0;
+
+  virtual uint32_t writeListBegin     (TTransport*    out,
+                                       const TType    elemType,
+                                       const uint32_t size)       const = 0;
+
+  virtual uint32_t writeListEnd       (TTransport*    out)        const = 0;
+
+  virtual uint32_t writeSetBegin      (TTransport*    out,
+                                       const TType    elemType,
+                                       const uint32_t size)       const = 0;
+
+  virtual uint32_t writeSetEnd        (TTransport*    out)        const = 0;
+
+  virtual uint32_t writeByte          (TTransport*    out,
+                                       const uint8_t  byte)       const = 0;
+
+  virtual uint32_t writeU32           (TTransport*    out,
+                                       const uint32_t u32)        const = 0;
+
+  virtual uint32_t writeI32           (TTransport*    out,
+                                       const int32_t  i32)        const = 0;
+
+  virtual uint32_t writeU64           (TTransport*    out,
+                                       const uint64_t u64)        const = 0;
+
+  virtual uint32_t writeI64           (TTransport*    out,
+                                       const int64_t  i64)        const = 0;
+
+  virtual uint32_t writeString        (TTransport*    out,
+                                       const std::string& str)    const = 0;
 
   /**
-   * Struct serialization.
+   * Reading functions
    */
 
-  virtual std::map<uint32_t, TBuf>
-    readStruct(TBuf& buf) const = 0;
-  virtual std::string
-    writeStruct(const std::map<uint32_t,std::string>& s) const = 0;
+  virtual uint32_t readStructBegin    (TTransport*    in,
+                                       std::string& name)         const = 0;
+
+  virtual uint32_t readStructEnd      (TTransport*    in)         const = 0;
+
+  virtual uint32_t readFieldBegin     (TTransport*    in,
+                                       std::string&   name,
+                                       TType&         fieldType,
+                                       uint16_t&      fieldId)    const = 0;
+  
+  virtual uint32_t readFieldEnd       (TTransport*    in)         const = 0;
+ 
+  virtual uint32_t readMapBegin       (TTransport*    in,
+                                       TType&         keyType,
+                                       TType&         valType,
+                                       uint32_t&      size)       const = 0;
+
+  virtual uint32_t readMapEnd         (TTransport*    in)         const = 0;
+
+  virtual uint32_t readListBegin      (TTransport*    in,
+                                       TType&         elemType,
+                                       uint32_t&      size)       const = 0;
+
+  virtual uint32_t readListEnd        (TTransport*    in)         const = 0;
+
+  virtual uint32_t readSetBegin       (TTransport*    in,
+                                       TType&         elemType,
+                                       uint32_t&      size)       const = 0;
+
+  virtual uint32_t readSetEnd         (TTransport*    in)         const = 0;
+
+  virtual uint32_t readByte           (TTransport*    in,
+                                       uint8_t&       byte)       const = 0;
+
+  virtual uint32_t readU32            (TTransport*    in,
+                                       uint32_t&      u32)        const = 0;
+
+  virtual uint32_t readI32            (TTransport*    in,
+                                       int32_t&       i32)        const = 0;
+
+  virtual uint32_t readU64            (TTransport*    in,
+                                       uint64_t&      u64)        const = 0;
+
+  virtual uint32_t readI64            (TTransport*    in,
+                                       int64_t&       i64)        const = 0;
+
+  virtual uint32_t readString         (TTransport*    in,
+                                       std::string&   str)        const = 0;
 
   /**
-   * Basic data type deserialization. Note that these read methods do not
-   * take a const reference to the TBuf object. They SHOULD change the TBuf
-   * object so that it reflects the buffer AFTER the basic data type has
-   * been consumed such that data may continue being read serially from the
-   * buffer.
+   * Method to arbitrarily skip over data.
    */
-
-  virtual std::string readString  (TBuf& buf) const = 0;
-  virtual uint8_t     readByte    (TBuf& buf) const = 0;
-  virtual uint32_t    readU32     (TBuf& buf) const = 0;
-  virtual int32_t     readI32     (TBuf& buf) const = 0;
-  virtual uint64_t    readU64     (TBuf& buf) const = 0;
-  virtual int64_t     readI64     (TBuf& buf) const = 0;
-
-  virtual std::string writeString (const std::string& str) const = 0;
-  virtual std::string writeByte   (const uint8_t  byte)    const = 0;
-  virtual std::string writeU32    (const uint32_t u32)     const = 0;
-  virtual std::string writeI32    (const int32_t  i32)     const = 0;
-  virtual std::string writeU64    (const uint64_t u64)     const = 0;
-  virtual std::string writeI64    (const int64_t  i64)     const = 0;
+  uint32_t skip(TTransport* in, TType type) const {
+    switch (type) {
+    case T_BYTE:
+      {
+        uint8_t byte;
+        return readByte(in, byte);
+      }
+    case T_U32:
+      {
+        uint32_t u32;
+        return readU32(in, u32);
+      }
+    case T_I32:
+      {
+        int32_t i32;
+        return readI32(in, i32);
+      }
+    case T_U64:
+      {
+        uint64_t u64;
+        return readU64(in, u64);
+      }
+    case T_I64:
+      {
+        int64_t i64;
+        return readI64(in, i64);
+      }
+    case T_STRING:
+      {
+        std::string str;
+        return readString(in, str);
+      }
+    case T_STRUCT:
+      {
+        uint32_t result = 0;
+        std::string name;
+        uint16_t fid;
+        TType ftype;
+        result += readStructBegin(in, name);
+        while (true) {
+          result += readFieldBegin(in, name, ftype, fid);
+          if (ftype == T_STOP) {
+            break;
+          }
+          result += skip(in, ftype);
+          result += readFieldEnd(in);
+        }
+        result += readStructEnd(in);
+        return result;
+      }
+    case T_MAP:
+      {
+        uint32_t result = 0;
+        TType keyType;
+        TType valType;
+        uint32_t i, size;
+        result += readMapBegin(in, keyType, valType, size);
+        for (i = 0; i < size; i++) {
+          result += skip(in, keyType);
+          result += skip(in, valType);
+        }
+        result += readMapEnd(in);
+        return result;
+      }
+    case T_SET:
+      {
+        uint32_t result = 0;
+        TType elemType;
+        uint32_t i, size;
+        result += readSetBegin(in, elemType, size);
+        for (i = 0; i < size; i++) {
+          result += skip(in, elemType);
+        }
+        result += readSetEnd(in);
+        return result;
+      }
+    case T_LIST:
+      {
+        uint32_t result = 0;
+        TType elemType;
+        uint32_t i, size;
+        result += readListBegin(in, elemType, size);
+        for (i = 0; i < size; i++) {
+          result += skip(in, elemType);
+        }
+        result += readListEnd(in);
+        return result;
+      }
+    default:
+      return 0;
+    }
+  }
 
  protected:
   TProtocol() {}
 };
 
-/**
- * Wrapper around raw data that allows us to track the length of a data
- * buffer. It is the responsibility of a robust TProtocol implementation
- * to ensure that any reads that are done from data do NOT overrun the
- * memory address at data+len. It is also a convention that TBuf objects
- * do NOT own the memory pointed to by data. They are merely wrappers
- * around buffers that have been allocated elsewhere. Therefore, the user
- * should never allocate memory before putting it into a TBuf nor should
- * they free the data pointed to by a TBuf.
- */
-struct TBuf {
-  TBuf(const TBuf& that) : data(that.data), len(that.len) {}
-  TBuf(const uint8_t* d, uint32_t l) : data(d), len(l) {}
-  const uint8_t* data;
-  uint32_t len;
-};
-
 #endif