Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:04

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements. See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership. The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License. You may obtain a copy of the License at
0009  *
0010  *   http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing,
0013  * software distributed under the License is distributed on an
0014  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015  * KIND, either express or implied. See the License for the
0016  * specific language governing permissions and limitations
0017  * under the License.
0018  */
0019 #ifndef _THRIFT_TDISPATCHPROCESSOR_H_
0020 #define _THRIFT_TDISPATCHPROCESSOR_H_ 1
0021 
0022 #include <thrift/TProcessor.h>
0023 
0024 namespace apache {
0025 namespace thrift {
0026 
0027 /**
0028  * TDispatchProcessor is a helper class to parse the message header then call
0029  * another function to dispatch based on the function name.
0030  *
0031  * Subclasses must implement dispatchCall() to dispatch on the function name.
0032  */
0033 template <class Protocol_>
0034 class TDispatchProcessorT : public TProcessor {
0035 public:
0036   bool process(std::shared_ptr<protocol::TProtocol> in,
0037                        std::shared_ptr<protocol::TProtocol> out,
0038                        void* connectionContext) override {
0039     protocol::TProtocol* inRaw = in.get();
0040     protocol::TProtocol* outRaw = out.get();
0041 
0042     // Try to dynamic cast to the template protocol type
0043     auto* specificIn = dynamic_cast<Protocol_*>(inRaw);
0044     auto* specificOut = dynamic_cast<Protocol_*>(outRaw);
0045     if (specificIn && specificOut) {
0046       return processFast(specificIn, specificOut, connectionContext);
0047     }
0048 
0049     // Log the fact that we have to use the slow path
0050     T_GENERIC_PROTOCOL(this, inRaw, specificIn);
0051     T_GENERIC_PROTOCOL(this, outRaw, specificOut);
0052 
0053     std::string fname;
0054     protocol::TMessageType mtype;
0055     int32_t seqid;
0056     inRaw->readMessageBegin(fname, mtype, seqid);
0057 
0058     // If this doesn't look like a valid call, log an error and return false so
0059     // that the server will close the connection.
0060     //
0061     // (The old generated processor code used to try to skip a T_STRUCT and
0062     // continue.  However, that seems unsafe.)
0063     if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
0064       GlobalOutput.printf("received invalid message type %d from client", mtype);
0065       return false;
0066     }
0067 
0068     return this->dispatchCall(inRaw, outRaw, fname, seqid, connectionContext);
0069   }
0070 
0071 protected:
0072   bool processFast(Protocol_* in, Protocol_* out, void* connectionContext) {
0073     std::string fname;
0074     protocol::TMessageType mtype;
0075     int32_t seqid;
0076     in->readMessageBegin(fname, mtype, seqid);
0077 
0078     if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
0079       GlobalOutput.printf("received invalid message type %d from client", mtype);
0080       return false;
0081     }
0082 
0083     return this->dispatchCallTemplated(in, out, fname, seqid, connectionContext);
0084   }
0085 
0086   /**
0087    * dispatchCall() methods must be implemented by subclasses
0088    */
0089   virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
0090                             apache::thrift::protocol::TProtocol* out,
0091                             const std::string& fname,
0092                             int32_t seqid,
0093                             void* callContext) = 0;
0094 
0095   virtual bool dispatchCallTemplated(Protocol_* in,
0096                                      Protocol_* out,
0097                                      const std::string& fname,
0098                                      int32_t seqid,
0099                                      void* callContext) = 0;
0100 };
0101 
0102 /**
0103  * Non-templatized version of TDispatchProcessor, that doesn't bother trying to
0104  * perform a dynamic_cast.
0105  */
0106 class TDispatchProcessor : public TProcessor {
0107 public:
0108   bool process(std::shared_ptr<protocol::TProtocol> in,
0109                        std::shared_ptr<protocol::TProtocol> out,
0110                        void* connectionContext) override {
0111     std::string fname;
0112     protocol::TMessageType mtype;
0113     int32_t seqid;
0114     in->readMessageBegin(fname, mtype, seqid);
0115 
0116     if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
0117       GlobalOutput.printf("received invalid message type %d from client", mtype);
0118       return false;
0119     }
0120 
0121     return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext);
0122   }
0123 
0124 protected:
0125   virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
0126                             apache::thrift::protocol::TProtocol* out,
0127                             const std::string& fname,
0128                             int32_t seqid,
0129                             void* callContext) = 0;
0130 };
0131 
0132 // Specialize TDispatchProcessorT for TProtocol and TDummyProtocol just to use
0133 // the generic TDispatchProcessor.
0134 template <>
0135 class TDispatchProcessorT<protocol::TDummyProtocol> : public TDispatchProcessor {};
0136 template <>
0137 class TDispatchProcessorT<protocol::TProtocol> : public TDispatchProcessor {};
0138 }
0139 } // apache::thrift
0140 
0141 #endif // _THRIFT_TDISPATCHPROCESSOR_H_