/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed 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_TRANSPORT_TVIRTUALTRANSPORT_H_ #define _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_ 1 #include 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 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 * e.g: class MyTransport : public TVirtualTransport { * 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 */ template > class TVirtualTransport : public Super_ { public: /* * Implementations of the *_virt() functions, to call the subclass's * non-virtual implementation function. */ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return static_cast(this)->read(buf, len); } uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { return static_cast(this)->readAll(buf, len); } void write_virt(const uint8_t* buf, uint32_t len) override { static_cast(this)->write(buf, len); } const uint8_t* borrow_virt(uint8_t* buf, uint32_t* len) override { return static_cast(this)->borrow(buf, len); } void consume_virt(uint32_t len) override { static_cast(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(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 TVirtualTransport(const Arg_& arg) : Super_(arg) {} template TVirtualTransport(const Arg1_& a1, const Arg2_& a2) : Super_(a1, a2) {} }; } // namespace transport } // namespace thrift } // namespace apache #endif // #ifndef _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_