Rev 30 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements. See the NOTICE file* distributed with this work for additional information* regarding copyright ownership. The ASF licenses this file* to you under the Apache License, Version 2.0 (the* "License"); you may not use this file except in compliance* with the License. You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY* KIND, either express or implied. See the License for the* specific language governing permissions and limitations* under the License.*/#ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_#define _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_ 1#include "TBinaryProtocol.h"namespace apache { namespace thrift { namespace protocol {/*** !!!WARNING!!!* This class is still highly experimental. Incompatible changes* WILL be made to it without notice. DO NOT USE IT YET unless* you are coordinating your testing with the author.** The dense protocol is designed to use as little space as possible.** There are two types of dense protocol instances. Standalone instances* are not used for RPC and just encoded and decode structures of* a predetermined type. Non-standalone instances are used for RPC.* Currently, only standalone instances exist.** To use a standalone dense protocol object, you must set the type_spec* property (either in the constructor, or with setTypeSpec) to the local* reflection TypeSpec of the structures you will write to (or read from) the* protocol instance.** BEST PRACTICES:* - Never use optional for primitives or containers.* - Only use optional for structures if they are very big and very rarely set.* - All integers are variable-length, so you can use i64 without bloating.* - NEVER EVER change the struct definitions IN ANY WAY without either* changing your cache keys or talking to dreiss.** TODO(dreiss): New class write with old meta.** We override all of TBinaryProtocol's methods.* We inherit so that we can can explicitly call TBPs's primitive-writing* methods within our versions.**/class TDenseProtocol : public TBinaryProtocol {protected:static const int32_t VERSION_MASK = 0xffff0000;// VERSION_1 (0x80010000) is taken by TBinaryProtocol.static const int32_t VERSION_2 = 0x80020000;public:typedef apache::thrift::reflection::local::TypeSpec TypeSpec;static const int FP_PREFIX_LEN;/*** @param tran The transport to use.* @param type_spec The TypeSpec of the structures using this protocol.*/TDenseProtocol(boost::shared_ptr<TTransport> trans,TypeSpec* type_spec = NULL) :TBinaryProtocol(trans),type_spec_(type_spec),standalone_(true){}void setTypeSpec(TypeSpec* type_spec) {type_spec_ = type_spec;}TypeSpec* getTypeSpec() {return type_spec_;}/** Writing functions.*/virtual uint32_t writeMessageBegin(const std::string& name,const TMessageType messageType,const int32_t seqid);virtual uint32_t writeMessageEnd();virtual uint32_t writeStructBegin(const char* name);virtual uint32_t writeStructEnd();virtual uint32_t writeFieldBegin(const char* name,const TType fieldType,const int16_t fieldId);virtual uint32_t writeFieldEnd();virtual uint32_t writeFieldStop();virtual uint32_t writeMapBegin(const TType keyType,const TType valType,const uint32_t size);virtual uint32_t writeMapEnd();virtual uint32_t writeListBegin(const TType elemType,const uint32_t size);virtual uint32_t writeListEnd();virtual uint32_t writeSetBegin(const TType elemType,const uint32_t size);virtual uint32_t writeSetEnd();virtual uint32_t writeBool(const bool value);virtual uint32_t writeByte(const int8_t byte);virtual uint32_t writeI16(const int16_t i16);virtual uint32_t writeI32(const int32_t i32);virtual uint32_t writeI64(const int64_t i64);virtual uint32_t writeDouble(const double dub);virtual uint32_t writeString(const std::string& str);virtual uint32_t writeBinary(const std::string& str);/** Helper writing functions (don't do state transitions).*/inline uint32_t subWriteI32(const int32_t i32);inline uint32_t subWriteString(const std::string& str);uint32_t subWriteBool(const bool value) {return TBinaryProtocol::writeBool(value);}/** Reading functions*/uint32_t readMessageBegin(std::string& name,TMessageType& messageType,int32_t& seqid);uint32_t readMessageEnd();uint32_t readStructBegin(std::string& name);uint32_t readStructEnd();uint32_t readFieldBegin(std::string& name,TType& fieldType,int16_t& fieldId);uint32_t readFieldEnd();uint32_t readMapBegin(TType& keyType,TType& valType,uint32_t& size);uint32_t readMapEnd();uint32_t readListBegin(TType& elemType,uint32_t& size);uint32_t readListEnd();uint32_t readSetBegin(TType& elemType,uint32_t& size);uint32_t readSetEnd();uint32_t readBool(bool& value);uint32_t readByte(int8_t& byte);uint32_t readI16(int16_t& i16);uint32_t readI32(int32_t& i32);uint32_t readI64(int64_t& i64);uint32_t readDouble(double& dub);uint32_t readString(std::string& str);uint32_t readBinary(std::string& str);/** Helper reading functions (don't do state transitions).*/inline uint32_t subReadI32(int32_t& i32);inline uint32_t subReadString(std::string& str);uint32_t subReadBool(bool& value) {return TBinaryProtocol::readBool(value);}private:// Implementation functions, documented in the .cpp.inline void checkTType(const TType ttype);inline void stateTransition();// Read and write variable-length integers.// Uses the same technique as the MIDI file format.inline uint32_t vlqRead(uint64_t& vlq);inline uint32_t vlqWrite(uint64_t vlq);// Called before throwing an exception to make the object reusable.void resetState() {ts_stack_.clear();idx_stack_.clear();mkv_stack_.clear();}// TypeSpec of the top-level structure to write,// for standalone protocol objects.TypeSpec* type_spec_;std::vector<TypeSpec*> ts_stack_; // TypeSpec stack.std::vector<int> idx_stack_; // InDeX stack.std::vector<bool> mkv_stack_; // Map Key/Vlue stack.// True = key, False = value.// True iff this is a standalone instance (no RPC).bool standalone_;};}}} // apache::thrift::protocol#endif // #ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_