135 lines
4.5 KiB
C
135 lines
4.5 KiB
C
|
// Copyright (c) 2006- Facebook
|
||
|
// Distributed under the Thrift Software License
|
||
|
//
|
||
|
// See accompanying file LICENSE or visit the Thrift site at:
|
||
|
// http://developers.facebook.com/thrift/
|
||
|
|
||
|
#ifndef _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_
|
||
|
#define _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_ 1
|
||
|
|
||
|
#include "thrift/lib/cpp/transport/TTransport.h"
|
||
|
|
||
|
namespace apache { namespace thrift { namespace transport {
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Helper class that provides default implementations of TTransport methods.
|
||
|
*
|
||
|
* This class provides default implementations of read(), readAll(), write(),
|
||
|
* borrow() and consume().
|
||
|
*
|
||
|
* In the TTransport base class, each of these methods simply invokes its
|
||
|
* virtual counterpart. This class overrides them to always perform the
|
||
|
* default behavior, without a virtual function call.
|
||
|
*
|
||
|
* The primary purpose of this class is to serve as a base class for
|
||
|
* TVirtualTransport, and prevent infinite recursion if one of its subclasses
|
||
|
* does not override the TTransport implementation of these methods. (Since
|
||
|
* TVirtualTransport::read_virt() calls read(), and TTransport::read() calls
|
||
|
* read_virt().)
|
||
|
*/
|
||
|
template <class Super_=TTransport>
|
||
|
class TTransportDefaults : public Super_ {
|
||
|
public:
|
||
|
/*
|
||
|
* TTransport *_virt() methods provide reasonable default implementations.
|
||
|
* Invoke them non-virtually.
|
||
|
*/
|
||
|
uint32_t read(uint8_t* buf, uint32_t len) {
|
||
|
return this->TTransport::read_virt(buf, len);
|
||
|
}
|
||
|
uint32_t readAll(uint8_t* buf, uint32_t len) {
|
||
|
return this->TTransport::readAll_virt(buf, len);
|
||
|
}
|
||
|
void write(const uint8_t* buf, uint32_t len) {
|
||
|
this->TTransport::write_virt(buf, len);
|
||
|
}
|
||
|
const uint8_t* borrow(uint8_t* buf, uint32_t* len) {
|
||
|
return this->TTransport::borrow_virt(buf, len);
|
||
|
}
|
||
|
void consume(uint32_t len) {
|
||
|
this->TTransport::consume_virt(len);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
TTransportDefaults() {}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Helper class to provide polymorphism for subclasses of TTransport.
|
||
|
*
|
||
|
* This class implements *_virt() methods of TTransport, to call the
|
||
|
* non-virtual versions of these functions in the proper subclass.
|
||
|
*
|
||
|
* To define your own transport class using TVirtualTransport:
|
||
|
* 1) Derive your subclass from TVirtualTransport<your class>
|
||
|
* e.g: class MyTransport : public TVirtualTransport<MyTransport> {
|
||
|
* 2) Provide your own implementations of read(), readAll(), etc.
|
||
|
* These methods should be non-virtual.
|
||
|
*
|
||
|
* Transport implementations that need to use virtual inheritance when
|
||
|
* inheriting from TTransport cannot use TVirtualTransport.
|
||
|
*
|
||
|
* @author Chad Walters <chad@powerset.com>
|
||
|
*/
|
||
|
template < class Transport_, class Super_=TTransportDefaults<TTransport> >
|
||
|
class TVirtualTransport : public Super_ {
|
||
|
public:
|
||
|
/*
|
||
|
* Implementations of the *_virt() functions, to call the subclass's
|
||
|
* non-virtual implementation function.
|
||
|
*/
|
||
|
virtual uint32_t read_virt(uint8_t* buf, uint32_t len) {
|
||
|
return static_cast<Transport_*>(this)->read(buf, len);
|
||
|
}
|
||
|
|
||
|
virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len) {
|
||
|
return static_cast<Transport_*>(this)->readAll(buf, len);
|
||
|
}
|
||
|
|
||
|
virtual void write_virt(const uint8_t* buf, uint32_t len) {
|
||
|
static_cast<Transport_*>(this)->write(buf, len);
|
||
|
}
|
||
|
|
||
|
virtual const uint8_t* borrow_virt(uint8_t* buf, uint32_t* len) {
|
||
|
return static_cast<Transport_*>(this)->borrow(buf, len);
|
||
|
}
|
||
|
|
||
|
virtual void consume_virt(uint32_t len) {
|
||
|
static_cast<Transport_*>(this)->consume(len);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Provide a default readAll() implementation that invokes
|
||
|
* read() non-virtually.
|
||
|
*
|
||
|
* Note: subclasses that use TVirtualTransport to derive from another
|
||
|
* transport implementation (i.e., not TTransportDefaults) should beware that
|
||
|
* this may override any non-default readAll() implementation provided by
|
||
|
* the parent transport class. They may need to redefine readAll() to call
|
||
|
* the correct parent implementation, if desired.
|
||
|
*/
|
||
|
uint32_t readAll(uint8_t* buf, uint32_t len) {
|
||
|
Transport_* trans = static_cast<Transport_*>(this);
|
||
|
return ::apache::thrift::transport::readAll(*trans, buf, len);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
TVirtualTransport() {}
|
||
|
|
||
|
/*
|
||
|
* Templatized constructors, to allow arguments to be passed to the Super_
|
||
|
* constructor. Currently we only support 0, 1, or 2 arguments, but
|
||
|
* additional versions can be added as needed.
|
||
|
*/
|
||
|
template <typename Arg_>
|
||
|
TVirtualTransport(Arg_ const& arg) : Super_(arg) { }
|
||
|
|
||
|
template <typename Arg1_, typename Arg2_>
|
||
|
TVirtualTransport(Arg1_ const& a1, Arg2_ const& a2) : Super_(a1, a2) { }
|
||
|
};
|
||
|
|
||
|
}}} // apache::thrift::transport
|
||
|
|
||
|
#endif // #ifndef _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_
|