123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /*
- * 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_TDISPATCHPROCESSOR_H_
- #define _THRIFT_TDISPATCHPROCESSOR_H_ 1
- #include <thrift/TProcessor.h>
- namespace apache {
- namespace thrift {
- /**
- * TDispatchProcessor is a helper class to parse the message header then call
- * another function to dispatch based on the function name.
- *
- * Subclasses must implement dispatchCall() to dispatch on the function name.
- */
- template <class Protocol_>
- class TDispatchProcessorT : public TProcessor {
- public:
- virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
- void* connectionContext) {
- protocol::TProtocol* inRaw = in.get();
- protocol::TProtocol* outRaw = out.get();
- // Try to dynamic cast to the template protocol type
- Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
- Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
- if (specificIn && specificOut) {
- return processFast(specificIn, specificOut, connectionContext);
- }
- // Log the fact that we have to use the slow path
- T_GENERIC_PROTOCOL(this, inRaw, specificIn);
- T_GENERIC_PROTOCOL(this, outRaw, specificOut);
- std::string fname;
- protocol::TMessageType mtype;
- int32_t seqid;
- inRaw->readMessageBegin(fname, mtype, seqid);
- // If this doesn't look like a valid call, log an error and return false so
- // that the server will close the connection.
- //
- // (The old generated processor code used to try to skip a T_STRUCT and
- // continue. However, that seems unsafe.)
- if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
- GlobalOutput.printf("received invalid message type %d from client", mtype);
- return false;
- }
- return this->dispatchCall(inRaw, outRaw, fname, seqid, connectionContext);
- }
- protected:
- bool processFast(Protocol_* in, Protocol_* out, void* connectionContext) {
- std::string fname;
- protocol::TMessageType mtype;
- int32_t seqid;
- in->readMessageBegin(fname, mtype, seqid);
- if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
- GlobalOutput.printf("received invalid message type %d from client", mtype);
- return false;
- }
- return this->dispatchCallTemplated(in, out, fname, seqid, connectionContext);
- }
- /**
- * dispatchCall() methods must be implemented by subclasses
- */
- virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
- apache::thrift::protocol::TProtocol* out,
- const std::string& fname,
- int32_t seqid,
- void* callContext) = 0;
- virtual bool dispatchCallTemplated(Protocol_* in,
- Protocol_* out,
- const std::string& fname,
- int32_t seqid,
- void* callContext) = 0;
- };
- /**
- * Non-templatized version of TDispatchProcessor, that doesn't bother trying to
- * perform a dynamic_cast.
- */
- class TDispatchProcessor : public TProcessor {
- public:
- virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
- void* connectionContext) {
- std::string fname;
- protocol::TMessageType mtype;
- int32_t seqid;
- in->readMessageBegin(fname, mtype, seqid);
- if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
- GlobalOutput.printf("received invalid message type %d from client", mtype);
- return false;
- }
- return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext);
- }
- protected:
- virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
- apache::thrift::protocol::TProtocol* out,
- const std::string& fname,
- int32_t seqid,
- void* callContext) = 0;
- };
- // Specialize TDispatchProcessorT for TProtocol and TDummyProtocol just to use
- // the generic TDispatchProcessor.
- template <>
- class TDispatchProcessorT<protocol::TDummyProtocol> : public TDispatchProcessor {};
- template <>
- class TDispatchProcessorT<protocol::TProtocol> : public TDispatchProcessor {};
- }
- } // apache::thrift
- #endif // _THRIFT_TDISPATCHPROCESSOR_H_
|