| #ifndef T_PROTOCOL_H | 
 | #define T_PROTOCOL_H | 
 |  | 
 | #include <sys/types.h> | 
 | #include <string> | 
 | #include <map> | 
 |  | 
 | /** Forward declaration for TProtocol */ | 
 | struct TBuf; | 
 |  | 
 | /** | 
 |  * 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 | 
 |  * with indexed fields. Also notice that all methods are strictly const. This | 
 |  * is by design. Protcol impelementations may NOT keep state, because the | 
 |  * same TProtocol object may be used simultaneously by multiple threads. This | 
 |  * theoretically introduces some limititations into the possible protocol | 
 |  * formats, but with the benefit of performance, clarity, and simplicity. | 
 |  * | 
 |  * @author Mark Slee <mcslee@facebook.com> | 
 |  */ | 
 | class TProtocol { | 
 |  public: | 
 |   virtual ~TProtocol() {} | 
 |  | 
 |   /** | 
 |    * Function call serialization. | 
 |    */ | 
 |  | 
 |   virtual std::string | 
 |     readFunction(TBuf& buf) const = 0; | 
 |   virtual std::string | 
 |     writeFunction(const std::string& name, const std::string& args) const = 0; | 
 |  | 
 |   /** | 
 |    * Struct serialization. | 
 |    */ | 
 |  | 
 |   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; | 
 |  | 
 |   /** | 
 |    * 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. | 
 |    */ | 
 |  | 
 |   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; | 
 |  | 
 |  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 |