1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-27 21:01:50 +03:00

remove commited old thrift, replace with static lib build from exterrnal project

This commit is contained in:
Leonid Fedorov
2022-12-15 16:18:03 +00:00
parent f6318f515a
commit 3b68353429
101 changed files with 58 additions and 19282 deletions

View File

@ -118,6 +118,7 @@ SET (ENGINE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE(columnstore_version)
INCLUDE(misc)
INCLUDE(boost)
INCLUDE(thrift)
FIND_PACKAGE(BISON)
IF (NOT BISON_FOUND)
@ -245,7 +246,7 @@ SET (ENGINE_DT_LIB datatypes)
SET (ENGINE_COMMON_LIBS messageqcpp loggingcpp configcpp idbboot boost_thread xml2 pthread rt ${ENGINE_DT_LIB})
SET (ENGINE_OAM_LIBS oamcpp)
SET (ENGINE_BRM_LIBS brm idbdatafile cacheutils rwlock ${ENGINE_OAM_LIBS} ${ENGINE_COMMON_LIBS})
SET (PLUGIN_EXEC_LIBS execplan windowfunction joiner rowgroup funcexp udfsdk regr dataconvert common compress querytele thrift threadpool ${ENGINE_BRM_LIBS})
SET (PLUGIN_EXEC_LIBS execplan windowfunction joiner rowgroup funcexp udfsdk regr dataconvert common compress querytele threadpool ${ENGINE_BRM_LIBS})
SET (ENGINE_EXEC_LIBS joblist querystats libmysql_client ${PLUGIN_EXEC_LIBS})
SET (PLUGIN_WRITE_LIBS ddlpackageproc ddlpackage dmlpackageproc dmlpackage writeengine writeengineclient idbdatafile cacheutils)
SET (ENGINE_WRITE_LIBS ${PLUGIN_WRITE_LIBS} ${ENGINE_EXEC_LIBS})
@ -327,7 +328,6 @@ SET (ENGINE_DBCON_DMLPKGPROC_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/dbcon/dmlpack
SET (ENGINE_UTILS_CACHEUTILS_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/cacheutils")
SET (ENGINE_UTILS_MYSQLCL_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/mysqlcl_idb")
SET (ENGINE_UTILS_QUERYTELE_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/querytele")
SET (ENGINE_UTILS_THRIFT_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/thrift")
SET (ENGINE_UTILS_JOINER_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/joiner")
SET (ENGINE_UTILS_THREADPOOL_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/threadpool")
SET (ENGINE_UTILS_BATCHLDR_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/batchloader")

29
cmake/thrift.cmake Normal file
View File

@ -0,0 +1,29 @@
include(ExternalProject)
set(INSTALL_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/external/thrift)
SET(THRIFT_INCLUDE_DIRS "${INSTALL_LOCATION}/include")
SET(THRIFT_LIBRARY_DIRS "${INSTALL_LOCATION}/lib")
set(THRIFT_LIBRARY ${THRIFT_LIBRARY_DIRS}/${CMAKE_STATIC_LIBRARY_PREFIX}thrift${CMAKE_STATIC_LIBRARY_SUFFIX})
ExternalProject_Add(external_thrift
URL https://github.com/apache/thrift/archive/refs/tags/v0.17.0.tar.gz
URL_HASH SHA256=f5888bcd3b8de40c2c2ab86896867ad9b18510deb412cba3e5da76fb4c604c29
PREFIX ${INSTALL_LOCATION}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${INSTALL_LOCATION}
-DBUILD_COMPILER=YES
-DBUILD_CPP=YES
-DBUILD_C_GLIB=YES
-DBUILD_JAVA=NO
-DBUILD_JAVASCRIPT=NO
-DBUILD_KOTLIN=NO
-DBUILD_NODEJS=NO
-DBUILD_PYTHON=NO
-DBUILD_TESTING=NO
-DBUILD_SHARED_LIBS=NO
-DCMAKE_CXX_FLAGS:STRING="-fPIC"
-DBOOST_INCLUDEDIR=${Boost_INCLUDE_DIRS}
-DBOOST_LIBRARYDIR=${Boost_LIBRARY_DIRS}
)
add_dependencies(external_thrift external_boost)

View File

@ -79,7 +79,6 @@ usr/lib/*/librowgroup.so
usr/lib/*/librwlock.so
usr/lib/*/libstoragemanager.so
usr/lib/*/libthreadpool.so
usr/lib/*/libthrift.so
usr/lib/*/libudfsdk.so
usr/lib/*/libwindowfunction.so
usr/lib/*/libwriteengine.so

View File

@ -20,7 +20,6 @@ add_subdirectory(querystats)
add_subdirectory(windowfunction)
add_subdirectory(idbdatafile)
add_subdirectory(winport)
add_subdirectory(thrift)
add_subdirectory(querytele)
add_subdirectory(libmysql_client)
add_subdirectory(regr)

View File

@ -13,7 +13,9 @@ set(querytele_LIB_SRCS
queryteleprotoimpl.cpp)
add_library(querytele SHARED ${querytele_LIB_SRCS})
add_dependencies(querytele external_boost)
add_dependencies(querytele external_boost external_thrift)
target_include_directories(querytele PRIVATE ${THRIFT_INCLUDE_DIRS})
target_link_libraries(querytele ${THRIFT_LIBRARY})
install(TARGETS querytele DESTINATION ${ENGINE_LIBDIR} COMPONENT columnstore-engine)

View File

@ -844,12 +844,12 @@ void QueryTeleServiceProcessor::process_postImport(int32_t seqid,
}
}
::boost::shared_ptr< ::apache::thrift::TProcessor> QueryTeleServiceProcessorFactory::getProcessor(
::std::shared_ptr< ::apache::thrift::TProcessor> QueryTeleServiceProcessorFactory::getProcessor(
const ::apache::thrift::TConnectionInfo& connInfo)
{
::apache::thrift::ReleaseHandler<QueryTeleServiceIfFactory> cleanup(handlerFactory_);
::boost::shared_ptr<QueryTeleServiceIf> handler(handlerFactory_->getHandler(connInfo), cleanup);
::boost::shared_ptr< ::apache::thrift::TProcessor> processor(new QueryTeleServiceProcessor(handler));
::std::shared_ptr<QueryTeleServiceIf> handler(handlerFactory_->getHandler(connInfo), cleanup);
::std::shared_ptr< ::apache::thrift::TProcessor> processor(new QueryTeleServiceProcessor(handler));
return processor;
}
} // namespace querytele

View File

@ -9,6 +9,7 @@
#include <thrift/TDispatchProcessor.h>
#include "querytele_types.h"
namespace querytele
{
class QueryTeleServiceIf
@ -38,7 +39,7 @@ class QueryTeleServiceIfFactory
class QueryTeleServiceIfSingletonFactory : virtual public QueryTeleServiceIfFactory
{
public:
QueryTeleServiceIfSingletonFactory(const boost::shared_ptr<QueryTeleServiceIf>& iface) : iface_(iface)
QueryTeleServiceIfSingletonFactory(const std::shared_ptr<QueryTeleServiceIf>& iface) : iface_(iface)
{
}
virtual ~QueryTeleServiceIfSingletonFactory()
@ -54,7 +55,7 @@ class QueryTeleServiceIfSingletonFactory : virtual public QueryTeleServiceIfFact
}
protected:
boost::shared_ptr<QueryTeleServiceIf> iface_;
std::shared_ptr<QueryTeleServiceIf> iface_;
};
class QueryTeleServiceNull : virtual public QueryTeleServiceIf
@ -362,24 +363,24 @@ class QueryTeleService_postImport_presult
class QueryTeleServiceClient : virtual public QueryTeleServiceIf
{
public:
QueryTeleServiceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot)
QueryTeleServiceClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot)
: piprot_(prot), poprot_(prot)
{
iprot_ = prot.get();
oprot_ = prot.get();
}
QueryTeleServiceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot,
boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot)
QueryTeleServiceClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot,
std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot)
: piprot_(iprot), poprot_(oprot)
{
iprot_ = iprot.get();
oprot_ = oprot.get();
}
boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol()
std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol()
{
return piprot_;
}
boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol()
std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol()
{
return poprot_;
}
@ -394,8 +395,8 @@ class QueryTeleServiceClient : virtual public QueryTeleServiceIf
void recv_postImport();
protected:
boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
::apache::thrift::protocol::TProtocol* iprot_;
::apache::thrift::protocol::TProtocol* oprot_;
};
@ -403,7 +404,7 @@ class QueryTeleServiceClient : virtual public QueryTeleServiceIf
class QueryTeleServiceProcessor : public ::apache::thrift::TDispatchProcessor
{
protected:
boost::shared_ptr<QueryTeleServiceIf> iface_;
std::shared_ptr<QueryTeleServiceIf> iface_;
virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot,
::apache::thrift::protocol::TProtocol* oprot, const std::string& fname,
int32_t seqid, void* callContext);
@ -421,7 +422,7 @@ class QueryTeleServiceProcessor : public ::apache::thrift::TDispatchProcessor
::apache::thrift::protocol::TProtocol* oprot, void* callContext);
public:
QueryTeleServiceProcessor(boost::shared_ptr<QueryTeleServiceIf> iface) : iface_(iface)
QueryTeleServiceProcessor(std::shared_ptr<QueryTeleServiceIf> iface) : iface_(iface)
{
processMap_["postQuery"] = &QueryTeleServiceProcessor::process_postQuery;
processMap_["postStep"] = &QueryTeleServiceProcessor::process_postStep;
@ -436,22 +437,22 @@ class QueryTeleServiceProcessor : public ::apache::thrift::TDispatchProcessor
class QueryTeleServiceProcessorFactory : public ::apache::thrift::TProcessorFactory
{
public:
QueryTeleServiceProcessorFactory(const ::boost::shared_ptr<QueryTeleServiceIfFactory>& handlerFactory)
QueryTeleServiceProcessorFactory(const ::std::shared_ptr<QueryTeleServiceIfFactory>& handlerFactory)
: handlerFactory_(handlerFactory)
{
}
::boost::shared_ptr< ::apache::thrift::TProcessor> getProcessor(
::std::shared_ptr< ::apache::thrift::TProcessor> getProcessor(
const ::apache::thrift::TConnectionInfo& connInfo);
protected:
::boost::shared_ptr<QueryTeleServiceIfFactory> handlerFactory_;
::std::shared_ptr<QueryTeleServiceIfFactory> handlerFactory_;
};
class QueryTeleServiceMultiface : virtual public QueryTeleServiceIf
{
public:
QueryTeleServiceMultiface(std::vector<boost::shared_ptr<QueryTeleServiceIf> >& ifaces) : ifaces_(ifaces)
QueryTeleServiceMultiface(std::vector<std::shared_ptr<QueryTeleServiceIf> >& ifaces) : ifaces_(ifaces)
{
}
virtual ~QueryTeleServiceMultiface()
@ -459,11 +460,11 @@ class QueryTeleServiceMultiface : virtual public QueryTeleServiceIf
}
protected:
std::vector<boost::shared_ptr<QueryTeleServiceIf> > ifaces_;
std::vector<std::shared_ptr<QueryTeleServiceIf> > ifaces_;
QueryTeleServiceMultiface()
{
}
void add(boost::shared_ptr<QueryTeleServiceIf> iface)
void add(std::shared_ptr<QueryTeleServiceIf> iface)
{
ifaces_.push_back(iface);
}

View File

@ -11,7 +11,6 @@
#include <thrift/protocol/TProtocol.h>
#include <thrift/transport/TTransport.h>
#include <thrift/cxxfunctional.h>
namespace querytele
{

View File

@ -22,7 +22,6 @@ using namespace std;
#define BOOST_DISABLE_ASSERTS
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include "thrift/transport/TSocket.h"
#include "thrift/transport/TBufferTransports.h"
@ -59,9 +58,9 @@ TsTeleQueue<querytele::ImportTele> itQueue;
volatile bool isInited = false;
boost::mutex initMux;
boost::shared_ptr<att::TSocket> fSocket;
boost::shared_ptr<att::TBufferedTransport> fTransport;
boost::shared_ptr<atp::TBinaryProtocol> fProtocol;
std::shared_ptr<att::TSocket> fSocket;
std::shared_ptr<att::TBufferedTransport> fTransport;
std::shared_ptr<atp::TBinaryProtocol> fProtocol;
querytele::StepTele gLastStep;

View File

@ -1,21 +0,0 @@
include_directories( ${ENGINE_COMMON_INCLUDES} )
########### next target ###############
set(thrift_LIB_SRCS
thrift/Thrift.cpp
thrift/server/TSimpleServer.cpp
thrift/transport/TSocket.cpp
thrift/transport/TServerSocket.cpp
thrift/transport/TBufferTransports.cpp
thrift/TApplicationException.cpp)
add_definitions(-DTHRIFT_SQUELCH_CONSOLE_OUTPUT)
add_library(thrift SHARED ${thrift_LIB_SRCS})
add_dependencies(thrift external_boost)
install(TARGETS thrift DESTINATION ${ENGINE_LIBDIR} COMPONENT columnstore-engine)

View File

@ -1,6 +0,0 @@
This is Apache Thrift 0.9.1
Actually, this is just the bits and pieces of the API necessary to work
with InfiniDB. It is provided as a convenience to source builders so
that they don't have to find and install Thrift

View File

@ -1,102 +0,0 @@
/*
* 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.
*/
#include <thrift/TApplicationException.h>
#include <thrift/protocol/TProtocol.h>
namespace apache
{
namespace thrift
{
uint32_t TApplicationException::read(apache::thrift::protocol::TProtocol* iprot)
{
uint32_t xfer = 0;
std::string fname;
apache::thrift::protocol::TType ftype;
int16_t fid;
xfer += iprot->readStructBegin(fname);
while (true)
{
xfer += iprot->readFieldBegin(fname, ftype, fid);
if (ftype == apache::thrift::protocol::T_STOP)
{
break;
}
switch (fid)
{
case 1:
if (ftype == apache::thrift::protocol::T_STRING)
{
xfer += iprot->readString(message_);
}
else
{
xfer += iprot->skip(ftype);
}
break;
case 2:
if (ftype == apache::thrift::protocol::T_I32)
{
int32_t type;
xfer += iprot->readI32(type);
type_ = (TApplicationExceptionType)type;
}
else
{
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
}
xfer += iprot->readFieldEnd();
}
xfer += iprot->readStructEnd();
return xfer;
}
uint32_t TApplicationException::write(apache::thrift::protocol::TProtocol* oprot) const
{
uint32_t xfer = 0;
xfer += oprot->writeStructBegin("TApplicationException");
xfer += oprot->writeFieldBegin("message", apache::thrift::protocol::T_STRING, 1);
xfer += oprot->writeString(message_);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("type", apache::thrift::protocol::T_I32, 2);
xfer += oprot->writeI32(type_);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
}
} // apache::thrift

View File

@ -1,149 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/Thrift.h>
namespace apache
{
namespace thrift
{
namespace protocol
{
class TProtocol;
}
class TApplicationException : public TException
{
public:
/**
* Error codes for the various types of exceptions.
*/
enum TApplicationExceptionType
{
UNKNOWN = 0,
UNKNOWN_METHOD = 1,
INVALID_MESSAGE_TYPE = 2,
WRONG_METHOD_NAME = 3,
BAD_SEQUENCE_ID = 4,
MISSING_RESULT = 5,
INTERNAL_ERROR = 6,
PROTOCOL_ERROR = 7,
INVALID_TRANSFORM = 8,
INVALID_PROTOCOL = 9,
UNSUPPORTED_CLIENT_TYPE = 10
};
TApplicationException() :
TException(),
type_(UNKNOWN) {}
TApplicationException(TApplicationExceptionType type) :
TException(),
type_(type) {}
TApplicationException(const std::string& message) :
TException(message),
type_(UNKNOWN) {}
TApplicationException(TApplicationExceptionType type,
const std::string& message) :
TException(message),
type_(type) {}
virtual ~TApplicationException() throw() {}
/**
* Returns an error code that provides information about the type of error
* that has occurred.
*
* @return Error code
*/
TApplicationExceptionType getType()
{
return type_;
}
virtual const char* what() const throw()
{
if (message_.empty())
{
switch (type_)
{
case UNKNOWN :
return "TApplicationException: Unknown application exception";
case UNKNOWN_METHOD :
return "TApplicationException: Unknown method";
case INVALID_MESSAGE_TYPE :
return "TApplicationException: Invalid message type";
case WRONG_METHOD_NAME :
return "TApplicationException: Wrong method name";
case BAD_SEQUENCE_ID :
return "TApplicationException: Bad sequence identifier";
case MISSING_RESULT :
return "TApplicationException: Missing result";
case INTERNAL_ERROR :
return "TApplicationException: Internal error";
case PROTOCOL_ERROR :
return "TApplicationException: Protocol error";
case INVALID_TRANSFORM :
return "TApplicationException: Invalid transform";
case INVALID_PROTOCOL :
return "TApplicationException: Invalid protocol";
case UNSUPPORTED_CLIENT_TYPE :
return "TApplicationException: Unsupported client type";
default :
return "TApplicationException: (Invalid exception type)";
};
}
else
{
return message_.c_str();
}
}
uint32_t read(protocol::TProtocol* iprot);
uint32_t write(protocol::TProtocol* oprot) const;
protected:
/**
* Error code
*/
TApplicationExceptionType type_;
};
}
} // apache::thrift

View File

@ -1,154 +0,0 @@
/*
* 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.
*/
#pragma once
#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(boost::shared_ptr<protocol::TProtocol> in,
boost::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(boost::shared_ptr<protocol::TProtocol> in,
boost::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

View File

@ -1,191 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/thrift-config.h>
/**
* Contains utility macros for debugging and logging.
*
*/
#include <time.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
/**
* T_GLOBAL_DEBUGGING_LEVEL = 0: all debugging turned off, debug macros undefined
* T_GLOBAL_DEBUGGING_LEVEL = 1: all debugging turned on
*/
#define T_GLOBAL_DEBUGGING_LEVEL 0
/**
* T_GLOBAL_LOGGING_LEVEL = 0: all logging turned off, logging macros undefined
* T_GLOBAL_LOGGING_LEVEL = 1: all logging turned on
*/
#define T_GLOBAL_LOGGING_LEVEL 1
/**
* Standard wrapper around fprintf what will prefix the file name and line
* number to the line. Uses T_GLOBAL_DEBUGGING_LEVEL to control whether it is
* turned on or off.
*
* @param format_string
*/
#if T_GLOBAL_DEBUGGING_LEVEL > 0
#define T_DEBUG(format_string,...) \
if (T_GLOBAL_DEBUGGING_LEVEL > 0) { \
fprintf(stderr,"[%s,%d] " format_string " \n", __FILE__, __LINE__,##__VA_ARGS__); \
}
#else
#define T_DEBUG(format_string,...)
#endif
/**
* analagous to T_DEBUG but also prints the time
*
* @param string format_string input: printf style format string
*/
#if T_GLOBAL_DEBUGGING_LEVEL > 0
#define T_DEBUG_T(format_string,...) \
{ \
if (T_GLOBAL_DEBUGGING_LEVEL > 0) { \
time_t now; \
char dbgtime[26] ; \
time(&now); \
THRIFT_CTIME_R(&now, dbgtime); \
dbgtime[24] = '\0'; \
fprintf(stderr,"[%s,%d] [%s] " format_string " \n", __FILE__, __LINE__,dbgtime,##__VA_ARGS__); \
} \
}
#else
#define T_DEBUG_T(format_string,...)
#endif
/**
* analagous to T_DEBUG but uses input level to determine whether or not the string
* should be logged.
*
* @param int level: specified debug level
* @param string format_string input: format string
*/
#define T_DEBUG_L(level, format_string,...) \
if ((level) > 0) { \
fprintf(stderr,"[%s,%d] " format_string " \n", __FILE__, __LINE__,##__VA_ARGS__); \
}
/**
* Explicit error logging. Prints time, file name and line number
*
* @param string format_string input: printf style format string
*/
#define T_ERROR(format_string,...) \
{ \
time_t now; \
char dbgtime[26] ; \
time(&now); \
THRIFT_CTIME_R(&now, dbgtime); \
dbgtime[24] = '\0'; \
fprintf(stderr,"[%s,%d] [%s] ERROR: " format_string " \n", __FILE__, __LINE__,dbgtime,##__VA_ARGS__); \
}
/**
* Analagous to T_ERROR, additionally aborting the process.
* WARNING: macro calls abort(), ending program execution
*
* @param string format_string input: printf style format string
*/
#define T_ERROR_ABORT(format_string,...) \
{ \
time_t now; \
char dbgtime[26] ; \
time(&now); \
THRIFT_CTIME_R(&now, dbgtime); \
dbgtime[24] = '\0'; \
fprintf(stderr,"[%s,%d] [%s] ERROR: Going to abort " format_string " \n", __FILE__, __LINE__,dbgtime,##__VA_ARGS__); \
exit(1); \
}
/**
* Log input message
*
* @param string format_string input: printf style format string
*/
#if T_GLOBAL_LOGGING_LEVEL > 0
#define T_LOG_OPER(format_string,...) \
{ \
if (T_GLOBAL_LOGGING_LEVEL > 0) { \
time_t now; \
char dbgtime[26] ; \
time(&now); \
THRIFT_CTIME_R(&now, dbgtime); \
dbgtime[24] = '\0'; \
fprintf(stderr,"[%s] " format_string " \n", dbgtime,##__VA_ARGS__); \
} \
}
#else
#define T_LOG_OPER(format_string,...)
#endif
/**
* T_GLOBAL_DEBUG_VIRTUAL = 0 or unset: normal operation,
* virtual call debug messages disabled
* T_GLOBAL_DEBUG_VIRTUAL = 1: log a debug messages whenever an
* avoidable virtual call is made
* T_GLOBAL_DEBUG_VIRTUAL = 2: record detailed info that can be
* printed by calling
* apache::thrift::profile_print_info()
*/
#if T_GLOBAL_DEBUG_VIRTUAL > 1
#define T_VIRTUAL_CALL() \
::apache::thrift::profile_virtual_call(typeid(*this))
#define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \
do { \
if (!(specific_prot)) { \
::apache::thrift::profile_generic_protocol( \
typeid(*template_class), typeid(*generic_prot)); \
} \
} while (0)
#elif T_GLOBAL_DEBUG_VIRTUAL == 1
#define T_VIRTUAL_CALL() \
fprintf(stderr,"[%s,%d] virtual call\n", __FILE__, __LINE__)
#define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \
do { \
if (!(specific_prot)) { \
fprintf(stderr, \
"[%s,%d] failed to cast to specific protocol type\n", \
__FILE__, __LINE__); \
} \
} while (0)
#else
#define T_VIRTUAL_CALL()
#define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot)
#endif

View File

@ -1,262 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#include <thrift/protocol/TProtocol.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
/**
* Virtual interface class that can handle events from the processor. To
* use this you should subclass it and implement the methods that you care
* about. Your subclass can also store local data that you may care about,
* such as additional "arguments" to these methods (stored in the object
* instance's state).
*/
class TProcessorEventHandler
{
public:
virtual ~TProcessorEventHandler() {}
/**
* Called before calling other callback methods.
* Expected to return some sort of context object.
* The return value is passed to all other callbacks
* for that function invocation.
*/
virtual void* getContext(const char* fn_name, void* serverContext)
{
(void) fn_name;
(void) serverContext;
return NULL;
}
/**
* Expected to free resources associated with a context.
*/
virtual void freeContext(void* ctx, const char* fn_name)
{
(void) ctx;
(void) fn_name;
}
/**
* Called before reading arguments.
*/
virtual void preRead(void* ctx, const char* fn_name)
{
(void) ctx;
(void) fn_name;
}
/**
* Called between reading arguments and calling the handler.
*/
virtual void postRead(void* ctx, const char* fn_name, uint32_t bytes)
{
(void) ctx;
(void) fn_name;
(void) bytes;
}
/**
* Called between calling the handler and writing the response.
*/
virtual void preWrite(void* ctx, const char* fn_name)
{
(void) ctx;
(void) fn_name;
}
/**
* Called after writing the response.
*/
virtual void postWrite(void* ctx, const char* fn_name, uint32_t bytes)
{
(void) ctx;
(void) fn_name;
(void) bytes;
}
/**
* Called when an async function call completes successfully.
*/
virtual void asyncComplete(void* ctx, const char* fn_name)
{
(void) ctx;
(void) fn_name;
}
/**
* Called if the handler throws an undeclared exception.
*/
virtual void handlerError(void* ctx, const char* fn_name)
{
(void) ctx;
(void) fn_name;
}
protected:
TProcessorEventHandler() {}
};
/**
* A helper class used by the generated code to free each context.
*/
class TProcessorContextFreer
{
public:
TProcessorContextFreer(TProcessorEventHandler* handler, void* context, const char* method) :
handler_(handler), context_(context), method_(method) {}
~TProcessorContextFreer()
{
if (handler_ != NULL) handler_->freeContext(context_, method_);
}
void unregister()
{
handler_ = NULL;
}
private:
apache::thrift::TProcessorEventHandler* handler_;
void* context_;
const char* method_;
};
/**
* A processor is a generic object that acts upon two streams of data, one
* an input and the other an output. The definition of this object is loose,
* though the typical case is for some sort of server that either generates
* responses to an input stream or forwards data from one pipe onto another.
*
*/
class TProcessor
{
public:
virtual ~TProcessor() {}
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out,
void* connectionContext) = 0;
bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> io,
void* connectionContext)
{
return process(io, io, connectionContext);
}
boost::shared_ptr<TProcessorEventHandler> getEventHandler()
{
return eventHandler_;
}
void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler)
{
eventHandler_ = eventHandler;
}
protected:
TProcessor() {}
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
};
/**
* This is a helper class to allow boost::shared_ptr to be used with handler
* pointers returned by the generated handler factories.
*
* The handler factory classes generated by the thrift compiler return raw
* pointers, and factory->releaseHandler() must be called when the handler is
* no longer needed.
*
* A ReleaseHandler object can be instantiated and passed as the second
* parameter to a shared_ptr, so that factory->releaseHandler() will be called
* when the object is no longer needed, instead of deleting the pointer.
*/
template<typename HandlerFactory_>
class ReleaseHandler
{
public:
ReleaseHandler(const boost::shared_ptr<HandlerFactory_>& handlerFactory) :
handlerFactory_(handlerFactory) {}
void operator()(typename HandlerFactory_::Handler* handler)
{
if (handler)
{
handlerFactory_->releaseHandler(handler);
}
}
private:
boost::shared_ptr<HandlerFactory_> handlerFactory_;
};
struct TConnectionInfo
{
// The input and output protocols
boost::shared_ptr<protocol::TProtocol> input;
boost::shared_ptr<protocol::TProtocol> output;
// The underlying transport used for the connection
// This is the transport that was returned by TServerTransport::accept(),
// and it may be different than the transport pointed to by the input and
// output protocols.
boost::shared_ptr<transport::TTransport> transport;
};
class TProcessorFactory
{
public:
virtual ~TProcessorFactory() {}
/**
* Get the TProcessor to use for a particular connection.
*
* This method is always invoked in the same thread that the connection was
* accepted on. This generally means that this call does not need to be
* thread safe, as it will always be invoked from a single thread.
*/
virtual boost::shared_ptr<TProcessor> getProcessor(
const TConnectionInfo& connInfo) = 0;
};
class TSingletonProcessorFactory : public TProcessorFactory
{
public:
TSingletonProcessorFactory(boost::shared_ptr<TProcessor> processor) :
processor_(processor) {}
boost::shared_ptr<TProcessor> getProcessor(const TConnectionInfo&)
{
return processor_;
}
private:
boost::shared_ptr<TProcessor> processor_;
};
}
} // apache::thrift

View File

@ -1,110 +0,0 @@
/*
* 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.
*/
#pragma once
#include <stdint.h>
#include <cstring>
#include <thrift/protocol/TProtocol.h>
/**
* Local Reflection is a blanket term referring to the the structure
* and generation of this particular representation of Thrift types.
* (It is called local because it cannot be serialized by Thrift).
*
*/
namespace apache
{
namespace thrift
{
namespace reflection
{
namespace local
{
using apache::thrift::protocol::TType;
// We include this many bytes of the structure's fingerprint when serializing
// a top-level structure. Long enough to make collisions unlikely, short
// enough to not significantly affect the amount of memory used.
const int FP_PREFIX_LEN = 4;
struct FieldMeta
{
int16_t tag;
bool is_optional;
};
struct TypeSpec
{
TType ttype;
uint8_t fp_prefix[FP_PREFIX_LEN];
// Use an anonymous union here so we can fit two TypeSpecs in one cache line.
union
{
struct
{
// Use parallel arrays here for denser packing (of the arrays).
FieldMeta* metas;
TypeSpec** specs;
} tstruct;
struct
{
TypeSpec* subtype1;
TypeSpec* subtype2;
} tcontainer;
};
// Static initialization of unions isn't really possible,
// so take the plunge and use constructors.
// Hopefully they'll be evaluated at compile time.
TypeSpec(TType ttype) : ttype(ttype)
{
std::memset(fp_prefix, 0, FP_PREFIX_LEN);
}
TypeSpec(TType ttype,
const uint8_t* fingerprint,
FieldMeta* metas,
TypeSpec** specs) :
ttype(ttype)
{
std::memcpy(fp_prefix, fingerprint, FP_PREFIX_LEN);
tstruct.metas = metas;
tstruct.specs = specs;
}
TypeSpec(TType ttype, TypeSpec* subtype1, TypeSpec* subtype2) :
ttype(ttype)
{
std::memset(fp_prefix, 0, FP_PREFIX_LEN);
tcontainer.subtype1 = subtype1;
tcontainer.subtype2 = subtype2;
}
};
}
}
}
} // apache::thrift::reflection::local

View File

@ -1,145 +0,0 @@
/*
* 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.
*/
#include <thrift/Thrift.h>
#include <cstring>
#include <cstdlib>
#include <boost/lexical_cast.hpp>
#include <stdarg.h>
#include <stdio.h>
namespace apache
{
namespace thrift
{
TOutput GlobalOutput;
void TOutput::printf(const char* message, ...)
{
#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
// Try to reduce heap usage, even if printf is called rarely.
static const int STACK_BUF_SIZE = 256;
char stack_buf[STACK_BUF_SIZE];
va_list ap;
#ifdef _MSC_VER
va_start(ap, message);
int need = _vscprintf(message, ap);
va_end(ap);
if (need < STACK_BUF_SIZE)
{
va_start(ap, message);
vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
va_end(ap);
f_(stack_buf);
return;
}
#else
va_start(ap, message);
int need = vsnprintf(stack_buf, STACK_BUF_SIZE, message, ap);
va_end(ap);
if (need < STACK_BUF_SIZE)
{
f_(stack_buf);
return;
}
#endif
char* heap_buf = (char*)malloc((need + 1) * sizeof(char));
if (heap_buf == NULL)
{
#ifdef _MSC_VER
va_start(ap, message);
vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
va_end(ap);
#endif
// Malloc failed. We might as well print the stack buffer.
f_(stack_buf);
return;
}
va_start(ap, message);
int rval = vsnprintf(heap_buf, need + 1, message, ap);
va_end(ap);
// TODO(shigin): inform user
if (rval != -1)
{
f_(heap_buf);
}
free(heap_buf);
#endif
}
void TOutput::errorTimeWrapper(const char* msg)
{
#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
time_t now;
char dbgtime[26];
time(&now);
THRIFT_CTIME_R(&now, dbgtime);
dbgtime[24] = 0;
fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg);
#endif
}
void TOutput::perror(const char* message, int errno_copy)
{
std::string out = message + strerror_s(errno_copy);
f_(out.c_str());
}
std::string TOutput::strerror_s(int errno_copy)
{
#ifndef HAVE_STRERROR_R
return "errno = " + boost::lexical_cast<std::string>(errno_copy);
#else // HAVE_STRERROR_R
char b_errbuf[1024] = { '\0' };
#ifdef STRERROR_R_CHAR_P
char* b_error = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
#else
char* b_error = b_errbuf;
int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
if (rv == -1)
{
// strerror_r failed. omgwtfbbq.
return "XSI-compliant strerror_r() failed with errno = " +
boost::lexical_cast<std::string>(errno_copy);
}
#endif
// Can anyone prove that explicit cast is probably not necessary
// to ensure that the string object is constructed before
// b_error becomes invalid?
return std::string(b_error);
#endif // HAVE_STRERROR_R
}
}
} // apache::thrift

View File

@ -1,226 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/PlatformSocket.h>
#include <thrift/thrift-config.h>
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <string>
#include <map>
#include <list>
#include <set>
#include <vector>
#include <exception>
#include <typeinfo>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <thrift/TLogging.h>
/**
* Helper macros to allow function overloading even when using
* boost::shared_ptr.
*
* shared_ptr makes overloading really annoying, since shared_ptr defines
* constructor methods to allow one shared_ptr type to be constructed from any
* other shared_ptr type. (Even if it would be a compile error to actually try
* to instantiate the constructor.) These macros add an extra argument to the
* function to cause it to only be instantiated if a pointer of type T is
* convertible to a pointer of type U.
*
* THRIFT_OVERLOAD_IF should be used in function declarations.
* THRIFT_OVERLOAD_IF_DEFN should be used in the function definition, if it is
* defined separately from where it is declared.
*/
#define THRIFT_OVERLOAD_IF_DEFN(T, Y) \
typename ::boost::enable_if<typename ::boost::is_convertible<T*, Y*>::type, \
void*>::type
#define THRIFT_OVERLOAD_IF(T, Y) \
THRIFT_OVERLOAD_IF_DEFN(T, Y) = NULL
#define THRIFT_UNUSED_VARIABLE(x) ((x)=(x))
namespace apache
{
namespace thrift
{
class TEnumIterator : public std::iterator<std::forward_iterator_tag, std::pair<int, const char*> >
{
public:
TEnumIterator(int n,
int* enums,
const char** names) :
ii_(0), n_(n), enums_(enums), names_(names)
{
}
int operator ++()
{
return ++ii_;
}
bool operator !=(const TEnumIterator& end)
{
assert(end.n_ == -1);
return (ii_ != n_);
}
std::pair<int, const char*> operator*() const
{
return std::make_pair(enums_[ii_], names_[ii_]);
}
private:
int ii_;
const int n_;
int* enums_;
const char** names_;
};
class TOutput
{
public:
TOutput() : f_(&errorTimeWrapper) {}
inline void setOutputFunction(void (*function)(const char*))
{
f_ = function;
}
inline void operator()(const char* message)
{
f_(message);
}
// It is important to have a const char* overload here instead of
// just the string version, otherwise errno could be corrupted
// if there is some problem allocating memory when constructing
// the string.
void perror(const char* message, int errno_copy);
inline void perror(const std::string& message, int errno_copy)
{
perror(message.c_str(), errno_copy);
}
void printf(const char* message, ...);
static void errorTimeWrapper(const char* msg);
/** Just like strerror_r but returns a C++ string object. */
static std::string strerror_s(int errno_copy);
private:
void (*f_)(const char*);
};
extern TOutput GlobalOutput;
class TException : public std::exception
{
public:
TException():
message_() {}
TException(const std::string& message) :
message_(message) {}
virtual ~TException() throw() {}
virtual const char* what() const throw()
{
if (message_.empty())
{
return "Default TException.";
}
else
{
return message_.c_str();
}
}
protected:
std::string message_;
};
// Forward declare this structure used by TDenseProtocol
namespace reflection
{
namespace local
{
struct TypeSpec;
}
}
class TDelayedException
{
public:
template <class E> static TDelayedException* delayException(const E& e);
virtual void throw_it() = 0;
virtual ~TDelayedException() {};
};
template <class E> class TExceptionWrapper : public TDelayedException
{
public:
TExceptionWrapper(const E& e) : e_(e) {}
virtual void throw_it()
{
E temp(e_);
delete this;
throw temp;
}
private:
E e_;
};
template <class E>
TDelayedException* TDelayedException::delayException(const E& e)
{
return new TExceptionWrapper<E>(e);
}
#if T_GLOBAL_DEBUG_VIRTUAL > 1
void profile_virtual_call(const std::type_info& info);
void profile_generic_protocol(const std::type_info& template_type,
const std::type_info& prot_type);
void profile_print_info(FILE* f);
void profile_print_info();
void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f);
#endif
}
} // apache::thrift

View File

@ -1,52 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/cxxfunctional.h>
#include <boost/shared_ptr.hpp>
#include <thrift/transport/TBufferTransports.h>
namespace apache
{
namespace thrift
{
namespace async
{
class TAsyncBufferProcessor
{
public:
// Process data in "in", putting the result in "out".
// Call _return(true) when done, or _return(false) to
// forcefully close the connection (if applicable).
// "in" and "out" should be TMemoryBuffer or similar,
// not a wrapper around a socket.
virtual void process(
apache::thrift::stdcxx::function<void(bool healthy)> _return,
boost::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
boost::shared_ptr<apache::thrift::transport::TBufferBase> obuf) = 0;
virtual ~TAsyncBufferProcessor() {}
};
}
}
} // apache::thrift::async

View File

@ -1,79 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/cxxfunctional.h>
#include <thrift/Thrift.h>
namespace apache
{
namespace thrift
{
namespace transport
{
class TMemoryBuffer;
}
}
}
namespace apache
{
namespace thrift
{
namespace async
{
using apache::thrift::transport::TMemoryBuffer;
class TAsyncChannel
{
public:
typedef apache::thrift::stdcxx::function<void()> VoidCallback;
virtual ~TAsyncChannel() {}
// is the channel in a good state?
virtual bool good() const = 0;
virtual bool error() const = 0;
virtual bool timedOut() const = 0;
/**
* Send a message over the channel.
*/
virtual void sendMessage(const VoidCallback& cob,
apache::thrift::transport::TMemoryBuffer* message) = 0;
/**
* Receive a message from the channel.
*/
virtual void recvMessage(const VoidCallback& cob,
apache::thrift::transport::TMemoryBuffer* message) = 0;
/**
* Send a message over the channel and receive a response.
*/
virtual void sendAndRecvMessage(const VoidCallback& cob,
apache::thrift::transport::TMemoryBuffer* sendBuf,
apache::thrift::transport::TMemoryBuffer* recvBuf);
};
}
}
} // apache::thrift::async

View File

@ -1,164 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/async/TAsyncProcessor.h>
namespace apache
{
namespace thrift
{
namespace async
{
/**
* TAsyncDispatchProcessor 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 TAsyncDispatchProcessorT : public TAsyncProcessor
{
public:
virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out)
{
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(_return, specificIn, specificOut);
}
// 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;
}
return this->dispatchCall(_return, inRaw, outRaw, fname, seqid);
}
void processFast(apache::thrift::stdcxx::function<void(bool success)> _return,
Protocol_* in, Protocol_* out)
{
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;
}
return this->dispatchCallTemplated(_return, in, out, fname, seqid);
}
virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
apache::thrift::protocol::TProtocol* in,
apache::thrift::protocol::TProtocol* out,
const std::string& fname, int32_t seqid) = 0;
virtual void dispatchCallTemplated(apache::thrift::stdcxx::function<void(bool ok)> _return,
Protocol_* in, Protocol_* out,
const std::string& fname,
int32_t seqid) = 0;
};
/**
* Non-templatized version of TAsyncDispatchProcessor,
* that doesn't bother trying to perform a dynamic_cast.
*/
class TAsyncDispatchProcessor : public TAsyncProcessor
{
public:
virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out)
{
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();
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;
}
return dispatchCall(_return, inRaw, outRaw, fname, seqid);
}
virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
apache::thrift::protocol::TProtocol* in,
apache::thrift::protocol::TProtocol* out,
const std::string& fname, int32_t seqid) = 0;
};
// Specialize TAsyncDispatchProcessorT for TProtocol and TDummyProtocol just to
// use the generic TDispatchProcessor.
template <>
class TAsyncDispatchProcessorT<protocol::TDummyProtocol> :
public TAsyncDispatchProcessor {};
template <>
class TAsyncDispatchProcessorT<protocol::TProtocol> :
public TAsyncDispatchProcessor {};
}
}
} // apache::thrift::async

View File

@ -1,113 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/cxxfunctional.h>
#include <boost/shared_ptr.hpp>
#include <thrift/protocol/TProtocol.h>
#include <thrift/TProcessor.h>
namespace apache
{
namespace thrift
{
namespace async
{
/**
* Async version of a TProcessor. It is not expected to complete by the time
* the call to process returns. Instead, it calls a cob to signal completion.
*/
class TEventServer; // forward declaration
class TAsyncProcessor
{
public:
virtual ~TAsyncProcessor() {}
virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out) = 0;
void process(apache::thrift::stdcxx::function<void(bool success)> _return,
boost::shared_ptr<apache::thrift::protocol::TProtocol> io)
{
return process(_return, io, io);
}
boost::shared_ptr<TProcessorEventHandler> getEventHandler()
{
return eventHandler_;
}
void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler)
{
eventHandler_ = eventHandler;
}
const TEventServer* getAsyncServer()
{
return asyncServer_;
}
protected:
TAsyncProcessor() {}
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
const TEventServer* asyncServer_;
private:
friend class TEventServer;
void setAsyncServer(const TEventServer* server)
{
asyncServer_ = server;
}
};
class TAsyncProcessorFactory
{
public:
virtual ~TAsyncProcessorFactory() {}
/**
* Get the TAsyncProcessor to use for a particular connection.
*
* This method is always invoked in the same thread that the connection was
* accepted on. This generally means that this call does not need to be
* thread safe, as it will always be invoked from a single thread.
*/
virtual boost::shared_ptr<TAsyncProcessor> getProcessor(
const TConnectionInfo& connInfo) = 0;
};
}
}
} // apache::thrift::async
// XXX I'm lazy for now
namespace apache
{
namespace thrift
{
using apache::thrift::async::TAsyncProcessor;
}
}

View File

@ -1,63 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/async/TAsyncProcessor.h>
#include <thrift/async/TAsyncBufferProcessor.h>
#include <thrift/protocol/TProtocol.h>
namespace apache
{
namespace thrift
{
namespace async
{
class TAsyncProtocolProcessor : public TAsyncBufferProcessor
{
public:
TAsyncProtocolProcessor(
boost::shared_ptr<TAsyncProcessor> underlying,
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact)
: underlying_(underlying)
, pfact_(pfact)
{}
virtual void process(
apache::thrift::stdcxx::function<void(bool healthy)> _return,
boost::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
boost::shared_ptr<apache::thrift::transport::TBufferBase> obuf);
virtual ~TAsyncProtocolProcessor() {}
private:
static void finish(
apache::thrift::stdcxx::function<void(bool healthy)> _return,
boost::shared_ptr<apache::thrift::protocol::TProtocol> oprot,
bool healthy);
boost::shared_ptr<TAsyncProcessor> underlying_;
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
};
}
}
} // apache::thrift::async

View File

@ -1,98 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#include <boost/shared_ptr.hpp>
#include <thrift/async/TAsyncChannel.h>
struct event_base;
struct evhttp_connection;
struct evhttp_request;
namespace apache
{
namespace thrift
{
namespace transport
{
class TMemoryBuffer;
}
}
}
namespace apache
{
namespace thrift
{
namespace async
{
class TEvhttpClientChannel : public TAsyncChannel
{
public:
using TAsyncChannel::VoidCallback;
TEvhttpClientChannel(
const std::string& host,
const std::string& path,
const char* address,
int port,
struct event_base* eb);
~TEvhttpClientChannel();
virtual void sendAndRecvMessage(const VoidCallback& cob,
apache::thrift::transport::TMemoryBuffer* sendBuf,
apache::thrift::transport::TMemoryBuffer* recvBuf);
virtual void sendMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message);
virtual void recvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message);
void finish(struct evhttp_request* req);
//XXX
virtual bool good() const
{
return true;
}
virtual bool error() const
{
return false;
}
virtual bool timedOut() const
{
return false;
}
private:
static void response(struct evhttp_request* req, void* arg);
std::string host_;
std::string path_;
VoidCallback cob_;
apache::thrift::transport::TMemoryBuffer* recvBuf_;
struct evhttp_connection* conn_;
};
}
}
} // apache::thrift::async

View File

@ -1,77 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/shared_ptr.hpp>
struct event_base;
struct evhttp;
struct evhttp_request;
namespace apache
{
namespace thrift
{
namespace async
{
class TAsyncBufferProcessor;
class TEvhttpServer
{
public:
/**
* Create a TEvhttpServer for use with an external evhttp instance.
* Must be manually installed with evhttp_set_cb, using
* TEvhttpServer::request as the callback and the
* address of the server as the extra arg.
* Do not call "serve" on this server.
*/
TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor);
/**
* Create a TEvhttpServer with an embedded event_base and evhttp,
* listening on port and responding on the endpoint "/".
* Call "serve" on this server to serve forever.
*/
TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port);
~TEvhttpServer();
static void request(struct evhttp_request* req, void* self);
int serve();
struct event_base* getEventBase();
private:
struct RequestContext;
void process(struct evhttp_request* req);
void complete(RequestContext* ctx, bool success);
boost::shared_ptr<TAsyncBufferProcessor> processor_;
struct event_base* eb_;
struct evhttp* eh_;
};
}
}
} // apache::thrift::async

View File

@ -1,81 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* A thread factory to create posix threads
*
* @version $Id:$
*/
class BoostThreadFactory : public ThreadFactory
{
public:
/**
* Boost thread factory. All threads created by a factory are reference-counted
* via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
* the Runnable tasks they host will be properly cleaned up once the last strong reference
* to both is given up.
*
* Threads are created with the specified boost policy, priority, stack-size. A detachable thread is not
* joinable.
*
* By default threads are not joinable.
*/
BoostThreadFactory(bool detached = true);
// From ThreadFactory;
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
// From ThreadFactory;
Thread::id_t getCurrentThreadId() const;
/**
* Sets detached mode of threads
*/
virtual void setDetached(bool detached);
/**
* Gets current detached mode
*/
virtual bool isDetached() const;
private:
class Impl;
boost::shared_ptr<Impl> impl_;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,73 +0,0 @@
/*
* 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.
*/
#pragma once
#include <exception>
#include <thrift/Thrift.h>
namespace apache
{
namespace thrift
{
namespace concurrency
{
class NoSuchTaskException : public apache::thrift::TException {};
class UncancellableTaskException : public apache::thrift::TException {};
class InvalidArgumentException : public apache::thrift::TException {};
class IllegalStateException : public apache::thrift::TException
{
public:
IllegalStateException() {}
IllegalStateException(const std::string& message) : TException(message) {}
};
class TimedOutException : public apache::thrift::TException
{
public:
TimedOutException(): TException("TimedOutException") {};
TimedOutException(const std::string& message ) :
TException(message) {}
};
class TooManyPendingTasksException : public apache::thrift::TException
{
public:
TooManyPendingTasksException(): TException("TooManyPendingTasksException") {};
TooManyPendingTasksException(const std::string& message ) :
TException(message) {}
};
class SystemResourceException : public apache::thrift::TException
{
public:
SystemResourceException() {}
SystemResourceException(const std::string& message) :
TException(message) {}
};
}
}
} // apache::thrift::concurrency

View File

@ -1,134 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/cxxfunctional.h>
#include <thrift/concurrency/Thread.h>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* Convenient implementation of Runnable that will execute arbitrary callbacks.
* Interfaces are provided to accept both a generic 'void(void)' callback, and
* a 'void* (void*)' pthread_create-style callback.
*
* Example use:
* void* my_thread_main(void* arg);
* shared_ptr<ThreadFactory> factory = ...;
* // To create a thread that executes my_thread_main once:
* shared_ptr<Thread> thread = factory->newThread(
* FunctionRunner::create(my_thread_main, some_argument));
* thread->start();
*
* bool A::foo();
* A* a = new A();
* // To create a thread that executes a.foo() every 100 milliseconds:
* factory->newThread(FunctionRunner::create(
* apache::thrift::stdcxx::bind(&A::foo, a), 100))->start();
*
*/
class FunctionRunner : public Runnable
{
public:
// This is the type of callback 'pthread_create()' expects.
typedef void* (*PthreadFuncPtr)(void* arg);
// This a fully-generic void(void) callback for custom bindings.
typedef apache::thrift::stdcxx::function<void()> VoidFunc;
typedef apache::thrift::stdcxx::function<bool()> BoolFunc;
/**
* Syntactic sugar to make it easier to create new FunctionRunner
* objects wrapped in shared_ptr.
*/
static boost::shared_ptr<FunctionRunner> create(const VoidFunc& cob)
{
return boost::shared_ptr<FunctionRunner>(new FunctionRunner(cob));
}
static boost::shared_ptr<FunctionRunner> create(PthreadFuncPtr func,
void* arg)
{
return boost::shared_ptr<FunctionRunner>(new FunctionRunner(func, arg));
}
private:
static void pthread_func_wrapper(PthreadFuncPtr func, void* arg)
{
//discard return value
func(arg);
}
public:
/**
* Given a 'pthread_create' style callback, this FunctionRunner will
* execute the given callback. Note that the 'void*' return value is ignored.
*/
FunctionRunner(PthreadFuncPtr func, void* arg)
: func_(apache::thrift::stdcxx::bind(pthread_func_wrapper, func, arg))
{ }
/**
* Given a generic callback, this FunctionRunner will execute it.
*/
FunctionRunner(const VoidFunc& cob)
: func_(cob)
{ }
/**
* Given a bool foo(...) type callback, FunctionRunner will execute
* the callback repeatedly with 'intervalMs' milliseconds between the calls,
* until it returns false. Note that the actual interval between calls will
* be intervalMs plus execution time of the callback.
*/
FunctionRunner(const BoolFunc& cob, int intervalMs)
: repFunc_(cob), intervalMs_(intervalMs)
{ }
void run()
{
if (repFunc_)
{
while (repFunc_())
{
THRIFT_SLEEP_USEC(intervalMs_ * 1000);
}
}
else
{
func_();
}
}
private:
VoidFunc func_;
BoolFunc repFunc_;
int intervalMs_;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,137 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Mutex.h>
#include <boost/utility.hpp>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* A monitor is a combination mutex and condition-event. Waiting and
* notifying condition events requires that the caller own the mutex. Mutex
* lock and unlock operations can be performed independently of condition
* events. This is more or less analogous to java.lang.Object multi-thread
* operations.
*
* Note the Monitor can create a new, internal mutex; alternatively, a
* separate Mutex can be passed in and the Monitor will re-use it without
* taking ownership. It's the user's responsibility to make sure that the
* Mutex is not deallocated before the Monitor.
*
* Note that all methods are const. Monitors implement logical constness, not
* bit constness. This allows const methods to call monitor methods without
* needing to cast away constness or change to non-const signatures.
*
* @version $Id:$
*/
class Monitor : boost::noncopyable
{
public:
/** Creates a new mutex, and takes ownership of it. */
Monitor();
/** Uses the provided mutex without taking ownership. */
explicit Monitor(Mutex* mutex);
/** Uses the mutex inside the provided Monitor without taking ownership. */
explicit Monitor(Monitor* monitor);
/** Deallocates the mutex only if we own it. */
virtual ~Monitor();
Mutex& mutex() const;
virtual void lock() const;
virtual void unlock() const;
/**
* Waits a maximum of the specified timeout in milliseconds for the condition
* to occur, or waits forever if timeout_ms == 0.
*
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
int waitForTimeRelative(int64_t timeout_ms) const;
/**
* Waits until the absolute time specified using struct THRIFT_TIMESPEC.
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
int waitForTime(const THRIFT_TIMESPEC* abstime) const;
/**
* Waits until the absolute time specified using struct timeval.
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
int waitForTime(const struct timeval* abstime) const;
/**
* Waits forever until the condition occurs.
* Returns 0 if condition occurs, or an error code otherwise.
*/
int waitForever() const;
/**
* Exception-throwing version of waitForTimeRelative(), called simply
* wait(int64) for historical reasons. Timeout is in milliseconds.
*
* If the condition occurs, this function returns cleanly; on timeout or
* error an exception is thrown.
*/
void wait(int64_t timeout_ms = 0LL) const;
/** Wakes up one thread waiting on this monitor. */
virtual void notify() const;
/** Wakes up all waiting threads on this monitor. */
virtual void notifyAll() const;
private:
class Impl;
Impl* impl_;
};
class Synchronized
{
public:
Synchronized(const Monitor* monitor) : g(monitor->mutex()) { }
Synchronized(const Monitor& monitor) : g(monitor.mutex()) { }
private:
Guard g;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,219 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
namespace apache
{
namespace thrift
{
namespace concurrency
{
#ifndef THRIFT_NO_CONTENTION_PROFILING
/**
* Determines if the Thrift Mutex and ReadWriteMutex classes will attempt to
* profile their blocking acquire methods. If this value is set to non-zero,
* Thrift will attempt to invoke the callback once every profilingSampleRate
* times. However, as the sampling is not synchronized the rate is not
* guranateed, and could be subject to big bursts and swings. Please ensure
* your sampling callback is as performant as your application requires.
*
* The callback will get called with the wait time taken to lock the mutex in
* usec and a (void*) that uniquely identifies the Mutex (or ReadWriteMutex)
* being locked.
*
* The enableMutexProfiling() function is unsynchronized; calling this function
* while profiling is already enabled may result in race conditions. On
* architectures where a pointer assignment is atomic, this is safe but there
* is no guarantee threads will agree on a single callback within any
* particular time period.
*/
typedef void (*MutexWaitCallback)(const void* id, int64_t waitTimeMicros);
void enableMutexProfiling(int32_t profilingSampleRate,
MutexWaitCallback callback);
#endif
/**
* A simple mutex class
*
* @version $Id:$
*/
class Mutex
{
public:
typedef void (*Initializer)(void*);
Mutex(Initializer init = DEFAULT_INITIALIZER);
virtual ~Mutex() {}
virtual void lock() const;
virtual bool trylock() const;
virtual bool timedlock(int64_t milliseconds) const;
virtual void unlock() const;
void* getUnderlyingImpl() const;
static void DEFAULT_INITIALIZER(void*);
static void ADAPTIVE_INITIALIZER(void*);
static void RECURSIVE_INITIALIZER(void*);
private:
class impl;
boost::shared_ptr<impl> impl_;
};
class ReadWriteMutex
{
public:
ReadWriteMutex();
virtual ~ReadWriteMutex() {}
// these get the lock and block until it is done successfully
virtual void acquireRead() const;
virtual void acquireWrite() const;
// these attempt to get the lock, returning false immediately if they fail
virtual bool attemptRead() const;
virtual bool attemptWrite() const;
// this releases both read and write locks
virtual void release() const;
private:
class impl;
boost::shared_ptr<impl> impl_;
};
/**
* A ReadWriteMutex that guarantees writers will not be starved by readers:
* When a writer attempts to acquire the mutex, all new readers will be
* blocked from acquiring the mutex until the writer has acquired and
* released it. In some operating systems, this may already be guaranteed
* by a regular ReadWriteMutex.
*/
class NoStarveReadWriteMutex : public ReadWriteMutex
{
public:
NoStarveReadWriteMutex();
virtual void acquireRead() const;
virtual void acquireWrite() const;
private:
Mutex mutex_;
mutable volatile bool writerWaiting_;
};
class Guard : boost::noncopyable
{
public:
Guard(const Mutex& value, int64_t timeout = 0) : mutex_(&value)
{
if (timeout == 0)
{
value.lock();
}
else if (timeout < 0)
{
if (!value.trylock())
{
mutex_ = NULL;
}
}
else
{
if (!value.timedlock(timeout))
{
mutex_ = NULL;
}
}
}
~Guard()
{
if (mutex_)
{
mutex_->unlock();
}
}
operator bool() const
{
return (mutex_ != NULL);
}
private:
const Mutex* mutex_;
};
// Can be used as second argument to RWGuard to make code more readable
// as to whether we're doing acquireRead() or acquireWrite().
enum RWGuardType
{
RW_READ = 0,
RW_WRITE = 1
};
class RWGuard : boost::noncopyable
{
public:
RWGuard(const ReadWriteMutex& value, bool write = false)
: rw_mutex_(value)
{
if (write)
{
rw_mutex_.acquireWrite();
}
else
{
rw_mutex_.acquireRead();
}
}
RWGuard(const ReadWriteMutex& value, RWGuardType type)
: rw_mutex_(value)
{
if (type == RW_WRITE)
{
rw_mutex_.acquireWrite();
}
else
{
rw_mutex_.acquireRead();
}
}
~RWGuard()
{
rw_mutex_.release();
}
private:
const ReadWriteMutex& rw_mutex_;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,49 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/thrift-config.h>
#if USE_BOOST_THREAD
# include <thrift/concurrency/BoostThreadFactory.h>
#elif USE_STD_THREAD
# include <thrift/concurrency/StdThreadFactory.h>
#else
# include <thrift/concurrency/PosixThreadFactory.h>
#endif
namespace apache
{
namespace thrift
{
namespace concurrency
{
#ifdef USE_BOOST_THREAD
typedef BoostThreadFactory PlatformThreadFactory;
#elif USE_STD_THREAD
typedef StdThreadFactory PlatformThreadFactory;
#else
typedef PosixThreadFactory PlatformThreadFactory;
#endif
}
}
} // apache::thrift::concurrency

View File

@ -1,138 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* A thread factory to create posix threads
*
* @version $Id:$
*/
class PosixThreadFactory : public ThreadFactory
{
public:
/**
* POSIX Thread scheduler policies
*/
enum POLICY
{
OTHER,
FIFO,
ROUND_ROBIN
};
/**
* POSIX Thread scheduler relative priorities,
*
* Absolute priority is determined by scheduler policy and OS. This
* enumeration specifies relative priorities such that one can specify a
* priority withing a giving scheduler policy without knowing the absolute
* value of the priority.
*/
enum PRIORITY
{
LOWEST = 0,
LOWER = 1,
LOW = 2,
NORMAL = 3,
HIGH = 4,
HIGHER = 5,
HIGHEST = 6,
INCREMENT = 7,
DECREMENT = 8
};
/**
* Posix thread (pthread) factory. All threads created by a factory are reference-counted
* via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
* the Runnable tasks they host will be properly cleaned up once the last strong reference
* to both is given up.
*
* Threads are created with the specified policy, priority, stack-size and detachable-mode
* detached means the thread is free-running and will release all system resources the
* when it completes. A detachable thread is not joinable. The join method
* of a detachable thread will return immediately with no error.
*
* By default threads are not joinable.
*/
PosixThreadFactory(POLICY policy = ROUND_ROBIN, PRIORITY priority = NORMAL, int stackSize = 1, bool detached = true);
// From ThreadFactory;
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
// From ThreadFactory;
Thread::id_t getCurrentThreadId() const;
/**
* Gets stack size for created threads
*
* @return int size in megabytes
*/
virtual int getStackSize() const;
/**
* Sets stack size for created threads
*
* @param value size in megabytes
*/
virtual void setStackSize(int value);
/**
* Gets priority relative to current policy
*/
virtual PRIORITY getPriority() const;
/**
* Sets priority relative to current policy
*/
virtual void setPriority(PRIORITY priority);
/**
* Sets detached mode of threads
*/
virtual void setDetached(bool detached);
/**
* Gets current detached mode
*/
virtual bool isDetached() const;
private:
class Impl;
boost::shared_ptr<Impl> impl_;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,78 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* A thread factory to create std::threads.
*
* @version $Id:$
*/
class StdThreadFactory : public ThreadFactory
{
public:
/**
* Std thread factory. All threads created by a factory are reference-counted
* via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
* the Runnable tasks they host will be properly cleaned up once the last strong reference
* to both is given up.
*
* By default threads are not joinable.
*/
StdThreadFactory(bool detached = true);
// From ThreadFactory;
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
// From ThreadFactory;
Thread::id_t getCurrentThreadId() const;
/**
* Sets detached mode of threads
*/
virtual void setDetached(bool detached);
/**
* Gets current detached mode
*/
virtual bool isDetached() const;
private:
class Impl;
boost::shared_ptr<Impl> impl_;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,190 +0,0 @@
/*
* 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.
*/
#pragma once
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <thrift/thrift-config.h>
#if USE_BOOST_THREAD
# include <boost/thread.hpp>
#elif USE_STD_THREAD
# include <thread>
#else
# ifdef HAVE_PTHREAD_H
# include <pthread.h>
# endif
#endif
namespace apache
{
namespace thrift
{
namespace concurrency
{
class Thread;
/**
* Minimal runnable class. More or less analogous to java.lang.Runnable.
*
* @version $Id:$
*/
class Runnable
{
public:
virtual ~Runnable() {};
virtual void run() = 0;
/**
* Gets the thread object that is hosting this runnable object - can return
* an empty boost::shared pointer if no references remain on thet thread object
*/
virtual boost::shared_ptr<Thread> thread()
{
return thread_.lock();
}
/**
* Sets the thread that is executing this object. This is only meant for
* use by concrete implementations of Thread.
*/
virtual void thread(boost::shared_ptr<Thread> value)
{
thread_ = value;
}
private:
boost::weak_ptr<Thread> thread_;
};
/**
* Minimal thread class. Returned by thread factory bound to a Runnable object
* and ready to start execution. More or less analogous to java.lang.Thread
* (minus all the thread group, priority, mode and other baggage, since that
* is difficult to abstract across platforms and is left for platform-specific
* ThreadFactory implemtations to deal with
*
* @see apache::thrift::concurrency::ThreadFactory)
*/
class Thread
{
public:
#if USE_BOOST_THREAD
typedef boost::thread::id id_t;
static inline bool is_current(id_t t)
{
return t == boost::this_thread::get_id();
}
static inline id_t get_current()
{
return boost::this_thread::get_id();
}
#elif USE_STD_THREAD
typedef std::thread::id id_t;
static inline bool is_current(id_t t)
{
return t == std::this_thread::get_id();
}
static inline id_t get_current()
{
return std::this_thread::get_id();
}
#else
typedef pthread_t id_t;
static inline bool is_current(id_t t)
{
return pthread_equal(pthread_self(), t);
}
static inline id_t get_current()
{
return pthread_self();
}
#endif
virtual ~Thread() {};
/**
* Starts the thread. Does platform specific thread creation and
* configuration then invokes the run method of the Runnable object bound
* to this thread.
*/
virtual void start() = 0;
/**
* Join this thread. Current thread blocks until this target thread
* completes.
*/
virtual void join() = 0;
/**
* Gets the thread's platform-specific ID
*/
virtual id_t getId() = 0;
/**
* Gets the runnable object this thread is hosting
*/
virtual boost::shared_ptr<Runnable> runnable() const
{
return _runnable;
}
protected:
virtual void runnable(boost::shared_ptr<Runnable> value)
{
_runnable = value;
}
private:
boost::shared_ptr<Runnable> _runnable;
};
/**
* Factory to create platform-specific thread object and bind them to Runnable
* object for execution
*/
class ThreadFactory
{
public:
virtual ~ThreadFactory() {}
virtual boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const = 0;
/** Gets the current thread id or unknown_thread_id if the current thread is not a thrift thread */
static const Thread::id_t unknown_thread_id;
virtual Thread::id_t getCurrentThreadId() const = 0;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,209 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <thrift/cxxfunctional.h>
#include <sys/types.h>
#include <thrift/concurrency/Thread.h>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* Thread Pool Manager and related classes
*
* @version $Id:$
*/
class ThreadManager;
/**
* ThreadManager class
*
* This class manages a pool of threads. It uses a ThreadFactory to create
* threads. It never actually creates or destroys worker threads, rather
* It maintains statistics on number of idle threads, number of active threads,
* task backlog, and average wait and service times and informs the PoolPolicy
* object bound to instances of this manager of interesting transitions. It is
* then up the PoolPolicy object to decide if the thread pool size needs to be
* adjusted and call this object addWorker and removeWorker methods to make
* changes.
*
* This design allows different policy implementations to used this code to
* handle basic worker thread management and worker task execution and focus on
* policy issues. The simplest policy, StaticPolicy, does nothing other than
* create a fixed number of threads.
*/
class ThreadManager
{
protected:
ThreadManager() {}
public:
class Task;
typedef apache::thrift::stdcxx::function<void(boost::shared_ptr<Runnable>)> ExpireCallback;
virtual ~ThreadManager() {}
/**
* Starts the thread manager. Verifies all attributes have been properly
* initialized, then allocates necessary resources to begin operation
*/
virtual void start() = 0;
/**
* Stops the thread manager. Aborts all remaining unprocessed task, shuts
* down all created worker threads, and realeases all allocated resources.
* This method blocks for all worker threads to complete, thus it can
* potentially block forever if a worker thread is running a task that
* won't terminate.
*/
virtual void stop() = 0;
/**
* Joins the thread manager. This is the same as stop, except that it will
* block until all the workers have finished their work. At that point
* the ThreadManager will transition into the STOPPED state.
*/
virtual void join() = 0;
enum STATE
{
UNINITIALIZED,
STARTING,
STARTED,
JOINING,
STOPPING,
STOPPED
};
virtual STATE state() const = 0;
virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
virtual void threadFactory(boost::shared_ptr<ThreadFactory> value) = 0;
virtual void addWorker(size_t value = 1) = 0;
virtual void removeWorker(size_t value = 1) = 0;
/**
* Gets the current number of idle worker threads
*/
virtual size_t idleWorkerCount() const = 0;
/**
* Gets the current number of total worker threads
*/
virtual size_t workerCount() const = 0;
/**
* Gets the current number of pending tasks
*/
virtual size_t pendingTaskCount() const = 0;
/**
* Gets the current number of pending and executing tasks
*/
virtual size_t totalTaskCount() const = 0;
/**
* Gets the maximum pending task count. 0 indicates no maximum
*/
virtual size_t pendingTaskCountMax() const = 0;
/**
* Gets the number of tasks which have been expired without being run.
*/
virtual size_t expiredTaskCount() = 0;
/**
* Adds a task to be executed at some time in the future by a worker thread.
*
* This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
* is greater than or equalt to pendingTaskCountMax(). If this method is called in the
* context of a ThreadManager worker thread it will throw a
* TooManyPendingTasksException
*
* @param task The task to queue for execution
*
* @param timeout Time to wait in milliseconds to add a task when a pending-task-count
* is specified. Specific cases:
* timeout = 0 : Wait forever to queue task.
* timeout = -1 : Return immediately if pending task count exceeds specified max
* @param expiration when nonzero, the number of milliseconds the task is valid
* to be run; if exceeded, the task will be dropped off the queue and not run.
*
* @throws TooManyPendingTasksException Pending task count exceeds max pending task count
*/
virtual void add(boost::shared_ptr<Runnable>task,
int64_t timeout = 0LL,
int64_t expiration = 0LL) = 0;
/**
* Removes a pending task
*/
virtual void remove(boost::shared_ptr<Runnable> task) = 0;
/**
* Remove the next pending task which would be run.
*
* @return the task removed.
*/
virtual boost::shared_ptr<Runnable> removeNextPending() = 0;
/**
* Remove tasks from front of task queue that have expired.
*/
virtual void removeExpiredTasks() = 0;
/**
* Set a callback to be called when a task is expired and not run.
*
* @param expireCallback a function called with the shared_ptr<Runnable> for
* the expired task.
*/
virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
static boost::shared_ptr<ThreadManager> newThreadManager();
/**
* Creates a simple thread manager the uses count number of worker threads and has
* a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
* on pending tasks
*/
static boost::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4, size_t pendingTaskCountMax = 0);
class Task;
class Worker;
class Impl;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,137 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
#include <map>
#include <time.h>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* Timer Manager
*
* This class dispatches timer tasks when they fall due.
*
* @version $Id:$
*/
class TimerManager
{
public:
TimerManager();
virtual ~TimerManager();
virtual boost::shared_ptr<const ThreadFactory> threadFactory() const;
virtual void threadFactory(boost::shared_ptr<const ThreadFactory> value);
/**
* Starts the timer manager service
*
* @throws IllegalArgumentException Missing thread factory attribute
*/
virtual void start();
/**
* Stops the timer manager service
*/
virtual void stop();
virtual size_t taskCount() const ;
/**
* Adds a task to be executed at some time in the future by a worker thread.
*
* @param task The task to execute
* @param timeout Time in milliseconds to delay before executing task
*/
virtual void add(boost::shared_ptr<Runnable> task, int64_t timeout);
/**
* Adds a task to be executed at some time in the future by a worker thread.
*
* @param task The task to execute
* @param timeout Absolute time in the future to execute task.
*/
virtual void add(boost::shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC& timeout);
/**
* Adds a task to be executed at some time in the future by a worker thread.
*
* @param task The task to execute
* @param timeout Absolute time in the future to execute task.
*/
virtual void add(boost::shared_ptr<Runnable> task, const struct timeval& timeout);
/**
* Removes a pending task
*
* @throws NoSuchTaskException Specified task doesn't exist. It was either
* processed already or this call was made for a
* task that was never added to this timer
*
* @throws UncancellableTaskException Specified task is already being
* executed or has completed execution.
*/
virtual void remove(boost::shared_ptr<Runnable> task);
enum STATE
{
UNINITIALIZED,
STARTING,
STARTED,
STOPPING,
STOPPED
};
virtual STATE state() const;
private:
boost::shared_ptr<const ThreadFactory> threadFactory_;
class Task;
friend class Task;
std::multimap<int64_t, boost::shared_ptr<Task> > taskMap_;
size_t taskCount_;
Monitor monitor_;
STATE state_;
class Dispatcher;
friend class Dispatcher;
boost::shared_ptr<Dispatcher> dispatcher_;
boost::shared_ptr<Thread> dispatcherThread_;
typedef std::multimap<int64_t, boost::shared_ptr<TimerManager::Task> >::iterator task_iterator;
typedef std::pair<task_iterator, task_iterator> task_range;
};
}
}
} // apache::thrift::concurrency

View File

@ -1,175 +0,0 @@
/*
* 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.
*/
#pragma once
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <thrift/transport/PlatformSocket.h>
namespace apache
{
namespace thrift
{
namespace concurrency
{
/**
* Utility methods
*
* This class contains basic utility methods for converting time formats,
* and other common platform-dependent concurrency operations.
* It should not be included in API headers for other concurrency library
* headers, since it will, by definition, pull in all sorts of horrid
* platform dependent stuff. Rather it should be inluded directly in
* concurrency library implementation source.
*
* @version $Id:$
*/
class Util
{
static const int64_t NS_PER_S = 1000000000LL;
static const int64_t US_PER_S = 1000000LL;
static const int64_t MS_PER_S = 1000LL;
static const int64_t NS_PER_MS = NS_PER_S / MS_PER_S;
static const int64_t NS_PER_US = NS_PER_S / US_PER_S;
static const int64_t US_PER_MS = US_PER_S / MS_PER_S;
public:
/**
* Converts millisecond timestamp into a THRIFT_TIMESPEC struct
*
* @param struct THRIFT_TIMESPEC& result
* @param time or duration in milliseconds
*/
static void toTimespec(struct THRIFT_TIMESPEC& result, int64_t value)
{
result.tv_sec = value / MS_PER_S; // ms to s
result.tv_nsec = (value % MS_PER_S) * NS_PER_MS; // ms to ns
}
static void toTimeval(struct timeval& result, int64_t value)
{
result.tv_sec = static_cast<uint32_t>(value / MS_PER_S); // ms to s
result.tv_usec = static_cast<uint32_t>((value % MS_PER_S) * US_PER_MS); // ms to us
}
static void toTicks(int64_t& result, int64_t secs, int64_t oldTicks,
int64_t oldTicksPerSec, int64_t newTicksPerSec)
{
result = secs * newTicksPerSec;
result += oldTicks * newTicksPerSec / oldTicksPerSec;
int64_t oldPerNew = oldTicksPerSec / newTicksPerSec;
if (oldPerNew && ((oldTicks % oldPerNew) >= (oldPerNew / 2)))
{
++result;
}
}
/**
* Converts struct THRIFT_TIMESPEC to arbitrary-sized ticks since epoch
*/
static void toTicks(int64_t& result,
const struct THRIFT_TIMESPEC& value,
int64_t ticksPerSec)
{
return toTicks(result, value.tv_sec, value.tv_nsec, NS_PER_S, ticksPerSec);
}
/**
* Converts struct timeval to arbitrary-sized ticks since epoch
*/
static void toTicks(int64_t& result,
const struct timeval& value,
int64_t ticksPerSec)
{
return toTicks(result, value.tv_sec, value.tv_usec, US_PER_S, ticksPerSec);
}
/**
* Converts struct THRIFT_TIMESPEC to milliseconds
*/
static void toMilliseconds(int64_t& result,
const struct THRIFT_TIMESPEC& value)
{
return toTicks(result, value, MS_PER_S);
}
/**
* Converts struct timeval to milliseconds
*/
static void toMilliseconds(int64_t& result,
const struct timeval& value)
{
return toTicks(result, value, MS_PER_S);
}
/**
* Converts struct THRIFT_TIMESPEC to microseconds
*/
static void toUsec(int64_t& result, const struct THRIFT_TIMESPEC& value)
{
return toTicks(result, value, US_PER_S);
}
/**
* Converts struct timeval to microseconds
*/
static void toUsec(int64_t& result, const struct timeval& value)
{
return toTicks(result, value, US_PER_S);
}
/**
* Get current time as a number of arbitrary-size ticks from epoch
*/
static int64_t currentTimeTicks(int64_t ticksPerSec);
/**
* Get current time as milliseconds from epoch
*/
static int64_t currentTime()
{
return currentTimeTicks(MS_PER_S);
}
/**
* Get current time as micros from epoch
*/
static int64_t currentTimeUsec()
{
return currentTimeTicks(US_PER_S);
}
};
}
}
} // apache::thrift::concurrency

View File

@ -1,148 +0,0 @@
/*
* 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.
*/
#pragma once
/**
* Loads <functional> from the 'right' location, depending
* on compiler and whether or not it's using C++03 with TR1
* or C++11.
*/
/*
* MSVC 10 and 11 have the <functional> stuff at <functional>.
* In MSVC 10 all of the implementations live in std::tr1.
* In MSVC 11 all of the implementations live in std, with aliases
* in std::tr1 to point to the ones in std.
*/
#ifdef _WIN32
#define _THRIFT_USING_MICROSOFT_STDLIB 1
#endif
#ifdef __clang__
/* Clang has two options, depending on standard library:
* - no -stdlib or -stdlib=libstdc++ set; uses GNU libstdc++.
* <tr1/functional>
* - -stdlib=libc++; uses LLVM libc++.
* <functional>, no 'std::tr1'.
*
* The compiler itself doesn't define anything differently
* depending on the value of -stdlib, but the library headers
* will set different preprocessor options. In order to check,
* though, we have to pull in some library header.
*/
#include <utility>
/* With LLVM libc++, utility pulls in __config, which sets
_LIBCPP_VERSION. */
#if defined(_LIBCPP_VERSION)
#define _THRIFT_USING_CLANG_LIBCXX 1
/* With GNU libstdc++, utility pulls in bits/c++config.h,
which sets __GLIBCXX__. */
#elif defined(__GLIBCXX__)
#define _THRIFT_USING_GNU_LIBSTDCXX 1
/* No idea. */
#else
#error Unable to detect which C++ standard library is in use.
#endif
#elif __GNUC__
#define _THRIFT_USING_GNU_LIBSTDCXX 1
#endif
#if _THRIFT_USING_MICROSOFT_STDLIB
#include <functional>
namespace apache
{
namespace thrift
{
namespace stdcxx
{
using ::std::tr1::function;
using ::std::tr1::bind;
namespace placeholders
{
using ::std::tr1::placeholders::_1;
using ::std::tr1::placeholders::_2;
using ::std::tr1::placeholders::_3;
using ::std::tr1::placeholders::_4;
using ::std::tr1::placeholders::_5;
using ::std::tr1::placeholders::_6;
} // apache::thrift::stdcxx::placeholders
}
}
} // apache::thrift::stdcxx
#elif _THRIFT_USING_CLANG_LIBCXX
#include <functional>
namespace apache
{
namespace thrift
{
namespace stdcxx
{
using ::std::function;
using ::std::bind;
namespace placeholders
{
using ::std::placeholders::_1;
using ::std::placeholders::_2;
using ::std::placeholders::_3;
using ::std::placeholders::_4;
using ::std::placeholders::_5;
using ::std::placeholders::_6;
} // apache::thrift::stdcxx::placeholders
}
}
} // apache::thrift::stdcxx
#elif _THRIFT_USING_GNU_LIBSTDCXX
#include <tr1/functional>
namespace apache
{
namespace thrift
{
namespace stdcxx
{
using ::std::tr1::function;
using ::std::tr1::bind;
namespace placeholders
{
using ::std::tr1::placeholders::_1;
using ::std::tr1::placeholders::_2;
using ::std::tr1::placeholders::_3;
using ::std::tr1::placeholders::_4;
using ::std::tr1::placeholders::_5;
using ::std::tr1::placeholders::_6;
} // apache::thrift::stdcxx::placeholders
}
}
} // apache::thrift::stdcxx
#endif
// Alias for thrift c++ compatibility namespace
namespace tcxx = apache::thrift::stdcxx;

View File

@ -1,84 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#include <thrift/TProcessor.h>
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TBufferTransports.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace processor
{
/*
* Class for peeking at the raw data that is being processed by another processor
* and gives the derived class a chance to change behavior accordingly
*
*/
class PeekProcessor : public apache::thrift::TProcessor
{
public:
PeekProcessor();
virtual ~PeekProcessor();
// Input here: actualProcessor - the underlying processor
// protocolFactory - the protocol factory used to wrap the memory buffer
// transportFactory - this TPipedTransportFactory is used to wrap the source transport
// via a call to getPipedTransport
void initialize(boost::shared_ptr<apache::thrift::TProcessor> actualProcessor,
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
boost::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory);
boost::shared_ptr<apache::thrift::transport::TTransport> getPipedTransport(boost::shared_ptr<apache::thrift::transport::TTransport> in);
void setTargetTransport(boost::shared_ptr<apache::thrift::transport::TTransport> targetTransport);
virtual bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> in,
boost::shared_ptr<apache::thrift::protocol::TProtocol> out,
void* connectionContext);
// The following three functions can be overloaded by child classes to
// achieve desired peeking behavior
virtual void peekName(const std::string& fname);
virtual void peekBuffer(uint8_t* buffer, uint32_t size);
virtual void peek(boost::shared_ptr<apache::thrift::protocol::TProtocol> in,
apache::thrift::protocol::TType ftype,
int16_t fid);
virtual void peekEnd();
private:
boost::shared_ptr<apache::thrift::TProcessor> actualProcessor_;
boost::shared_ptr<apache::thrift::protocol::TProtocol> pipedProtocol_;
boost::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory_;
boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> memoryBuffer_;
boost::shared_ptr<apache::thrift::transport::TTransport> targetTransport_;
};
}
}
} // apache::thrift::processor

View File

@ -1,362 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <thrift/transport/TTransport.h>
#include <thrift/protocol/TProtocol.h>
#include <TProcessor.h>
namespace apache
{
namespace thrift
{
namespace processor
{
/*
* Class for keeping track of function call statistics and printing them if desired
*
*/
class StatsProcessor : public apache::thrift::TProcessor
{
public:
StatsProcessor(bool print, bool frequency)
: print_(print),
frequency_(frequency)
{}
virtual ~StatsProcessor() {};
virtual bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot,
boost::shared_ptr<apache::thrift::protocol::TProtocol> poprot,
void* serverContext)
{
piprot_ = piprot;
std::string fname;
apache::thrift::protocol::TMessageType mtype;
int32_t seqid;
piprot_->readMessageBegin(fname, mtype, seqid);
if (mtype != apache::thrift::protocol::T_CALL)
{
if (print_)
{
printf("Unknown message type\n");
}
throw apache::thrift::TException("Unexpected message type");
}
if (print_)
{
printf("%s (", fname.c_str());
}
if (frequency_)
{
if (frequency_map_.find(fname) != frequency_map_.end())
{
frequency_map_[fname]++;
}
else
{
frequency_map_[fname] = 1;
}
}
apache::thrift::protocol::TType ftype;
int16_t fid;
while (true)
{
piprot_->readFieldBegin(fname, ftype, fid);
if (ftype == apache::thrift::protocol::T_STOP)
{
break;
}
printAndPassToBuffer(ftype);
if (print_)
{
printf(", ");
}
}
if (print_)
{
printf("\b\b)\n");
}
return true;
}
const std::map<std::string, int64_t>& get_frequency_map()
{
return frequency_map_;
}
protected:
void printAndPassToBuffer(apache::thrift::protocol::TType ftype)
{
switch (ftype)
{
case apache::thrift::protocol::T_BOOL:
{
bool boolv;
piprot_->readBool(boolv);
if (print_)
{
printf("%d", boolv);
}
}
break;
case apache::thrift::protocol::T_BYTE:
{
int8_t bytev;
piprot_->readByte(bytev);
if (print_)
{
printf("%d", bytev);
}
}
break;
case apache::thrift::protocol::T_I16:
{
int16_t i16;
piprot_->readI16(i16);
if (print_)
{
printf("%d", i16);
}
}
break;
case apache::thrift::protocol::T_I32:
{
int32_t i32;
piprot_->readI32(i32);
if (print_)
{
printf("%d", i32);
}
}
break;
case apache::thrift::protocol::T_I64:
{
int64_t i64;
piprot_->readI64(i64);
if (print_)
{
printf("%ld", i64);
}
}
break;
case apache::thrift::protocol::T_DOUBLE:
{
double dub;
piprot_->readDouble(dub);
if (print_)
{
printf("%f", dub);
}
}
break;
case apache::thrift::protocol::T_STRING:
{
std::string str;
piprot_->readString(str);
if (print_)
{
printf("%s", str.c_str());
}
}
break;
case apache::thrift::protocol::T_STRUCT:
{
std::string name;
int16_t fid;
apache::thrift::protocol::TType ftype;
piprot_->readStructBegin(name);
if (print_)
{
printf("<");
}
while (true)
{
piprot_->readFieldBegin(name, ftype, fid);
if (ftype == apache::thrift::protocol::T_STOP)
{
break;
}
printAndPassToBuffer(ftype);
if (print_)
{
printf(",");
}
piprot_->readFieldEnd();
}
piprot_->readStructEnd();
if (print_)
{
printf("\b>");
}
}
break;
case apache::thrift::protocol::T_MAP:
{
apache::thrift::protocol::TType keyType;
apache::thrift::protocol::TType valType;
uint32_t i, size;
piprot_->readMapBegin(keyType, valType, size);
if (print_)
{
printf("{");
}
for (i = 0; i < size; i++)
{
printAndPassToBuffer(keyType);
if (print_)
{
printf("=>");
}
printAndPassToBuffer(valType);
if (print_)
{
printf(",");
}
}
piprot_->readMapEnd();
if (print_)
{
printf("\b}");
}
}
break;
case apache::thrift::protocol::T_SET:
{
apache::thrift::protocol::TType elemType;
uint32_t i, size;
piprot_->readSetBegin(elemType, size);
if (print_)
{
printf("{");
}
for (i = 0; i < size; i++)
{
printAndPassToBuffer(elemType);
if (print_)
{
printf(",");
}
}
piprot_->readSetEnd();
if (print_)
{
printf("\b}");
}
}
break;
case apache::thrift::protocol::T_LIST:
{
apache::thrift::protocol::TType elemType;
uint32_t i, size;
piprot_->readListBegin(elemType, size);
if (print_)
{
printf("[");
}
for (i = 0; i < size; i++)
{
printAndPassToBuffer(elemType);
if (print_)
{
printf(",");
}
}
piprot_->readListEnd();
if (print_)
{
printf("\b]");
}
}
break;
default:
break;
}
}
boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;
std::map<std::string, int64_t> frequency_map_;
bool print_;
bool frequency_;
};
}
}
} // apache::thrift::processor

View File

@ -1,219 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TProtocolDecorator.h>
#include <thrift/TApplicationException.h>
#include <thrift/TProcessor.h>
#include <boost/tokenizer.hpp>
namespace apache
{
namespace thrift
{
using boost::shared_ptr;
namespace protocol
{
/**
* To be able to work with any protocol, we needed
* to allow them to call readMessageBegin() and get a TMessage in exactly
* the standard format, without the service name prepended to TMessage.name.
*/
class StoredMessageProtocol : public TProtocolDecorator
{
public:
StoredMessageProtocol( shared_ptr<protocol::TProtocol> _protocol,
const std::string& _name, const TMessageType _type,
const int32_t _seqid) :
TProtocolDecorator(_protocol),
name(_name),
type(_type),
seqid(_seqid)
{
}
uint32_t readMessageBegin_virt(std::string& _name, TMessageType& _type, int32_t& _seqid)
{
_name = name;
_type = type;
_seqid = seqid;
return 0; // (Normal TProtocol read functions return number of bytes read)
}
std::string name;
TMessageType type;
int32_t seqid;
};
} //namespace protocol
/**
* <code>TMultiplexedProcessor</code> is a <code>TProcessor</code> allowing
* a single <code>TServer</code> to provide multiple services.
*
* <p>To do so, you instantiate the processor and then register additional
* processors with it, as shown in the following example:</p>
*
* <blockquote><code>
* shared_ptr<TMultiplexedProcessor> processor(new TMultiplexedProcessor());
*
* processor->registerProcessor(
* "Calculator",
* shared_ptr<TProcessor>( new CalculatorProcessor(
* shared_ptr<CalculatorHandler>( new CalculatorHandler()))));
*
* processor->registerProcessor(
* "WeatherReport",
* shared_ptr<TProcessor>( new WeatherReportProcessor(
* shared_ptr<WeatherReportHandler>( new WeatherReportHandler()))));
*
* shared_ptr<TServerTransport> transport(new TServerSocket(9090));
* TSimpleServer server(processor, transport);
*
* server.serve();
* </code></blockquote>
*/
class TMultiplexedProcessor : public TProcessor
{
public:
typedef std::map< std::string, shared_ptr<TProcessor> > services_t;
/**
* 'Register' a service with this <code>TMultiplexedProcessor</code>. This
* allows us to broker requests to individual services by using the service
* name to select them at request time.
*
* \param [in] serviceName Name of a service, has to be identical to the name
* declared in the Thrift IDL, e.g. "WeatherReport".
* \param [in] processor Implementation of a service, ususally referred to
* as "handlers", e.g. WeatherReportHandler,
* implementing WeatherReportIf interface.
*/
void registerProcessor( const std::string& serviceName,
shared_ptr<TProcessor> processor )
{
services[serviceName] = processor;
}
/**
* This implementation of <code>process</code> performs the following steps:
*
* <ol>
* <li>Read the beginning of the message.</li>
* <li>Extract the service name from the message.</li>
* <li>Using the service name to locate the appropriate processor.</li>
* <li>Dispatch to the processor, with a decorated instance of TProtocol
* that allows readMessageBegin() to return the original TMessage.</li>
* </ol>
*
* \throws TException If the message type is not T_CALL or T_ONEWAY, if
* the service name was not found in the message, or if the service
* name was not found in the service map.
*/
bool process( shared_ptr<protocol::TProtocol> in,
shared_ptr<protocol::TProtocol> out,
void* connectionContext)
{
std::string name;
protocol::TMessageType type;
int32_t seqid;
// Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
// message header. This pulls the message "off the wire", which we'll
// deal with at the end of this method.
in->readMessageBegin(name, type, seqid);
if ( type != protocol::T_CALL && type != protocol::T_ONEWAY )
{
// Unexpected message type.
in->skip(::apache::thrift::protocol::T_STRUCT);
in->readMessageEnd();
in->getTransport()->readEnd();
const std::string msg("TMultiplexedProcessor: Unexpected message type");
::apache::thrift::TApplicationException x(
::apache::thrift::TApplicationException::PROTOCOL_ERROR,
msg);
out->writeMessageBegin(name, ::apache::thrift::protocol::T_EXCEPTION, seqid);
x.write(out.get());
out->writeMessageEnd();
out->getTransport()->writeEnd();
out->getTransport()->flush();
throw TException(msg);
}
// Extract the service name
boost::tokenizer<boost::char_separator<char> > tok( name, boost::char_separator<char>(":") );
std::vector<std::string> tokens;
std::copy( tok.begin(), tok.end(), std::back_inserter(tokens) );
// A valid message should consist of two tokens: the service
// name and the name of the method to call.
if ( tokens.size() == 2 )
{
// Search for a processor associated with this service name.
services_t::iterator it = services.find(tokens[0]);
if ( it != services.end() )
{
shared_ptr<TProcessor> processor = it->second;
// Let the processor registered for this service name
// process the message.
return processor->process(
shared_ptr<protocol::TProtocol>(
new protocol::StoredMessageProtocol( in, tokens[1], type, seqid ) ),
out, connectionContext );
}
else
{
// Unknown service.
in->skip(::apache::thrift::protocol::T_STRUCT);
in->readMessageEnd();
in->getTransport()->readEnd();
std::string msg("TMultiplexedProcessor: Unknown service: ");
msg += tokens[0];
::apache::thrift::TApplicationException x(
::apache::thrift::TApplicationException::PROTOCOL_ERROR,
msg);
out->writeMessageBegin(name, ::apache::thrift::protocol::T_EXCEPTION, seqid);
x.write(out.get());
out->writeMessageEnd();
out->getTransport()->writeEnd();
out->getTransport()->flush();
msg += ". Did you forget to call registerProcessor()?";
throw TException(msg);
}
}
return false;
}
private:
/** Map of service processor objects, indexed by service names. */
services_t services;
};
}
}

View File

@ -1,47 +0,0 @@
/*
* 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.
*/
#pragma once
#include <stdint.h>
#include <string>
namespace apache
{
namespace thrift
{
namespace protocol
{
// in must be at least len bytes
// len must be 1, 2, or 3
// buf must be a buffer of at least 4 bytes and may not overlap in
// the data is not padded with '='; the caller can do this if desired
void base64_encode(const uint8_t* in, uint32_t len, uint8_t* buf);
// buf must be a buffer of at least 4 bytes and contain base64 encoded values
// buf will be changed to contain output bytes
// len is number of bytes to consume from input (must be 2, 3, or 4)
// no '=' padding should be included in the input
void base64_decode(uint8_t* buf, uint32_t len);
}
}
} // apache::thrift::protocol

View File

@ -1,302 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TProtocol.h>
#include <thrift/protocol/TVirtualProtocol.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace protocol
{
/**
* The default binary protocol for thrift. Writes all data in a very basic
* binary format, essentially just spitting out the raw bytes.
*
*/
template <class Transport_>
class TBinaryProtocolT
: public TVirtualProtocol< TBinaryProtocolT<Transport_> >
{
protected:
static const int32_t VERSION_MASK = ((int32_t)0xffff0000);
static const int32_t VERSION_1 = ((int32_t)0x80010000);
// VERSION_2 (0x80020000) is taken by TDenseProtocol.
public:
TBinaryProtocolT(boost::shared_ptr<Transport_> trans) :
TVirtualProtocol< TBinaryProtocolT<Transport_> >(trans),
trans_(trans.get()),
string_limit_(0),
container_limit_(0),
strict_read_(false),
strict_write_(true),
string_buf_(NULL),
string_buf_size_(0) {}
TBinaryProtocolT(boost::shared_ptr<Transport_> trans,
int32_t string_limit,
int32_t container_limit,
bool strict_read,
bool strict_write) :
TVirtualProtocol< TBinaryProtocolT<Transport_> >(trans),
trans_(trans.get()),
string_limit_(string_limit),
container_limit_(container_limit),
strict_read_(strict_read),
strict_write_(strict_write),
string_buf_(NULL),
string_buf_size_(0) {}
~TBinaryProtocolT()
{
if (string_buf_ != NULL)
{
std::free(string_buf_);
string_buf_size_ = 0;
}
}
void setStringSizeLimit(int32_t string_limit)
{
string_limit_ = string_limit;
}
void setContainerSizeLimit(int32_t container_limit)
{
container_limit_ = container_limit;
}
void setStrict(bool strict_read, bool strict_write)
{
strict_read_ = strict_read;
strict_write_ = strict_write;
}
/**
* Writing functions.
*/
/*ol*/ uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid);
/*ol*/ uint32_t writeMessageEnd();
inline uint32_t writeStructBegin(const char* name);
inline uint32_t writeStructEnd();
inline uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId);
inline uint32_t writeFieldEnd();
inline uint32_t writeFieldStop();
inline uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size);
inline uint32_t writeMapEnd();
inline uint32_t writeListBegin(const TType elemType, const uint32_t size);
inline uint32_t writeListEnd();
inline uint32_t writeSetBegin(const TType elemType, const uint32_t size);
inline uint32_t writeSetEnd();
inline uint32_t writeBool(const bool value);
inline uint32_t writeByte(const int8_t byte);
inline uint32_t writeI16(const int16_t i16);
inline uint32_t writeI32(const int32_t i32);
inline uint32_t writeI64(const int64_t i64);
inline uint32_t writeDouble(const double dub);
template <typename StrType>
inline uint32_t writeString(const StrType& str);
inline uint32_t writeBinary(const std::string& str);
/**
* Reading functions
*/
/*ol*/ uint32_t readMessageBegin(std::string& name,
TMessageType& messageType,
int32_t& seqid);
/*ol*/ uint32_t readMessageEnd();
inline uint32_t readStructBegin(std::string& name);
inline uint32_t readStructEnd();
inline uint32_t readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId);
inline uint32_t readFieldEnd();
inline uint32_t readMapBegin(TType& keyType,
TType& valType,
uint32_t& size);
inline uint32_t readMapEnd();
inline uint32_t readListBegin(TType& elemType, uint32_t& size);
inline uint32_t readListEnd();
inline uint32_t readSetBegin(TType& elemType, uint32_t& size);
inline uint32_t readSetEnd();
inline uint32_t readBool(bool& value);
// Provide the default readBool() implementation for std::vector<bool>
using TVirtualProtocol< TBinaryProtocolT<Transport_> >::readBool;
inline uint32_t readByte(int8_t& byte);
inline uint32_t readI16(int16_t& i16);
inline uint32_t readI32(int32_t& i32);
inline uint32_t readI64(int64_t& i64);
inline uint32_t readDouble(double& dub);
template<typename StrType>
inline uint32_t readString(StrType& str);
inline uint32_t readBinary(std::string& str);
protected:
template<typename StrType>
uint32_t readStringBody(StrType& str, int32_t sz);
Transport_* trans_;
int32_t string_limit_;
int32_t container_limit_;
// Enforce presence of version identifier
bool strict_read_;
bool strict_write_;
// Buffer for reading strings, save for the lifetime of the protocol to
// avoid memory churn allocating memory on every string read
uint8_t* string_buf_;
int32_t string_buf_size_;
};
typedef TBinaryProtocolT<TTransport> TBinaryProtocol;
/**
* Constructs binary protocol handlers
*/
template <class Transport_>
class TBinaryProtocolFactoryT : public TProtocolFactory
{
public:
TBinaryProtocolFactoryT() :
string_limit_(0),
container_limit_(0),
strict_read_(false),
strict_write_(true) {}
TBinaryProtocolFactoryT(int32_t string_limit, int32_t container_limit,
bool strict_read, bool strict_write) :
string_limit_(string_limit),
container_limit_(container_limit),
strict_read_(strict_read),
strict_write_(strict_write) {}
virtual ~TBinaryProtocolFactoryT() {}
void setStringSizeLimit(int32_t string_limit)
{
string_limit_ = string_limit;
}
void setContainerSizeLimit(int32_t container_limit)
{
container_limit_ = container_limit;
}
void setStrict(bool strict_read, bool strict_write)
{
strict_read_ = strict_read;
strict_write_ = strict_write;
}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans)
{
boost::shared_ptr<Transport_> specific_trans =
boost::dynamic_pointer_cast<Transport_>(trans);
TProtocol* prot;
if (specific_trans)
{
prot = new TBinaryProtocolT<Transport_>(specific_trans, string_limit_,
container_limit_, strict_read_,
strict_write_);
}
else
{
prot = new TBinaryProtocol(trans, string_limit_, container_limit_,
strict_read_, strict_write_);
}
return boost::shared_ptr<TProtocol>(prot);
}
private:
int32_t string_limit_;
int32_t container_limit_;
bool strict_read_;
bool strict_write_;
};
typedef TBinaryProtocolFactoryT<TTransport> TBinaryProtocolFactory;
}
}
} // apache::thrift::protocol
#include <thrift/protocol/TBinaryProtocol.tcc>

View File

@ -1,465 +0,0 @@
/*
* 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_TBINARYPROTOCOL_TCC_
#define _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ 1
#include <thrift/protocol/TBinaryProtocol.h>
#include <limits>
namespace apache { namespace thrift { namespace protocol {
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid) {
if (this->strict_write_) {
int32_t version = (VERSION_1) | ((int32_t)messageType);
uint32_t wsize = 0;
wsize += writeI32(version);
wsize += writeString(name);
wsize += writeI32(seqid);
return wsize;
} else {
uint32_t wsize = 0;
wsize += writeString(name);
wsize += writeByte((int8_t)messageType);
wsize += writeI32(seqid);
return wsize;
}
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeMessageEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeStructBegin(const char* name) {
(void) name;
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeStructEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId) {
(void) name;
uint32_t wsize = 0;
wsize += writeByte((int8_t)fieldType);
wsize += writeI16(fieldId);
return wsize;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeFieldEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeFieldStop() {
return
writeByte((int8_t)T_STOP);
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size) {
uint32_t wsize = 0;
wsize += writeByte((int8_t)keyType);
wsize += writeByte((int8_t)valType);
wsize += writeI32((int32_t)size);
return wsize;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeMapEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeListBegin(const TType elemType,
const uint32_t size) {
uint32_t wsize = 0;
wsize += writeByte((int8_t) elemType);
wsize += writeI32((int32_t)size);
return wsize;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeListEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeSetBegin(const TType elemType,
const uint32_t size) {
uint32_t wsize = 0;
wsize += writeByte((int8_t)elemType);
wsize += writeI32((int32_t)size);
return wsize;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeSetEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeBool(const bool value) {
uint8_t tmp = value ? 1 : 0;
this->trans_->write(&tmp, 1);
return 1;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeByte(const int8_t byte) {
this->trans_->write((uint8_t*)&byte, 1);
return 1;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeI16(const int16_t i16) {
int16_t net = (int16_t)htons(i16);
this->trans_->write((uint8_t*)&net, 2);
return 2;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeI32(const int32_t i32) {
int32_t net = (int32_t)htonl(i32);
this->trans_->write((uint8_t*)&net, 4);
return 4;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeI64(const int64_t i64) {
int64_t net = (int64_t)htonll(i64);
this->trans_->write((uint8_t*)&net, 8);
return 8;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) {
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
uint64_t bits = bitwise_cast<uint64_t>(dub);
bits = htonll(bits);
this->trans_->write((uint8_t*)&bits, 8);
return 8;
}
template <class Transport_>
template<typename StrType>
uint32_t TBinaryProtocolT<Transport_>::writeString(const StrType& str) {
if(str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)()))
throw TProtocolException(TProtocolException::SIZE_LIMIT);
uint32_t size = static_cast<uint32_t>(str.size());
uint32_t result = writeI32((int32_t)size);
if (size > 0) {
this->trans_->write((uint8_t*)str.data(), size);
}
return result + size;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeBinary(const std::string& str) {
return TBinaryProtocolT<Transport_>::writeString(str);
}
/**
* Reading functions
*/
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readMessageBegin(std::string& name,
TMessageType& messageType,
int32_t& seqid) {
uint32_t result = 0;
int32_t sz;
result += readI32(sz);
if (sz < 0) {
// Check for correct version number
int32_t version = sz & VERSION_MASK;
if (version != VERSION_1) {
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
}
messageType = (TMessageType)(sz & 0x000000ff);
result += readString(name);
result += readI32(seqid);
} else {
if (this->strict_read_) {
throw TProtocolException(TProtocolException::BAD_VERSION, "No version identifier... old protocol client in strict mode?");
} else {
// Handle pre-versioned input
int8_t type;
result += readStringBody(name, sz);
result += readByte(type);
messageType = (TMessageType)type;
result += readI32(seqid);
}
}
return result;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readMessageEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readStructBegin(std::string& name) {
name = "";
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readStructEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId) {
(void) name;
uint32_t result = 0;
int8_t type;
result += readByte(type);
fieldType = (TType)type;
if (fieldType == T_STOP) {
fieldId = 0;
return result;
}
result += readI16(fieldId);
return result;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readFieldEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readMapBegin(TType& keyType,
TType& valType,
uint32_t& size) {
int8_t k, v;
uint32_t result = 0;
int32_t sizei;
result += readByte(k);
keyType = (TType)k;
result += readByte(v);
valType = (TType)v;
result += readI32(sizei);
if (sizei < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
} else if (this->container_limit_ && sizei > this->container_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
size = (uint32_t)sizei;
return result;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readMapEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readListBegin(TType& elemType,
uint32_t& size) {
int8_t e;
uint32_t result = 0;
int32_t sizei;
result += readByte(e);
elemType = (TType)e;
result += readI32(sizei);
if (sizei < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
} else if (this->container_limit_ && sizei > this->container_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
size = (uint32_t)sizei;
return result;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readListEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readSetBegin(TType& elemType,
uint32_t& size) {
int8_t e;
uint32_t result = 0;
int32_t sizei;
result += readByte(e);
elemType = (TType)e;
result += readI32(sizei);
if (sizei < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
} else if (this->container_limit_ && sizei > this->container_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
size = (uint32_t)sizei;
return result;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readSetEnd() {
return 0;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readBool(bool& value) {
uint8_t b[1];
this->trans_->readAll(b, 1);
value = *(int8_t*)b != 0;
return 1;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readByte(int8_t& byte) {
uint8_t b[1];
this->trans_->readAll(b, 1);
byte = *(int8_t*)b;
return 1;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readI16(int16_t& i16) {
union bytes {
uint8_t b[2];
int16_t all;
} theBytes;
this->trans_->readAll(theBytes.b, 2);
i16 = (int16_t)ntohs(theBytes.all);
return 2;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readI32(int32_t& i32) {
union bytes {
uint8_t b[4];
int32_t all;
} theBytes;
this->trans_->readAll(theBytes.b, 4);
i32 = (int32_t)ntohl(theBytes.all);
return 4;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readI64(int64_t& i64) {
union bytes {
uint8_t b[8];
int64_t all;
} theBytes;
this->trans_->readAll(theBytes.b, 8);
i64 = (int64_t)ntohll(theBytes.all);
return 8;
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readDouble(double& dub) {
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
union bytes {
uint8_t b[8];
uint64_t all;
} theBytes;
this->trans_->readAll(theBytes.b, 8);
theBytes.all = ntohll(theBytes.all);
dub = bitwise_cast<double>(theBytes.all);
return 8;
}
template <class Transport_>
template<typename StrType>
uint32_t TBinaryProtocolT<Transport_>::readString(StrType& str) {
uint32_t result;
int32_t size;
result = readI32(size);
return result + readStringBody(str, size);
}
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::readBinary(std::string& str) {
return TBinaryProtocolT<Transport_>::readString(str);
}
template <class Transport_>
template<typename StrType>
uint32_t TBinaryProtocolT<Transport_>::readStringBody(StrType& str,
int32_t size) {
uint32_t result = 0;
// Catch error cases
if (size < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
}
if (this->string_limit_ > 0 && size > this->string_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
// Catch empty string case
if (size == 0) {
str.clear();
return result;
}
// Try to borrow first
const uint8_t* borrow_buf;
uint32_t got = size;
if ((borrow_buf = this->trans_->borrow(NULL, &got))) {
str.assign((const char*)borrow_buf, size);
this->trans_->consume(size);
return size;
}
// Use the heap here to prevent stack overflow for v. large strings
if (size > this->string_buf_size_ || this->string_buf_ == NULL) {
void* new_string_buf = std::realloc(this->string_buf_, (uint32_t)size);
if (new_string_buf == NULL) {
throw std::bad_alloc();
}
this->string_buf_ = (uint8_t*)new_string_buf;
this->string_buf_size_ = size;
}
this->trans_->readAll(this->string_buf_, size);
str.assign((char*)this->string_buf_, size);
return (uint32_t)size;
}
}}} // apache::thrift::protocol
#endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_

View File

@ -1,338 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TVirtualProtocol.h>
#include <stack>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace protocol
{
/**
* C++ Implementation of the Compact Protocol as described in THRIFT-110
*/
template <class Transport_>
class TCompactProtocolT
: public TVirtualProtocol< TCompactProtocolT<Transport_> >
{
protected:
static const int8_t PROTOCOL_ID = (int8_t)0x82u;
static const int8_t VERSION_N = 1;
static const int8_t VERSION_MASK = 0x1f; // 0001 1111
static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000
static const int32_t TYPE_SHIFT_AMOUNT = 5;
Transport_* trans_;
/**
* (Writing) If we encounter a boolean field begin, save the TField here
* so it can have the value incorporated.
*/
struct
{
const char* name;
TType fieldType;
int16_t fieldId;
} booleanField_;
/**
* (Reading) If we read a field header, and it's a boolean field, save
* the boolean value here so that readBool can use it.
*/
struct
{
bool hasBoolValue;
bool boolValue;
} boolValue_;
/**
* Used to keep track of the last field for the current and previous structs,
* so we can do the delta stuff.
*/
std::stack<int16_t> lastField_;
int16_t lastFieldId_;
public:
TCompactProtocolT(boost::shared_ptr<Transport_> trans) :
TVirtualProtocol< TCompactProtocolT<Transport_> >(trans),
trans_(trans.get()),
lastFieldId_(0),
string_limit_(0),
string_buf_(NULL),
string_buf_size_(0),
container_limit_(0)
{
booleanField_.name = NULL;
boolValue_.hasBoolValue = false;
}
TCompactProtocolT(boost::shared_ptr<Transport_> trans,
int32_t string_limit,
int32_t container_limit) :
TVirtualProtocol< TCompactProtocolT<Transport_> >(trans),
trans_(trans.get()),
lastFieldId_(0),
string_limit_(string_limit),
string_buf_(NULL),
string_buf_size_(0),
container_limit_(container_limit)
{
booleanField_.name = NULL;
boolValue_.hasBoolValue = false;
}
~TCompactProtocolT()
{
free(string_buf_);
}
/**
* Writing functions
*/
virtual uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid);
uint32_t writeStructBegin(const char* name);
uint32_t writeStructEnd();
uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId);
uint32_t writeFieldStop();
uint32_t writeListBegin(const TType elemType,
const uint32_t size);
uint32_t writeSetBegin(const TType elemType,
const uint32_t size);
virtual uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size);
uint32_t writeBool(const bool value);
uint32_t writeByte(const int8_t byte);
uint32_t writeI16(const int16_t i16);
uint32_t writeI32(const int32_t i32);
uint32_t writeI64(const int64_t i64);
uint32_t writeDouble(const double dub);
uint32_t writeString(const std::string& str);
uint32_t writeBinary(const std::string& str);
/**
* These methods are called by structs, but don't actually have any wired
* output or purpose
*/
virtual uint32_t writeMessageEnd()
{
return 0;
}
uint32_t writeMapEnd()
{
return 0;
}
uint32_t writeListEnd()
{
return 0;
}
uint32_t writeSetEnd()
{
return 0;
}
uint32_t writeFieldEnd()
{
return 0;
}
protected:
int32_t writeFieldBeginInternal(const char* name,
const TType fieldType,
const int16_t fieldId,
int8_t typeOverride);
uint32_t writeCollectionBegin(const TType elemType, int32_t size);
uint32_t writeVarint32(uint32_t n);
uint32_t writeVarint64(uint64_t n);
uint64_t i64ToZigzag(const int64_t l);
uint32_t i32ToZigzag(const int32_t n);
inline int8_t getCompactType(const TType ttype);
public:
uint32_t readMessageBegin(std::string& name,
TMessageType& messageType,
int32_t& seqid);
uint32_t readStructBegin(std::string& name);
uint32_t readStructEnd();
uint32_t readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId);
uint32_t readMapBegin(TType& keyType,
TType& valType,
uint32_t& size);
uint32_t readListBegin(TType& elemType,
uint32_t& size);
uint32_t readSetBegin(TType& elemType,
uint32_t& size);
uint32_t readBool(bool& value);
// Provide the default readBool() implementation for std::vector<bool>
using TVirtualProtocol< TCompactProtocolT<Transport_> >::readBool;
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);
/*
*These methods are here for the struct to call, but don't have any wire
* encoding.
*/
uint32_t readMessageEnd()
{
return 0;
}
uint32_t readFieldEnd()
{
return 0;
}
uint32_t readMapEnd()
{
return 0;
}
uint32_t readListEnd()
{
return 0;
}
uint32_t readSetEnd()
{
return 0;
}
protected:
uint32_t readVarint32(int32_t& i32);
uint32_t readVarint64(int64_t& i64);
int32_t zigzagToI32(uint32_t n);
int64_t zigzagToI64(uint64_t n);
TType getTType(int8_t type);
// Buffer for reading strings, save for the lifetime of the protocol to
// avoid memory churn allocating memory on every string read
int32_t string_limit_;
uint8_t* string_buf_;
int32_t string_buf_size_;
int32_t container_limit_;
};
typedef TCompactProtocolT<TTransport> TCompactProtocol;
/**
* Constructs compact protocol handlers
*/
template <class Transport_>
class TCompactProtocolFactoryT : public TProtocolFactory
{
public:
TCompactProtocolFactoryT() :
string_limit_(0),
container_limit_(0) {}
TCompactProtocolFactoryT(int32_t string_limit, int32_t container_limit) :
string_limit_(string_limit),
container_limit_(container_limit) {}
virtual ~TCompactProtocolFactoryT() {}
void setStringSizeLimit(int32_t string_limit)
{
string_limit_ = string_limit;
}
void setContainerSizeLimit(int32_t container_limit)
{
container_limit_ = container_limit;
}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans)
{
boost::shared_ptr<Transport_> specific_trans =
boost::dynamic_pointer_cast<Transport_>(trans);
TProtocol* prot;
if (specific_trans)
{
prot = new TCompactProtocolT<Transport_>(specific_trans, string_limit_,
container_limit_);
}
else
{
prot = new TCompactProtocol(trans, string_limit_, container_limit_);
}
return boost::shared_ptr<TProtocol>(prot);
}
private:
int32_t string_limit_;
int32_t container_limit_;
};
typedef TCompactProtocolFactoryT<TTransport> TCompactProtocolFactory;
}
}
} // apache::thrift::protocol
#include <thrift/protocol/TCompactProtocol.tcc>

View File

@ -1,818 +0,0 @@
/*
* 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_TCOMPACTPROTOCOL_TCC_
#define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_ 1
#include <limits>
/*
* TCompactProtocol::i*ToZigzag depend on the fact that the right shift
* operator on a signed integer is an arithmetic (sign-extending) shift.
* If this is not the case, the current implementation will not work.
* If anyone encounters this error, we can try to figure out the best
* way to implement an arithmetic right shift on their platform.
*/
#if !defined(SIGNED_RIGHT_SHIFT_IS) || !defined(ARITHMETIC_RIGHT_SHIFT)
# error "Unable to determine the behavior of a signed right shift"
#endif
#if SIGNED_RIGHT_SHIFT_IS != ARITHMETIC_RIGHT_SHIFT
# error "TCompactProtocol currently only works if a signed right shift is arithmetic"
#endif
#ifdef __GNUC__
#define UNLIKELY(val) (__builtin_expect((val), 0))
#else
#define UNLIKELY(val) (val)
#endif
namespace apache { namespace thrift { namespace protocol {
namespace detail { namespace compact {
enum Types {
CT_STOP = 0x00,
CT_BOOLEAN_TRUE = 0x01,
CT_BOOLEAN_FALSE = 0x02,
CT_BYTE = 0x03,
CT_I16 = 0x04,
CT_I32 = 0x05,
CT_I64 = 0x06,
CT_DOUBLE = 0x07,
CT_BINARY = 0x08,
CT_LIST = 0x09,
CT_SET = 0x0A,
CT_MAP = 0x0B,
CT_STRUCT = 0x0C
};
const int8_t TTypeToCType[16] = {
CT_STOP, // T_STOP
0, // unused
CT_BOOLEAN_TRUE, // T_BOOL
CT_BYTE, // T_BYTE
CT_DOUBLE, // T_DOUBLE
0, // unused
CT_I16, // T_I16
0, // unused
CT_I32, // T_I32
0, // unused
CT_I64, // T_I64
CT_BINARY, // T_STRING
CT_STRUCT, // T_STRUCT
CT_MAP, // T_MAP
CT_SET, // T_SET
CT_LIST, // T_LIST
};
}} // end detail::compact namespace
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeMessageBegin(
const std::string& name,
const TMessageType messageType,
const int32_t seqid) {
uint32_t wsize = 0;
wsize += writeByte(PROTOCOL_ID);
wsize += writeByte((VERSION_N & VERSION_MASK) | (((int32_t)messageType << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
wsize += writeVarint32(seqid);
wsize += writeString(name);
return wsize;
}
/**
* Write a field header containing the field id and field type. If the
* difference between the current field id and the last one is small (< 15),
* then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
* field id will follow the type header as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId) {
if (fieldType == T_BOOL) {
booleanField_.name = name;
booleanField_.fieldType = fieldType;
booleanField_.fieldId = fieldId;
} else {
return writeFieldBeginInternal(name, fieldType, fieldId, -1);
}
return 0;
}
/**
* Write the STOP symbol so we know there are no more fields in this struct.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeFieldStop() {
return writeByte(T_STOP);
}
/**
* Write a struct begin. This doesn't actually put anything on the wire. We
* use it as an opportunity to put special placeholder markers on the field
* stack so we can get the field id deltas correct.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeStructBegin(const char* name) {
(void) name;
lastField_.push(lastFieldId_);
lastFieldId_ = 0;
return 0;
}
/**
* Write a struct end. This doesn't actually put anything on the wire. We use
* this as an opportunity to pop the last field from the current struct off
* of the field stack.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeStructEnd() {
lastFieldId_ = lastField_.top();
lastField_.pop();
return 0;
}
/**
* Write a List header.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeListBegin(const TType elemType,
const uint32_t size) {
return writeCollectionBegin(elemType, size);
}
/**
* Write a set header.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeSetBegin(const TType elemType,
const uint32_t size) {
return writeCollectionBegin(elemType, size);
}
/**
* Write a map header. If the map is empty, omit the key and value type
* headers, as we don't need any additional information to skip it.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size) {
uint32_t wsize = 0;
if (size == 0) {
wsize += writeByte(0);
} else {
wsize += writeVarint32(size);
wsize += writeByte(getCompactType(keyType) << 4 | getCompactType(valType));
}
return wsize;
}
/**
* Write a boolean value. Potentially, this could be a boolean field, in
* which case the field header info isn't written yet. If so, decide what the
* right type header is for the value and then write the field header.
* Otherwise, write a single byte.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeBool(const bool value) {
uint32_t wsize = 0;
if (booleanField_.name != NULL) {
// we haven't written the field header yet
wsize
+= writeFieldBeginInternal(booleanField_.name,
booleanField_.fieldType,
booleanField_.fieldId,
static_cast<int8_t>(value
? detail::compact::CT_BOOLEAN_TRUE
: detail::compact::CT_BOOLEAN_FALSE));
booleanField_.name = NULL;
} else {
// we're not part of a field, so just write the value
wsize
+= writeByte(static_cast<int8_t>(value
? detail::compact::CT_BOOLEAN_TRUE
: detail::compact::CT_BOOLEAN_FALSE));
}
return wsize;
}
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeByte(const int8_t byte) {
trans_->write((uint8_t*)&byte, 1);
return 1;
}
/**
* Write an i16 as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeI16(const int16_t i16) {
return writeVarint32(i32ToZigzag(i16));
}
/**
* Write an i32 as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeI32(const int32_t i32) {
return writeVarint32(i32ToZigzag(i32));
}
/**
* Write an i64 as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeI64(const int64_t i64) {
return writeVarint64(i64ToZigzag(i64));
}
/**
* Write a double to the wire as 8 bytes.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeDouble(const double dub) {
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
uint64_t bits = bitwise_cast<uint64_t>(dub);
bits = htolell(bits);
trans_->write((uint8_t*)&bits, 8);
return 8;
}
/**
* Write a string to the wire with a varint size preceeding.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeString(const std::string& str) {
return writeBinary(str);
}
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeBinary(const std::string& str) {
uint32_t ssize = str.size();
uint32_t wsize = writeVarint32(ssize) + ssize;
trans_->write((uint8_t*)str.data(), ssize);
return wsize;
}
//
// Internal Writing methods
//
/**
* The workhorse of writeFieldBegin. It has the option of doing a
* 'type override' of the type header. This is used specifically in the
* boolean field case.
*/
template <class Transport_>
int32_t TCompactProtocolT<Transport_>::writeFieldBeginInternal(
const char* name,
const TType fieldType,
const int16_t fieldId,
int8_t typeOverride) {
(void) name;
uint32_t wsize = 0;
// if there's a type override, use that.
int8_t typeToWrite = (typeOverride == -1 ? getCompactType(fieldType) : typeOverride);
// check if we can use delta encoding for the field id
if (fieldId > lastFieldId_ && fieldId - lastFieldId_ <= 15) {
// write them together
wsize += writeByte(static_cast<int8_t>((fieldId - lastFieldId_)
<< 4 | typeToWrite));
} else {
// write them separate
wsize += writeByte(typeToWrite);
wsize += writeI16(fieldId);
}
lastFieldId_ = fieldId;
return wsize;
}
/**
* Abstract method for writing the start of lists and sets. List and sets on
* the wire differ only by the type indicator.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeCollectionBegin(const TType elemType,
int32_t size) {
uint32_t wsize = 0;
if (size <= 14) {
wsize += writeByte(static_cast<int8_t>(size
<< 4 | getCompactType(elemType)));
} else {
wsize += writeByte(0xf0 | getCompactType(elemType));
wsize += writeVarint32(size);
}
return wsize;
}
/**
* Write an i32 as a varint. Results in 1-5 bytes on the wire.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeVarint32(uint32_t n) {
uint8_t buf[5];
uint32_t wsize = 0;
while (true) {
if ((n & ~0x7F) == 0) {
buf[wsize++] = (int8_t)n;
break;
} else {
buf[wsize++] = (int8_t)((n & 0x7F) | 0x80);
n >>= 7;
}
}
trans_->write(buf, wsize);
return wsize;
}
/**
* Write an i64 as a varint. Results in 1-10 bytes on the wire.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeVarint64(uint64_t n) {
uint8_t buf[10];
uint32_t wsize = 0;
while (true) {
if ((n & ~0x7FL) == 0) {
buf[wsize++] = (int8_t)n;
break;
} else {
buf[wsize++] = (int8_t)((n & 0x7F) | 0x80);
n >>= 7;
}
}
trans_->write(buf, wsize);
return wsize;
}
/**
* Convert l into a zigzag long. This allows negative numbers to be
* represented compactly as a varint.
*/
template <class Transport_>
uint64_t TCompactProtocolT<Transport_>::i64ToZigzag(const int64_t l) {
return (l << 1) ^ (l >> 63);
}
/**
* Convert n into a zigzag int. This allows negative numbers to be
* represented compactly as a varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::i32ToZigzag(const int32_t n) {
return (n << 1) ^ (n >> 31);
}
/**
* Given a TType value, find the appropriate detail::compact::Types value
*/
template <class Transport_>
int8_t TCompactProtocolT<Transport_>::getCompactType(const TType ttype) {
return detail::compact::TTypeToCType[ttype];
}
//
// Reading Methods
//
/**
* Read a message header.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readMessageBegin(
std::string& name,
TMessageType& messageType,
int32_t& seqid) {
uint32_t rsize = 0;
int8_t protocolId;
int8_t versionAndType;
int8_t version;
rsize += readByte(protocolId);
if (protocolId != PROTOCOL_ID) {
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol identifier");
}
rsize += readByte(versionAndType);
version = (int8_t)(versionAndType & VERSION_MASK);
if (version != VERSION_N) {
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version");
}
messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
rsize += readVarint32(seqid);
rsize += readString(name);
return rsize;
}
/**
* Read a struct begin. There's nothing on the wire for this, but it is our
* opportunity to push a new struct begin marker on the field stack.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readStructBegin(std::string& name) {
name = "";
lastField_.push(lastFieldId_);
lastFieldId_ = 0;
return 0;
}
/**
* Doesn't actually consume any wire data, just removes the last field for
* this struct from the field stack.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readStructEnd() {
lastFieldId_ = lastField_.top();
lastField_.pop();
return 0;
}
/**
* Read a field header off the wire.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId) {
(void) name;
uint32_t rsize = 0;
int8_t byte;
int8_t type;
rsize += readByte(byte);
type = (byte & 0x0f);
// if it's a stop, then we can return immediately, as the struct is over.
if (type == T_STOP) {
fieldType = T_STOP;
fieldId = 0;
return rsize;
}
// mask off the 4 MSB of the type header. it could contain a field id delta.
int16_t modifier = (int16_t)(((uint8_t)byte & 0xf0) >> 4);
if (modifier == 0) {
// not a delta, look ahead for the zigzag varint field id.
rsize += readI16(fieldId);
} else {
fieldId = (int16_t)(lastFieldId_ + modifier);
}
fieldType = getTType(type);
// if this happens to be a boolean field, the value is encoded in the type
if (type == detail::compact::CT_BOOLEAN_TRUE ||
type == detail::compact::CT_BOOLEAN_FALSE) {
// save the boolean value in a special instance variable.
boolValue_.hasBoolValue = true;
boolValue_.boolValue =
(type == detail::compact::CT_BOOLEAN_TRUE ? true : false);
}
// push the new field onto the field stack so we can keep the deltas going.
lastFieldId_ = fieldId;
return rsize;
}
/**
* Read a map header off the wire. If the size is zero, skip reading the key
* and value type. This means that 0-length maps will yield TMaps without the
* "correct" types.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readMapBegin(TType& keyType,
TType& valType,
uint32_t& size) {
uint32_t rsize = 0;
int8_t kvType = 0;
int32_t msize = 0;
rsize += readVarint32(msize);
if (msize != 0)
rsize += readByte(kvType);
if (msize < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
} else if (container_limit_ && msize > container_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
keyType = getTType((int8_t)((uint8_t)kvType >> 4));
valType = getTType((int8_t)((uint8_t)kvType & 0xf));
size = (uint32_t)msize;
return rsize;
}
/**
* Read a list header off the wire. If the list size is 0-14, the size will
* be packed into the element type header. If it's a longer list, the 4 MSB
* of the element type header will be 0xF, and a varint will follow with the
* true size.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readListBegin(TType& elemType,
uint32_t& size) {
int8_t size_and_type;
uint32_t rsize = 0;
int32_t lsize;
rsize += readByte(size_and_type);
lsize = ((uint8_t)size_and_type >> 4) & 0x0f;
if (lsize == 15) {
rsize += readVarint32(lsize);
}
if (lsize < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
} else if (container_limit_ && lsize > container_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
elemType = getTType((int8_t)(size_and_type & 0x0f));
size = (uint32_t)lsize;
return rsize;
}
/**
* Read a set header off the wire. If the set size is 0-14, the size will
* be packed into the element type header. If it's a longer set, the 4 MSB
* of the element type header will be 0xF, and a varint will follow with the
* true size.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readSetBegin(TType& elemType,
uint32_t& size) {
return readListBegin(elemType, size);
}
/**
* Read a boolean off the wire. If this is a boolean field, the value should
* already have been read during readFieldBegin, so we'll just consume the
* pre-stored value. Otherwise, read a byte.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readBool(bool& value) {
if (boolValue_.hasBoolValue == true) {
value = boolValue_.boolValue;
boolValue_.hasBoolValue = false;
return 0;
} else {
int8_t val;
readByte(val);
value = (val == detail::compact::CT_BOOLEAN_TRUE);
return 1;
}
}
/**
* Read a single byte off the wire. Nothing interesting here.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readByte(int8_t& byte) {
uint8_t b[1];
trans_->readAll(b, 1);
byte = *(int8_t*)b;
return 1;
}
/**
* Read an i16 from the wire as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readI16(int16_t& i16) {
int32_t value;
uint32_t rsize = readVarint32(value);
i16 = (int16_t)zigzagToI32(value);
return rsize;
}
/**
* Read an i32 from the wire as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readI32(int32_t& i32) {
int32_t value;
uint32_t rsize = readVarint32(value);
i32 = zigzagToI32(value);
return rsize;
}
/**
* Read an i64 from the wire as a zigzag varint.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readI64(int64_t& i64) {
int64_t value;
uint32_t rsize = readVarint64(value);
i64 = zigzagToI64(value);
return rsize;
}
/**
* No magic here - just read a double off the wire.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readDouble(double& dub) {
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
union {
uint64_t bits;
uint8_t b[8];
} u;
trans_->readAll(u.b, 8);
u.bits = letohll(u.bits);
dub = bitwise_cast<double>(u.bits);
return 8;
}
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readString(std::string& str) {
return readBinary(str);
}
/**
* Read a byte[] from the wire.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readBinary(std::string& str) {
int32_t rsize = 0;
int32_t size;
rsize += readVarint32(size);
// Catch empty string case
if (size == 0) {
str = "";
return rsize;
}
// Catch error cases
if (size < 0) {
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
}
if (string_limit_ > 0 && size > string_limit_) {
throw TProtocolException(TProtocolException::SIZE_LIMIT);
}
// Use the heap here to prevent stack overflow for v. large strings
if (size > string_buf_size_ || string_buf_ == NULL) {
void* new_string_buf = std::realloc(string_buf_, (uint32_t)size);
if (new_string_buf == NULL) {
throw std::bad_alloc();
}
string_buf_ = (uint8_t*)new_string_buf;
string_buf_size_ = size;
}
trans_->readAll(string_buf_, size);
str.assign((char*)string_buf_, size);
return rsize + (uint32_t)size;
}
/**
* Read an i32 from the wire as a varint. The MSB of each byte is set
* if there is another byte to follow. This can read up to 5 bytes.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readVarint32(int32_t& i32) {
int64_t val;
uint32_t rsize = readVarint64(val);
i32 = (int32_t)val;
return rsize;
}
/**
* Read an i64 from the wire as a proper varint. The MSB of each byte is set
* if there is another byte to follow. This can read up to 10 bytes.
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readVarint64(int64_t& i64) {
uint32_t rsize = 0;
uint64_t val = 0;
int shift = 0;
uint8_t buf[10]; // 64 bits / (7 bits/byte) = 10 bytes.
uint32_t buf_size = sizeof(buf);
const uint8_t* borrowed = trans_->borrow(buf, &buf_size);
// Fast path.
if (borrowed != NULL) {
while (true) {
uint8_t byte = borrowed[rsize];
rsize++;
val |= (uint64_t)(byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80)) {
i64 = val;
trans_->consume(rsize);
return rsize;
}
// Have to check for invalid data so we don't crash.
if (UNLIKELY(rsize == sizeof(buf))) {
throw TProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.");
}
}
}
// Slow path.
else {
while (true) {
uint8_t byte;
rsize += trans_->readAll(&byte, 1);
val |= (uint64_t)(byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80)) {
i64 = val;
return rsize;
}
// Might as well check for invalid data on the slow path too.
if (UNLIKELY(rsize >= sizeof(buf))) {
throw TProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.");
}
}
}
}
/**
* Convert from zigzag int to int.
*/
template <class Transport_>
int32_t TCompactProtocolT<Transport_>::zigzagToI32(uint32_t n) {
return (n >> 1) ^ -static_cast<int32_t>(n & 1);
}
/**
* Convert from zigzag long to long.
*/
template <class Transport_>
int64_t TCompactProtocolT<Transport_>::zigzagToI64(uint64_t n) {
return (n >> 1) ^ -static_cast<int32_t>(n & 1);
}
template <class Transport_>
TType TCompactProtocolT<Transport_>::getTType(int8_t type) {
switch (type) {
case T_STOP:
return T_STOP;
case detail::compact::CT_BOOLEAN_FALSE:
case detail::compact::CT_BOOLEAN_TRUE:
return T_BOOL;
case detail::compact::CT_BYTE:
return T_BYTE;
case detail::compact::CT_I16:
return T_I16;
case detail::compact::CT_I32:
return T_I32;
case detail::compact::CT_I64:
return T_I64;
case detail::compact::CT_DOUBLE:
return T_DOUBLE;
case detail::compact::CT_BINARY:
return T_STRING;
case detail::compact::CT_LIST:
return T_LIST;
case detail::compact::CT_SET:
return T_SET;
case detail::compact::CT_MAP:
return T_MAP;
case detail::compact::CT_STRUCT:
return T_STRUCT;
default:
throw TException(std::string("don't know what type: ") + (char)type);
}
return T_STOP;
}
}}} // apache::thrift::protocol
#endif // _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_

View File

@ -1,247 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TVirtualProtocol.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace protocol
{
/*
!!! EXPERIMENTAL CODE !!!
This protocol is very much a work in progress.
It doesn't handle many cases properly.
It throws exceptions in many cases.
It probably segfaults in many cases.
Bug reports and feature requests are welcome.
Complaints are not. :R
*/
/**
* Protocol that prints the payload in a nice human-readable format.
* Reading from this protocol is not supported.
*
*/
class TDebugProtocol : public TVirtualProtocol<TDebugProtocol>
{
private:
enum write_state_t
{
UNINIT
, STRUCT
, LIST
, SET
, MAP_KEY
, MAP_VALUE
};
public:
TDebugProtocol(boost::shared_ptr<TTransport> trans)
: TVirtualProtocol<TDebugProtocol>(trans)
, trans_(trans.get())
, string_limit_(DEFAULT_STRING_LIMIT)
, string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
{
write_state_.push_back(UNINIT);
}
static const int32_t DEFAULT_STRING_LIMIT = 256;
static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
void setStringSizeLimit(int32_t string_limit)
{
string_limit_ = string_limit;
}
void setStringPrefixSize(int32_t string_prefix_size)
{
string_prefix_size_ = string_prefix_size;
}
uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid);
uint32_t writeMessageEnd();
uint32_t writeStructBegin(const char* name);
uint32_t writeStructEnd();
uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId);
uint32_t writeFieldEnd();
uint32_t writeFieldStop();
uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size);
uint32_t writeMapEnd();
uint32_t writeListBegin(const TType elemType,
const uint32_t size);
uint32_t writeListEnd();
uint32_t writeSetBegin(const TType elemType,
const uint32_t size);
uint32_t writeSetEnd();
uint32_t writeBool(const bool value);
uint32_t writeByte(const int8_t byte);
uint32_t writeI16(const int16_t i16);
uint32_t writeI32(const int32_t i32);
uint32_t writeI64(const int64_t i64);
uint32_t writeDouble(const double dub);
uint32_t writeString(const std::string& str);
uint32_t writeBinary(const std::string& str);
private:
void indentUp();
void indentDown();
uint32_t writePlain(const std::string& str);
uint32_t writeIndented(const std::string& str);
uint32_t startItem();
uint32_t endItem();
uint32_t writeItem(const std::string& str);
static std::string fieldTypeName(TType type);
TTransport* trans_;
int32_t string_limit_;
int32_t string_prefix_size_;
std::string indent_str_;
static const int indent_inc = 2;
std::vector<write_state_t> write_state_;
std::vector<int> list_idx_;
};
/**
* Constructs debug protocol handlers
*/
class TDebugProtocolFactory : public TProtocolFactory
{
public:
TDebugProtocolFactory() {}
virtual ~TDebugProtocolFactory() {}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans)
{
return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
}
};
}
}
} // apache::thrift::protocol
// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
#include <thrift/transport/TBufferTransports.h>
namespace apache
{
namespace thrift
{
template<typename ThriftStruct>
std::string ThriftDebugString(const ThriftStruct& ts)
{
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
TMemoryBuffer* buffer = new TMemoryBuffer;
boost::shared_ptr<TTransport> trans(buffer);
TDebugProtocol protocol(trans);
ts.write(&protocol);
uint8_t* buf;
uint32_t size;
buffer->getBuffer(&buf, &size);
return std::string((char*)buf, (unsigned int)size);
}
// TODO(dreiss): This is badly broken. Don't use it unless you are me.
#if 0
template<typename Object>
std::string DebugString(const std::vector<Object>& vec)
{
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
TMemoryBuffer* buffer = new TMemoryBuffer;
boost::shared_ptr<TTransport> trans(buffer);
TDebugProtocol protocol(trans);
// I am gross!
protocol.writeStructBegin("SomeRandomVector");
// TODO: Fix this with a trait.
protocol.writeListBegin((TType)99, vec.size());
typename std::vector<Object>::const_iterator it;
for (it = vec.begin(); it != vec.end(); ++it)
{
it->write(&protocol);
}
protocol.writeListEnd();
uint8_t* buf;
uint32_t size;
buffer->getBuffer(&buf, &size);
return std::string((char*)buf, (unsigned int)size);
}
#endif // 0
}
} // apache::thrift

View File

@ -1,265 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/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 TVirtualProtocol<TDenseProtocol, TBinaryProtocol>
{
protected:
static const int32_t VERSION_MASK = ((int32_t)0xffff0000);
// VERSION_1 (0x80010000) is taken by TBinaryProtocol.
static const int32_t VERSION_2 = ((int32_t)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) :
TVirtualProtocol<TDenseProtocol, TBinaryProtocol>(trans),
type_spec_(type_spec),
standalone_(true)
{}
void setTypeSpec(TypeSpec* type_spec)
{
type_spec_ = type_spec;
}
TypeSpec* getTypeSpec()
{
return type_spec_;
}
/*
* Writing functions.
*/
uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid);
uint32_t writeMessageEnd();
uint32_t writeStructBegin(const char* name);
uint32_t writeStructEnd();
uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId);
uint32_t writeFieldEnd();
uint32_t writeFieldStop();
uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size);
uint32_t writeMapEnd();
uint32_t writeListBegin(const TType elemType, const uint32_t size);
uint32_t writeListEnd();
uint32_t writeSetBegin(const TType elemType, const uint32_t size);
uint32_t writeSetEnd();
uint32_t writeBool(const bool value);
uint32_t writeByte(const int8_t byte);
uint32_t writeI16(const int16_t i16);
uint32_t writeI32(const int32_t i32);
uint32_t writeI64(const int64_t i64);
uint32_t writeDouble(const double dub);
uint32_t writeString(const std::string& str);
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);
// Provide the default readBool() implementation for std::vector<bool>
using TVirtualProtocol<TDenseProtocol, TBinaryProtocol>::readBool;
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

View File

@ -1,361 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TVirtualProtocol.h>
#include <stack>
namespace apache
{
namespace thrift
{
namespace protocol
{
// Forward declaration
class TJSONContext;
/**
* JSON protocol for Thrift.
*
* Implements a protocol which uses JSON as the wire-format.
*
* Thrift types are represented as described below:
*
* 1. Every Thrift integer type is represented as a JSON number.
*
* 2. Thrift doubles are represented as JSON numbers. Some special values are
* represented as strings:
* a. "NaN" for not-a-number values
* b. "Infinity" for postive infinity
* c. "-Infinity" for negative infinity
*
* 3. Thrift string values are emitted as JSON strings, with appropriate
* escaping.
*
* 4. Thrift binary values are encoded into Base64 and emitted as JSON strings.
* The readBinary() method is written such that it will properly skip if
* called on a Thrift string (although it will decode garbage data).
*
* 5. Thrift structs are represented as JSON objects, with the field ID as the
* key, and the field value represented as a JSON object with a single
* key-value pair. The key is a short string identifier for that type,
* followed by the value. The valid type identifiers are: "tf" for bool,
* "i8" for byte, "i16" for 16-bit integer, "i32" for 32-bit integer, "i64"
* for 64-bit integer, "dbl" for double-precision loating point, "str" for
* string (including binary), "rec" for struct ("records"), "map" for map,
* "lst" for list, "set" for set.
*
* 6. Thrift lists and sets are represented as JSON arrays, with the first
* element of the JSON array being the string identifier for the Thrift
* element type and the second element of the JSON array being the count of
* the Thrift elements. The Thrift elements then follow.
*
* 7. Thrift maps are represented as JSON arrays, with the first two elements
* of the JSON array being the string identifiers for the Thrift key type
* and value type, followed by the count of the Thrift pairs, followed by a
* JSON object containing the key-value pairs. Note that JSON keys can only
* be strings, which means that the key type of the Thrift map should be
* restricted to numeric or string types -- in the case of numerics, they
* are serialized as strings.
*
* 8. Thrift messages are represented as JSON arrays, with the protocol
* version #, the message name, the message type, and the sequence ID as
* the first 4 elements.
*
* More discussion of the double handling is probably warranted. The aim of
* the current implementation is to match as closely as possible the behavior
* of Java's Double.toString(), which has no precision loss. Implementors in
* other languages should strive to achieve that where possible. I have not
* yet verified whether boost:lexical_cast, which is doing that work for me in
* C++, loses any precision, but I am leaving this as a future improvement. I
* may try to provide a C component for this, so that other languages could
* bind to the same underlying implementation for maximum consistency.
*
*/
class TJSONProtocol : public TVirtualProtocol<TJSONProtocol>
{
public:
TJSONProtocol(boost::shared_ptr<TTransport> ptrans);
~TJSONProtocol();
private:
void pushContext(boost::shared_ptr<TJSONContext> c);
void popContext();
uint32_t writeJSONEscapeChar(uint8_t ch);
uint32_t writeJSONChar(uint8_t ch);
uint32_t writeJSONString(const std::string& str);
uint32_t writeJSONBase64(const std::string& str);
template <typename NumberType>
uint32_t writeJSONInteger(NumberType num);
uint32_t writeJSONDouble(double num);
uint32_t writeJSONObjectStart() ;
uint32_t writeJSONObjectEnd();
uint32_t writeJSONArrayStart();
uint32_t writeJSONArrayEnd();
uint32_t readJSONSyntaxChar(uint8_t ch);
uint32_t readJSONEscapeChar(uint8_t* out);
uint32_t readJSONString(std::string& str, bool skipContext = false);
uint32_t readJSONBase64(std::string& str);
uint32_t readJSONNumericChars(std::string& str);
template <typename NumberType>
uint32_t readJSONInteger(NumberType& num);
uint32_t readJSONDouble(double& num);
uint32_t readJSONObjectStart();
uint32_t readJSONObjectEnd();
uint32_t readJSONArrayStart();
uint32_t readJSONArrayEnd();
public:
/**
* Writing functions.
*/
uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid);
uint32_t writeMessageEnd();
uint32_t writeStructBegin(const char* name);
uint32_t writeStructEnd();
uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId);
uint32_t writeFieldEnd();
uint32_t writeFieldStop();
uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size);
uint32_t writeMapEnd();
uint32_t writeListBegin(const TType elemType,
const uint32_t size);
uint32_t writeListEnd();
uint32_t writeSetBegin(const TType elemType,
const uint32_t size);
uint32_t writeSetEnd();
uint32_t writeBool(const bool value);
uint32_t writeByte(const int8_t byte);
uint32_t writeI16(const int16_t i16);
uint32_t writeI32(const int32_t i32);
uint32_t writeI64(const int64_t i64);
uint32_t writeDouble(const double dub);
uint32_t writeString(const std::string& str);
uint32_t writeBinary(const std::string& str);
/**
* 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);
// Provide the default readBool() implementation for std::vector<bool>
using TVirtualProtocol<TJSONProtocol>::readBool;
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);
class LookaheadReader
{
public:
LookaheadReader(TTransport& trans) :
trans_(&trans),
hasData_(false)
{
}
uint8_t read()
{
if (hasData_)
{
hasData_ = false;
}
else
{
trans_->readAll(&data_, 1);
}
return data_;
}
uint8_t peek()
{
if (!hasData_)
{
trans_->readAll(&data_, 1);
}
hasData_ = true;
return data_;
}
private:
TTransport* trans_;
bool hasData_;
uint8_t data_;
};
private:
TTransport* trans_;
std::stack<boost::shared_ptr<TJSONContext> > contexts_;
boost::shared_ptr<TJSONContext> context_;
LookaheadReader reader_;
};
/**
* Constructs input and output protocol objects given transports.
*/
class TJSONProtocolFactory : public TProtocolFactory
{
public:
TJSONProtocolFactory() {}
virtual ~TJSONProtocolFactory() {}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans)
{
return boost::shared_ptr<TProtocol>(new TJSONProtocol(trans));
}
};
}
}
} // apache::thrift::protocol
// TODO(dreiss): Move part of ThriftJSONString into a .cpp file and remove this.
#include <thrift/transport/TBufferTransports.h>
namespace apache
{
namespace thrift
{
template<typename ThriftStruct>
std::string ThriftJSONString(const ThriftStruct& ts)
{
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
TMemoryBuffer* buffer = new TMemoryBuffer;
boost::shared_ptr<TTransport> trans(buffer);
TJSONProtocol protocol(trans);
ts.write(&protocol);
uint8_t* buf;
uint32_t size;
buffer->getBuffer(&buf, &size);
return std::string((char*)buf, (unsigned int)size);
}
}
} // apache::thrift

View File

@ -1,101 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TProtocolDecorator.h>
namespace apache
{
namespace thrift
{
namespace protocol
{
using boost::shared_ptr;
/**
* <code>TMultiplexedProtocol</code> is a protocol-independent concrete decorator
* that allows a Thrift client to communicate with a multiplexing Thrift server,
* by prepending the service name to the function name during function calls.
*
* \note THIS IS NOT USED BY SERVERS. On the server, use
* {@link apache::thrift::TMultiplexedProcessor TMultiplexedProcessor} to handle requests
* from a multiplexing client.
*
* This example uses a single socket transport to invoke two services:
*
* <blockquote><code>
* shared_ptr<TSocket> transport(new TSocket("localhost", 9090));
* transport->open();
*
* shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
*
* shared_ptr<TMultiplexedProtocol> mp1(new TMultiplexedProtocol(protocol, "Calculator"));
* shared_ptr<CalculatorClient> service1(new CalculatorClient(mp1));
*
* shared_ptr<TMultiplexedProtocol> mp2(new TMultiplexedProtocol(protocol, "WeatherReport"));
* shared_ptr<WeatherReportClient> service2(new WeatherReportClient(mp2));
*
* service1->add(2,2);
* int temp = service2->getTemperature();
* </code></blockquote>
*
* @see apache::thrift::protocol::TProtocolDecorator
*/
class TMultiplexedProtocol : public TProtocolDecorator
{
public:
/**
* Wrap the specified protocol, allowing it to be used to communicate with a
* multiplexing server. The <code>serviceName</code> is required as it is
* prepended to the message header so that the multiplexing server can broker
* the function call to the proper service.
*
* \param _protocol Your communication protocol of choice, e.g. <code>TBinaryProtocol</code>.
* \param _serviceName The service name of the service communicating via this protocol.
*/
TMultiplexedProtocol( shared_ptr<TProtocol> _protocol, const std::string& _serviceName )
: TProtocolDecorator(_protocol),
serviceName(_serviceName),
separator(":")
{ }
virtual ~TMultiplexedProtocol() {}
/**
* Prepends the service name to the function name, separated by TMultiplexedProtocol::SEPARATOR.
*
* \param [in] _name The name of the method to be called in the service.
* \param [in] _type The type of message
* \param [in] _name The sequential id of the message
*
* \throws TException Passed through from wrapped <code>TProtocol</code> instance.
*/
uint32_t writeMessageBegin_virt(
const std::string& _name,
const TMessageType _type,
const int32_t _seqid);
private:
const std::string serviceName;
const std::string separator;
};
}
}
}

View File

@ -1,790 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TTransport.h>
#include <thrift/protocol/TProtocolException.h>
#include <boost/shared_ptr.hpp>
#include <boost/static_assert.hpp>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <sys/types.h>
#include <string>
#include <map>
#include <vector>
// Use this to get around strict aliasing rules.
// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
// The most obvious implementation is to just cast a pointer,
// but that doesn't work.
// For a pretty in-depth explanation of the problem, see
// http://www.cellperformance.com/mike_acton/2006/06/ (...)
// understanding_strict_aliasing.html
template <typename To, typename From>
static inline To bitwise_cast(From from)
{
BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
// BAD!!! These are all broken with -O2.
//return *reinterpret_cast<To*>(&from); // BAD!!!
//return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
//return *(To*)(void*)&from; // BAD!!!
// Super clean and paritally blessed by section 3.9 of the standard.
//unsigned char c[sizeof(from)];
//memcpy(c, &from, sizeof(from));
//To to;
//memcpy(&to, c, sizeof(c));
//return to;
// Slightly more questionable.
// Same code emitted by GCC.
//To to;
//memcpy(&to, &from, sizeof(from));
//return to;
// Technically undefined, but almost universally supported,
// and the most efficient implementation.
union
{
From f;
To t;
} u;
u.f = from;
return u.t;
}
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifndef __THRIFT_BYTE_ORDER
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
# define __THRIFT_BYTE_ORDER BYTE_ORDER
# define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
# define __THRIFT_BIG_ENDIAN BIG_ENDIAN
# else
# include <boost/config.hpp>
# include <boost/detail/endian.hpp>
# define __THRIFT_BYTE_ORDER BOOST_BYTE_ORDER
# ifdef BOOST_LITTLE_ENDIAN
# define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
# define __THRIFT_BIG_ENDIAN 0
# else
# define __THRIFT_LITTLE_ENDIAN 0
# define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
# endif
# endif
#endif
#if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
# define ntohll(n) (n)
# define htonll(n) (n)
# if defined(__GNUC__) && defined(__GLIBC__)
# include <byteswap.h>
# define htolell(n) bswap_64(n)
# define letohll(n) bswap_64(n)
# else /* GNUC & GLIBC */
# define bswap_64(n) \
( (((n) & 0xff00000000000000ull) >> 56) \
| (((n) & 0x00ff000000000000ull) >> 40) \
| (((n) & 0x0000ff0000000000ull) >> 24) \
| (((n) & 0x000000ff00000000ull) >> 8) \
| (((n) & 0x00000000ff000000ull) << 8) \
| (((n) & 0x0000000000ff0000ull) << 24) \
| (((n) & 0x000000000000ff00ull) << 40) \
| (((n) & 0x00000000000000ffull) << 56) )
# define htolell(n) bswap_64(n)
# define letohll(n) bswap_64(n)
# endif /* GNUC & GLIBC */
#elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN
# define htolell(n) (n)
# define letohll(n) (n)
# if defined(__GNUC__) && defined(__GLIBC__)
# include <byteswap.h>
# define ntohll(n) bswap_64(n)
# define htonll(n) bswap_64(n)
# elif defined(_MSC_VER) /* Microsoft Visual C++ */
# define ntohll(n) ( _byteswap_uint64((uint64_t)n) )
# define htonll(n) ( _byteswap_uint64((uint64_t)n) )
# else /* Not GNUC/GLIBC or MSVC */
# define ntohll(n) ( (((uint64_t)ntohl((uint32_t)n)) << 32) + ntohl((uint32_t)(n >> 32)) )
# define htonll(n) ( (((uint64_t)htonl((uint32_t)n)) << 32) + htonl((uint32_t)(n >> 32)) )
# endif /* GNUC/GLIBC or MSVC or something else */
#else /* __THRIFT_BYTE_ORDER */
# error "Can't define htonll or ntohll!"
#endif
namespace apache
{
namespace thrift
{
namespace protocol
{
using apache::thrift::transport::TTransport;
/**
* Enumerated definition of the types that the Thrift protocol supports.
* Take special note of the T_END type which is used specifically to mark
* the end of a sequence of fields.
*/
enum TType
{
T_STOP = 0,
T_VOID = 1,
T_BOOL = 2,
T_BYTE = 3,
T_I08 = 3,
T_I16 = 6,
T_I32 = 8,
T_U64 = 9,
T_I64 = 10,
T_DOUBLE = 4,
T_STRING = 11,
T_UTF7 = 11,
T_STRUCT = 12,
T_MAP = 13,
T_SET = 14,
T_LIST = 15,
T_UTF8 = 16,
T_UTF16 = 17
};
/**
* Enumerated definition of the message types that the Thrift protocol
* supports.
*/
enum TMessageType
{
T_CALL = 1,
T_REPLY = 2,
T_EXCEPTION = 3,
T_ONEWAY = 4
};
/**
* Helper template for implementing TProtocol::skip().
*
* Templatized to avoid having to make virtual function calls.
*/
template <class Protocol_>
uint32_t skip(Protocol_& prot, TType type)
{
switch (type)
{
case T_BOOL:
{
bool boolv;
return prot.readBool(boolv);
}
case T_BYTE:
{
int8_t bytev;
return prot.readByte(bytev);
}
case T_I16:
{
int16_t i16;
return prot.readI16(i16);
}
case T_I32:
{
int32_t i32;
return prot.readI32(i32);
}
case T_I64:
{
int64_t i64;
return prot.readI64(i64);
}
case T_DOUBLE:
{
double dub;
return prot.readDouble(dub);
}
case T_STRING:
{
std::string str;
return prot.readBinary(str);
}
case T_STRUCT:
{
uint32_t result = 0;
std::string name;
int16_t fid;
TType ftype;
result += prot.readStructBegin(name);
while (true)
{
result += prot.readFieldBegin(name, ftype, fid);
if (ftype == T_STOP)
{
break;
}
result += skip(prot, ftype);
result += prot.readFieldEnd();
}
result += prot.readStructEnd();
return result;
}
case T_MAP:
{
uint32_t result = 0;
TType keyType;
TType valType;
uint32_t i, size;
result += prot.readMapBegin(keyType, valType, size);
for (i = 0; i < size; i++)
{
result += skip(prot, keyType);
result += skip(prot, valType);
}
result += prot.readMapEnd();
return result;
}
case T_SET:
{
uint32_t result = 0;
TType elemType;
uint32_t i, size;
result += prot.readSetBegin(elemType, size);
for (i = 0; i < size; i++)
{
result += skip(prot, elemType);
}
result += prot.readSetEnd();
return result;
}
case T_LIST:
{
uint32_t result = 0;
TType elemType;
uint32_t i, size;
result += prot.readListBegin(elemType, size);
for (i = 0; i < size; i++)
{
result += skip(prot, elemType);
}
result += prot.readListEnd();
return result;
}
case T_STOP:
case T_VOID:
case T_U64:
case T_UTF8:
case T_UTF16:
break;
}
return 0;
}
/**
* Abstract class for a thrift protocol driver. These are all the methods that
* a protocol must implement. Essentially, there must be some way of reading
* and writing all the base types, plus a mechanism for writing out structs
* with indexed fields.
*
* TProtocol objects should not be shared across multiple encoding contexts,
* as they may need to maintain internal state in some protocols (i.e. XML).
* Note that is is acceptable for the TProtocol module to do its own internal
* buffered reads/writes to the underlying TTransport where appropriate (i.e.
* when parsing an input XML stream, reading should be batched rather than
* looking ahead character by character for a close tag).
*
*/
class TProtocol
{
public:
virtual ~TProtocol() {}
/**
* Writing functions.
*/
virtual uint32_t writeMessageBegin_virt(const std::string& name,
const TMessageType messageType,
const int32_t seqid) = 0;
virtual uint32_t writeMessageEnd_virt() = 0;
virtual uint32_t writeStructBegin_virt(const char* name) = 0;
virtual uint32_t writeStructEnd_virt() = 0;
virtual uint32_t writeFieldBegin_virt(const char* name,
const TType fieldType,
const int16_t fieldId) = 0;
virtual uint32_t writeFieldEnd_virt() = 0;
virtual uint32_t writeFieldStop_virt() = 0;
virtual uint32_t writeMapBegin_virt(const TType keyType,
const TType valType,
const uint32_t size) = 0;
virtual uint32_t writeMapEnd_virt() = 0;
virtual uint32_t writeListBegin_virt(const TType elemType,
const uint32_t size) = 0;
virtual uint32_t writeListEnd_virt() = 0;
virtual uint32_t writeSetBegin_virt(const TType elemType,
const uint32_t size) = 0;
virtual uint32_t writeSetEnd_virt() = 0;
virtual uint32_t writeBool_virt(const bool value) = 0;
virtual uint32_t writeByte_virt(const int8_t byte) = 0;
virtual uint32_t writeI16_virt(const int16_t i16) = 0;
virtual uint32_t writeI32_virt(const int32_t i32) = 0;
virtual uint32_t writeI64_virt(const int64_t i64) = 0;
virtual uint32_t writeDouble_virt(const double dub) = 0;
virtual uint32_t writeString_virt(const std::string& str) = 0;
virtual uint32_t writeBinary_virt(const std::string& str) = 0;
uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid)
{
T_VIRTUAL_CALL();
return writeMessageBegin_virt(name, messageType, seqid);
}
uint32_t writeMessageEnd()
{
T_VIRTUAL_CALL();
return writeMessageEnd_virt();
}
uint32_t writeStructBegin(const char* name)
{
T_VIRTUAL_CALL();
return writeStructBegin_virt(name);
}
uint32_t writeStructEnd()
{
T_VIRTUAL_CALL();
return writeStructEnd_virt();
}
uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId)
{
T_VIRTUAL_CALL();
return writeFieldBegin_virt(name, fieldType, fieldId);
}
uint32_t writeFieldEnd()
{
T_VIRTUAL_CALL();
return writeFieldEnd_virt();
}
uint32_t writeFieldStop()
{
T_VIRTUAL_CALL();
return writeFieldStop_virt();
}
uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size)
{
T_VIRTUAL_CALL();
return writeMapBegin_virt(keyType, valType, size);
}
uint32_t writeMapEnd()
{
T_VIRTUAL_CALL();
return writeMapEnd_virt();
}
uint32_t writeListBegin(const TType elemType, const uint32_t size)
{
T_VIRTUAL_CALL();
return writeListBegin_virt(elemType, size);
}
uint32_t writeListEnd()
{
T_VIRTUAL_CALL();
return writeListEnd_virt();
}
uint32_t writeSetBegin(const TType elemType, const uint32_t size)
{
T_VIRTUAL_CALL();
return writeSetBegin_virt(elemType, size);
}
uint32_t writeSetEnd()
{
T_VIRTUAL_CALL();
return writeSetEnd_virt();
}
uint32_t writeBool(const bool value)
{
T_VIRTUAL_CALL();
return writeBool_virt(value);
}
uint32_t writeByte(const int8_t byte)
{
T_VIRTUAL_CALL();
return writeByte_virt(byte);
}
uint32_t writeI16(const int16_t i16)
{
T_VIRTUAL_CALL();
return writeI16_virt(i16);
}
uint32_t writeI32(const int32_t i32)
{
T_VIRTUAL_CALL();
return writeI32_virt(i32);
}
uint32_t writeI64(const int64_t i64)
{
T_VIRTUAL_CALL();
return writeI64_virt(i64);
}
uint32_t writeDouble(const double dub)
{
T_VIRTUAL_CALL();
return writeDouble_virt(dub);
}
uint32_t writeString(const std::string& str)
{
T_VIRTUAL_CALL();
return writeString_virt(str);
}
uint32_t writeBinary(const std::string& str)
{
T_VIRTUAL_CALL();
return writeBinary_virt(str);
}
/**
* Reading functions
*/
virtual uint32_t readMessageBegin_virt(std::string& name,
TMessageType& messageType,
int32_t& seqid) = 0;
virtual uint32_t readMessageEnd_virt() = 0;
virtual uint32_t readStructBegin_virt(std::string& name) = 0;
virtual uint32_t readStructEnd_virt() = 0;
virtual uint32_t readFieldBegin_virt(std::string& name,
TType& fieldType,
int16_t& fieldId) = 0;
virtual uint32_t readFieldEnd_virt() = 0;
virtual uint32_t readMapBegin_virt(TType& keyType,
TType& valType,
uint32_t& size) = 0;
virtual uint32_t readMapEnd_virt() = 0;
virtual uint32_t readListBegin_virt(TType& elemType,
uint32_t& size) = 0;
virtual uint32_t readListEnd_virt() = 0;
virtual uint32_t readSetBegin_virt(TType& elemType,
uint32_t& size) = 0;
virtual uint32_t readSetEnd_virt() = 0;
virtual uint32_t readBool_virt(bool& value) = 0;
virtual uint32_t readBool_virt(std::vector<bool>::reference value) = 0;
virtual uint32_t readByte_virt(int8_t& byte) = 0;
virtual uint32_t readI16_virt(int16_t& i16) = 0;
virtual uint32_t readI32_virt(int32_t& i32) = 0;
virtual uint32_t readI64_virt(int64_t& i64) = 0;
virtual uint32_t readDouble_virt(double& dub) = 0;
virtual uint32_t readString_virt(std::string& str) = 0;
virtual uint32_t readBinary_virt(std::string& str) = 0;
uint32_t readMessageBegin(std::string& name,
TMessageType& messageType,
int32_t& seqid)
{
T_VIRTUAL_CALL();
return readMessageBegin_virt(name, messageType, seqid);
}
uint32_t readMessageEnd()
{
T_VIRTUAL_CALL();
return readMessageEnd_virt();
}
uint32_t readStructBegin(std::string& name)
{
T_VIRTUAL_CALL();
return readStructBegin_virt(name);
}
uint32_t readStructEnd()
{
T_VIRTUAL_CALL();
return readStructEnd_virt();
}
uint32_t readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId)
{
T_VIRTUAL_CALL();
return readFieldBegin_virt(name, fieldType, fieldId);
}
uint32_t readFieldEnd()
{
T_VIRTUAL_CALL();
return readFieldEnd_virt();
}
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size)
{
T_VIRTUAL_CALL();
return readMapBegin_virt(keyType, valType, size);
}
uint32_t readMapEnd()
{
T_VIRTUAL_CALL();
return readMapEnd_virt();
}
uint32_t readListBegin(TType& elemType, uint32_t& size)
{
T_VIRTUAL_CALL();
return readListBegin_virt(elemType, size);
}
uint32_t readListEnd()
{
T_VIRTUAL_CALL();
return readListEnd_virt();
}
uint32_t readSetBegin(TType& elemType, uint32_t& size)
{
T_VIRTUAL_CALL();
return readSetBegin_virt(elemType, size);
}
uint32_t readSetEnd()
{
T_VIRTUAL_CALL();
return readSetEnd_virt();
}
uint32_t readBool(bool& value)
{
T_VIRTUAL_CALL();
return readBool_virt(value);
}
uint32_t readByte(int8_t& byte)
{
T_VIRTUAL_CALL();
return readByte_virt(byte);
}
uint32_t readI16(int16_t& i16)
{
T_VIRTUAL_CALL();
return readI16_virt(i16);
}
uint32_t readI32(int32_t& i32)
{
T_VIRTUAL_CALL();
return readI32_virt(i32);
}
uint32_t readI64(int64_t& i64)
{
T_VIRTUAL_CALL();
return readI64_virt(i64);
}
uint32_t readDouble(double& dub)
{
T_VIRTUAL_CALL();
return readDouble_virt(dub);
}
uint32_t readString(std::string& str)
{
T_VIRTUAL_CALL();
return readString_virt(str);
}
uint32_t readBinary(std::string& str)
{
T_VIRTUAL_CALL();
return readBinary_virt(str);
}
/*
* std::vector is specialized for bool, and its elements are individual bits
* rather than bools. We need to define a different version of readBool()
* to work with std::vector<bool>.
*/
uint32_t readBool(std::vector<bool>::reference value)
{
T_VIRTUAL_CALL();
return readBool_virt(value);
}
/**
* Method to arbitrarily skip over data.
*/
uint32_t skip(TType type)
{
T_VIRTUAL_CALL();
return skip_virt(type);
}
virtual uint32_t skip_virt(TType type)
{
return ::apache::thrift::protocol::skip(*this, type);
}
inline boost::shared_ptr<TTransport> getTransport()
{
return ptrans_;
}
// TODO: remove these two calls, they are for backwards
// compatibility
inline boost::shared_ptr<TTransport> getInputTransport()
{
return ptrans_;
}
inline boost::shared_ptr<TTransport> getOutputTransport()
{
return ptrans_;
}
protected:
TProtocol(boost::shared_ptr<TTransport> ptrans):
ptrans_(ptrans)
{
}
boost::shared_ptr<TTransport> ptrans_;
private:
TProtocol() {}
};
/**
* Constructs input and output protocol objects given transports.
*/
class TProtocolFactory
{
public:
TProtocolFactory() {}
virtual ~TProtocolFactory() {}
virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) = 0;
};
/**
* Dummy protocol class.
*
* This class does nothing, and should never be instantiated.
* It is used only by the generator code.
*/
class TDummyProtocol : public TProtocol
{
};
}
}
} // apache::thrift::protocol

View File

@ -1,254 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TProtocol.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace protocol
{
using boost::shared_ptr;
/**
* <code>TProtocolDecorator</code> forwards all requests to an enclosed
* <code>TProtocol</code> instance, providing a way to author concise
* concrete decorator subclasses.
*
* <p>See p.175 of Design Patterns (by Gamma et al.)</p>
*
* @see apache::thrift::protocol::TMultiplexedProtocol
*/
class TProtocolDecorator : public TProtocol
{
public:
virtual ~TProtocolDecorator() {}
// Desc: Initializes the protocol decorator object.
TProtocolDecorator( shared_ptr<TProtocol> proto )
: TProtocol(proto->getTransport()), protocol(proto)
{
}
virtual uint32_t writeMessageBegin_virt(
const std::string& name,
const TMessageType messageType,
const int32_t seqid)
{
return protocol->writeMessageBegin(name, messageType, seqid);
}
virtual uint32_t writeMessageEnd_virt()
{
return protocol->writeMessageEnd();
}
virtual uint32_t writeStructBegin_virt(const char* name)
{
return protocol->writeStructBegin(name);
}
virtual uint32_t writeStructEnd_virt()
{
return protocol->writeStructEnd();
}
virtual uint32_t writeFieldBegin_virt(const char* name,
const TType fieldType,
const int16_t fieldId)
{
return protocol->writeFieldBegin(name, fieldType, fieldId);
}
virtual uint32_t writeFieldEnd_virt()
{
return protocol->writeFieldEnd();
}
virtual uint32_t writeFieldStop_virt()
{
return protocol->writeFieldStop();
}
virtual uint32_t writeMapBegin_virt(const TType keyType,
const TType valType,
const uint32_t size)
{
return protocol->writeMapBegin(keyType, valType, size);
}
virtual uint32_t writeMapEnd_virt()
{
return protocol->writeMapEnd();
}
virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size)
{
return protocol->writeListBegin(elemType, size);
}
virtual uint32_t writeListEnd_virt()
{
return protocol->writeListEnd();
}
virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size)
{
return protocol->writeSetBegin(elemType, size);
}
virtual uint32_t writeSetEnd_virt()
{
return protocol->writeSetEnd();
}
virtual uint32_t writeBool_virt(const bool value)
{
return protocol->writeBool(value);
}
virtual uint32_t writeByte_virt(const int8_t byte)
{
return protocol->writeByte(byte);
}
virtual uint32_t writeI16_virt(const int16_t i16)
{
return protocol->writeI16(i16);
}
virtual uint32_t writeI32_virt(const int32_t i32)
{
return protocol->writeI32(i32);
}
virtual uint32_t writeI64_virt(const int64_t i64)
{
return protocol->writeI64(i64);
}
virtual uint32_t writeDouble_virt(const double dub)
{
return protocol->writeDouble(dub);
}
virtual uint32_t writeString_virt(const std::string& str)
{
return protocol->writeString(str);
}
virtual uint32_t writeBinary_virt(const std::string& str)
{
return protocol->writeBinary(str);
}
virtual uint32_t readMessageBegin_virt(std::string& name, TMessageType& messageType, int32_t& seqid)
{
return protocol->readMessageBegin(name, messageType, seqid);
}
virtual uint32_t readMessageEnd_virt()
{
return protocol->readMessageEnd();
}
virtual uint32_t readStructBegin_virt(std::string& name)
{
return protocol->readStructBegin(name);
}
virtual uint32_t readStructEnd_virt()
{
return protocol->readStructEnd();
}
virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId)
{
return protocol->readFieldBegin(name, fieldType, fieldId);
}
virtual uint32_t readFieldEnd_virt()
{
return protocol->readFieldEnd();
}
virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size)
{
return protocol->readMapBegin(keyType, valType, size);
}
virtual uint32_t readMapEnd_virt()
{
return protocol->readMapEnd();
}
virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size)
{
return protocol->readListBegin(elemType, size);
}
virtual uint32_t readListEnd_virt()
{
return protocol->readListEnd();
}
virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size)
{
return protocol->readSetBegin(elemType, size);
}
virtual uint32_t readSetEnd_virt()
{
return protocol->readSetEnd();
}
virtual uint32_t readBool_virt(bool& value)
{
return protocol->readBool(value);
}
virtual uint32_t readBool_virt(std::vector<bool>::reference value)
{
return protocol->readBool(value);
}
virtual uint32_t readByte_virt(int8_t& byte)
{
return protocol->readByte(byte);
}
virtual uint32_t readI16_virt(int16_t& i16)
{
return protocol->readI16(i16);
}
virtual uint32_t readI32_virt(int32_t& i32)
{
return protocol->readI32(i32);
}
virtual uint32_t readI64_virt(int64_t& i64)
{
return protocol->readI64(i64);
}
virtual uint32_t readDouble_virt(double& dub)
{
return protocol->readDouble(dub);
}
virtual uint32_t readString_virt(std::string& str)
{
return protocol->readString(str);
}
virtual uint32_t readBinary_virt(std::string& str)
{
return protocol->readBinary(str);
}
private:
shared_ptr<TProtocol> protocol;
};
}
}
}

View File

@ -1,130 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
namespace apache
{
namespace thrift
{
namespace protocol
{
/**
* Class to encapsulate all the possible types of protocol errors that may
* occur in various protocol systems. This provides a sort of generic
* wrapper around the vague UNIX E_ error codes that lets a common code
* base of error handling to be used for various types of protocols, i.e.
* pipes etc.
*
*/
class TProtocolException : public apache::thrift::TException
{
public:
/**
* Error codes for the various types of exceptions.
*/
enum TProtocolExceptionType
{
UNKNOWN = 0
, INVALID_DATA = 1
, NEGATIVE_SIZE = 2
, SIZE_LIMIT = 3
, BAD_VERSION = 4
, NOT_IMPLEMENTED = 5
};
TProtocolException() :
apache::thrift::TException(),
type_(UNKNOWN) {}
TProtocolException(TProtocolExceptionType type) :
apache::thrift::TException(),
type_(type) {}
TProtocolException(const std::string& message) :
apache::thrift::TException(message),
type_(UNKNOWN) {}
TProtocolException(TProtocolExceptionType type, const std::string& message) :
apache::thrift::TException(message),
type_(type) {}
virtual ~TProtocolException() throw() {}
/**
* Returns an error code that provides information about the type of error
* that has occurred.
*
* @return Error code
*/
TProtocolExceptionType getType()
{
return type_;
}
virtual const char* what() const throw()
{
if (message_.empty())
{
switch (type_)
{
case UNKNOWN :
return "TProtocolException: Unknown protocol exception";
case INVALID_DATA :
return "TProtocolException: Invalid data";
case NEGATIVE_SIZE :
return "TProtocolException: Negative size";
case SIZE_LIMIT :
return "TProtocolException: Exceeded size limit";
case BAD_VERSION :
return "TProtocolException: Invalid version";
case NOT_IMPLEMENTED :
return "TProtocolException: Not implemented";
default :
return "TProtocolException: (Invalid exception type)";
}
}
else
{
return message_.c_str();
}
}
protected:
/**
* Error code
*/
TProtocolExceptionType type_;
};
}
}
} // apache::thrift::protocol

View File

@ -1,219 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TVirtualProtocol.h>
namespace apache
{
namespace thrift
{
namespace protocol
{
using apache::thrift::transport::TTransport;
/**
* Puts a wiretap on a protocol object. Any reads to this class are passed
* through to an enclosed protocol object, but also mirrored as write to a
* second protocol object.
*
*/
class TProtocolTap : public TVirtualProtocol<TProtocolTap>
{
public:
TProtocolTap(boost::shared_ptr<TProtocol> source,
boost::shared_ptr<TProtocol> sink)
: TVirtualProtocol<TProtocolTap>(source->getTransport())
, source_(source)
, sink_(sink)
{}
uint32_t readMessageBegin(std::string& name,
TMessageType& messageType,
int32_t& seqid)
{
uint32_t rv = source_->readMessageBegin(name, messageType, seqid);
sink_->writeMessageBegin(name, messageType, seqid);
return rv;
}
uint32_t readMessageEnd()
{
uint32_t rv = source_->readMessageEnd();
sink_->writeMessageEnd();
return rv;
}
uint32_t readStructBegin(std::string& name)
{
uint32_t rv = source_->readStructBegin(name);
sink_->writeStructBegin(name.c_str());
return rv;
}
uint32_t readStructEnd()
{
uint32_t rv = source_->readStructEnd();
sink_->writeStructEnd();
return rv;
}
uint32_t readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId)
{
uint32_t rv = source_->readFieldBegin(name, fieldType, fieldId);
if (fieldType == T_STOP)
{
sink_->writeFieldStop();
}
else
{
sink_->writeFieldBegin(name.c_str(), fieldType, fieldId);
}
return rv;
}
uint32_t readFieldEnd()
{
uint32_t rv = source_->readFieldEnd();
sink_->writeFieldEnd();
return rv;
}
uint32_t readMapBegin(TType& keyType,
TType& valType,
uint32_t& size)
{
uint32_t rv = source_->readMapBegin(keyType, valType, size);
sink_->writeMapBegin(keyType, valType, size);
return rv;
}
uint32_t readMapEnd()
{
uint32_t rv = source_->readMapEnd();
sink_->writeMapEnd();
return rv;
}
uint32_t readListBegin(TType& elemType, uint32_t& size)
{
uint32_t rv = source_->readListBegin(elemType, size);
sink_->writeListBegin(elemType, size);
return rv;
}
uint32_t readListEnd()
{
uint32_t rv = source_->readListEnd();
sink_->writeListEnd();
return rv;
}
uint32_t readSetBegin(TType& elemType, uint32_t& size)
{
uint32_t rv = source_->readSetBegin(elemType, size);
sink_->writeSetBegin(elemType, size);
return rv;
}
uint32_t readSetEnd()
{
uint32_t rv = source_->readSetEnd();
sink_->writeSetEnd();
return rv;
}
uint32_t readBool(bool& value)
{
uint32_t rv = source_->readBool(value);
sink_->writeBool(value);
return rv;
}
// Provide the default readBool() implementation for std::vector<bool>
using TVirtualProtocol<TProtocolTap>::readBool;
uint32_t readByte(int8_t& byte)
{
uint32_t rv = source_->readByte(byte);
sink_->writeByte(byte);
return rv;
}
uint32_t readI16(int16_t& i16)
{
uint32_t rv = source_->readI16(i16);
sink_->writeI16(i16);
return rv;
}
uint32_t readI32(int32_t& i32)
{
uint32_t rv = source_->readI32(i32);
sink_->writeI32(i32);
return rv;
}
uint32_t readI64(int64_t& i64)
{
uint32_t rv = source_->readI64(i64);
sink_->writeI64(i64);
return rv;
}
uint32_t readDouble(double& dub)
{
uint32_t rv = source_->readDouble(dub);
sink_->writeDouble(dub);
return rv;
}
uint32_t readString(std::string& str)
{
uint32_t rv = source_->readString(str);
sink_->writeString(str);
return rv;
}
uint32_t readBinary(std::string& str)
{
uint32_t rv = source_->readBinary(str);
sink_->writeBinary(str);
return rv;
}
private:
boost::shared_ptr<TProtocol> source_;
boost::shared_ptr<TProtocol> sink_;
};
}
}
} // apache::thrift::protocol

View File

@ -1,659 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/protocol/TProtocol.h>
namespace apache
{
namespace thrift
{
namespace protocol
{
using apache::thrift::transport::TTransport;
/**
* Helper class that provides default implementations of TProtocol methods.
*
* This class provides default implementations of the non-virtual TProtocol
* methods. It exists primarily so TVirtualProtocol can derive from it. It
* prevents TVirtualProtocol methods from causing infinite recursion if the
* non-virtual methods are not overridden by the TVirtualProtocol subclass.
*
* You probably don't want to use this class directly. Use TVirtualProtocol
* instead.
*/
class TProtocolDefaults : public TProtocol
{
public:
uint32_t readMessageBegin(std::string& name,
TMessageType& messageType,
int32_t& seqid)
{
(void) name;
(void) messageType;
(void) seqid;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readMessageEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readStructBegin(std::string& name)
{
(void) name;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readStructEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readFieldBegin(std::string& name,
TType& fieldType,
int16_t& fieldId)
{
(void) name;
(void) fieldType;
(void) fieldId;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readFieldEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size)
{
(void) keyType;
(void) valType;
(void) size;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readMapEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readListBegin(TType& elemType, uint32_t& size)
{
(void) elemType;
(void) size;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readListEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readSetBegin(TType& elemType, uint32_t& size)
{
(void) elemType;
(void) size;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readSetEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readBool(bool& value)
{
(void) value;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readBool(std::vector<bool>::reference value)
{
(void) value;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readByte(int8_t& byte)
{
(void) byte;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readI16(int16_t& i16)
{
(void) i16;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readI32(int32_t& i32)
{
(void) i32;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readI64(int64_t& i64)
{
(void) i64;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readDouble(double& dub)
{
(void) dub;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readString(std::string& str)
{
(void) str;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t readBinary(std::string& str)
{
(void) str;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support reading (yet).");
}
uint32_t writeMessageBegin(const std::string& name,
const TMessageType messageType,
const int32_t seqid)
{
(void) name;
(void) messageType;
(void) seqid;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeMessageEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeStructBegin(const char* name)
{
(void) name;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeStructEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeFieldBegin(const char* name,
const TType fieldType,
const int16_t fieldId)
{
(void) name;
(void) fieldType;
(void) fieldId;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeFieldEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeFieldStop()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeMapBegin(const TType keyType,
const TType valType,
const uint32_t size)
{
(void) keyType;
(void) valType;
(void) size;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeMapEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeListBegin(const TType elemType, const uint32_t size)
{
(void) elemType;
(void) size;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeListEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeSetBegin(const TType elemType, const uint32_t size)
{
(void) elemType;
(void) size;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeSetEnd()
{
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeBool(const bool value)
{
(void) value;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeByte(const int8_t byte)
{
(void) byte;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeI16(const int16_t i16)
{
(void) i16;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeI32(const int32_t i32)
{
(void) i32;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeI64(const int64_t i64)
{
(void) i64;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeDouble(const double dub)
{
(void) dub;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeString(const std::string& str)
{
(void) str;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t writeBinary(const std::string& str)
{
(void) str;
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
"this protocol does not support writing (yet).");
}
uint32_t skip(TType type)
{
return ::apache::thrift::protocol::skip(*this, type);
}
protected:
TProtocolDefaults(boost::shared_ptr<TTransport> ptrans)
: TProtocol(ptrans)
{}
};
/**
* Concrete TProtocol classes should inherit from TVirtualProtocol
* so they don't have to manually override virtual methods.
*/
template <class Protocol_, class Super_ = TProtocolDefaults>
class TVirtualProtocol : public Super_
{
public:
/**
* Writing functions.
*/
virtual uint32_t writeMessageBegin_virt(const std::string& name,
const TMessageType messageType,
const int32_t seqid)
{
return static_cast<Protocol_*>(this)->writeMessageBegin(name, messageType,
seqid);
}
virtual uint32_t writeMessageEnd_virt()
{
return static_cast<Protocol_*>(this)->writeMessageEnd();
}
virtual uint32_t writeStructBegin_virt(const char* name)
{
return static_cast<Protocol_*>(this)->writeStructBegin(name);
}
virtual uint32_t writeStructEnd_virt()
{
return static_cast<Protocol_*>(this)->writeStructEnd();
}
virtual uint32_t writeFieldBegin_virt(const char* name,
const TType fieldType,
const int16_t fieldId)
{
return static_cast<Protocol_*>(this)->writeFieldBegin(name, fieldType,
fieldId);
}
virtual uint32_t writeFieldEnd_virt()
{
return static_cast<Protocol_*>(this)->writeFieldEnd();
}
virtual uint32_t writeFieldStop_virt()
{
return static_cast<Protocol_*>(this)->writeFieldStop();
}
virtual uint32_t writeMapBegin_virt(const TType keyType,
const TType valType,
const uint32_t size)
{
return static_cast<Protocol_*>(this)->writeMapBegin(keyType, valType, size);
}
virtual uint32_t writeMapEnd_virt()
{
return static_cast<Protocol_*>(this)->writeMapEnd();
}
virtual uint32_t writeListBegin_virt(const TType elemType,
const uint32_t size)
{
return static_cast<Protocol_*>(this)->writeListBegin(elemType, size);
}
virtual uint32_t writeListEnd_virt()
{
return static_cast<Protocol_*>(this)->writeListEnd();
}
virtual uint32_t writeSetBegin_virt(const TType elemType,
const uint32_t size)
{
return static_cast<Protocol_*>(this)->writeSetBegin(elemType, size);
}
virtual uint32_t writeSetEnd_virt()
{
return static_cast<Protocol_*>(this)->writeSetEnd();
}
virtual uint32_t writeBool_virt(const bool value)
{
return static_cast<Protocol_*>(this)->writeBool(value);
}
virtual uint32_t writeByte_virt(const int8_t byte)
{
return static_cast<Protocol_*>(this)->writeByte(byte);
}
virtual uint32_t writeI16_virt(const int16_t i16)
{
return static_cast<Protocol_*>(this)->writeI16(i16);
}
virtual uint32_t writeI32_virt(const int32_t i32)
{
return static_cast<Protocol_*>(this)->writeI32(i32);
}
virtual uint32_t writeI64_virt(const int64_t i64)
{
return static_cast<Protocol_*>(this)->writeI64(i64);
}
virtual uint32_t writeDouble_virt(const double dub)
{
return static_cast<Protocol_*>(this)->writeDouble(dub);
}
virtual uint32_t writeString_virt(const std::string& str)
{
return static_cast<Protocol_*>(this)->writeString(str);
}
virtual uint32_t writeBinary_virt(const std::string& str)
{
return static_cast<Protocol_*>(this)->writeBinary(str);
}
/**
* Reading functions
*/
virtual uint32_t readMessageBegin_virt(std::string& name,
TMessageType& messageType,
int32_t& seqid)
{
return static_cast<Protocol_*>(this)->readMessageBegin(name, messageType,
seqid);
}
virtual uint32_t readMessageEnd_virt()
{
return static_cast<Protocol_*>(this)->readMessageEnd();
}
virtual uint32_t readStructBegin_virt(std::string& name)
{
return static_cast<Protocol_*>(this)->readStructBegin(name);
}
virtual uint32_t readStructEnd_virt()
{
return static_cast<Protocol_*>(this)->readStructEnd();
}
virtual uint32_t readFieldBegin_virt(std::string& name,
TType& fieldType,
int16_t& fieldId)
{
return static_cast<Protocol_*>(this)->readFieldBegin(name, fieldType,
fieldId);
}
virtual uint32_t readFieldEnd_virt()
{
return static_cast<Protocol_*>(this)->readFieldEnd();
}
virtual uint32_t readMapBegin_virt(TType& keyType,
TType& valType,
uint32_t& size)
{
return static_cast<Protocol_*>(this)->readMapBegin(keyType, valType, size);
}
virtual uint32_t readMapEnd_virt()
{
return static_cast<Protocol_*>(this)->readMapEnd();
}
virtual uint32_t readListBegin_virt(TType& elemType,
uint32_t& size)
{
return static_cast<Protocol_*>(this)->readListBegin(elemType, size);
}
virtual uint32_t readListEnd_virt()
{
return static_cast<Protocol_*>(this)->readListEnd();
}
virtual uint32_t readSetBegin_virt(TType& elemType,
uint32_t& size)
{
return static_cast<Protocol_*>(this)->readSetBegin(elemType, size);
}
virtual uint32_t readSetEnd_virt()
{
return static_cast<Protocol_*>(this)->readSetEnd();
}
virtual uint32_t readBool_virt(bool& value)
{
return static_cast<Protocol_*>(this)->readBool(value);
}
virtual uint32_t readBool_virt(std::vector<bool>::reference value)
{
return static_cast<Protocol_*>(this)->readBool(value);
}
virtual uint32_t readByte_virt(int8_t& byte)
{
return static_cast<Protocol_*>(this)->readByte(byte);
}
virtual uint32_t readI16_virt(int16_t& i16)
{
return static_cast<Protocol_*>(this)->readI16(i16);
}
virtual uint32_t readI32_virt(int32_t& i32)
{
return static_cast<Protocol_*>(this)->readI32(i32);
}
virtual uint32_t readI64_virt(int64_t& i64)
{
return static_cast<Protocol_*>(this)->readI64(i64);
}
virtual uint32_t readDouble_virt(double& dub)
{
return static_cast<Protocol_*>(this)->readDouble(dub);
}
virtual uint32_t readString_virt(std::string& str)
{
return static_cast<Protocol_*>(this)->readString(str);
}
virtual uint32_t readBinary_virt(std::string& str)
{
return static_cast<Protocol_*>(this)->readBinary(str);
}
virtual uint32_t skip_virt(TType type)
{
return static_cast<Protocol_*>(this)->skip(type);
}
/*
* Provide a default skip() implementation that uses non-virtual read
* methods.
*
* Note: subclasses that use TVirtualProtocol to derive from another protocol
* implementation (i.e., not TProtocolDefaults) should beware that this may
* override any non-default skip() implementation provided by the parent
* transport class. They may need to explicitly redefine skip() to call the
* correct parent implementation, if desired.
*/
uint32_t skip(TType type)
{
Protocol_* const prot = static_cast<Protocol_*>(this);
return ::apache::thrift::protocol::skip(*prot, type);
}
/*
* Provide a default readBool() implementation for use with
* std::vector<bool>, that behaves the same as reading into a normal bool.
*
* Subclasses can override this if desired, but there normally shouldn't
* be a need to.
*/
uint32_t readBool(std::vector<bool>::reference value)
{
bool b = false;
uint32_t ret = static_cast<Protocol_*>(this)->readBool(b);
value = b;
return ret;
}
using Super_::readBool; // so we don't hide readBool(bool&)
protected:
TVirtualProtocol(boost::shared_ptr<TTransport> ptrans)
: Super_(ptrans)
{}
};
}
}
} // apache::thrift::protocol

View File

@ -1,70 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <thrift/transport/TVirtualTransport.h>
class QIODevice;
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Transport that operates on a QIODevice (socket, file, etc).
*/
class TQIODeviceTransport : public apache::thrift::transport::TVirtualTransport<TQIODeviceTransport>
{
public:
explicit TQIODeviceTransport(boost::shared_ptr<QIODevice> dev);
virtual ~TQIODeviceTransport();
void open();
bool isOpen();
bool peek();
void close();
uint32_t readAll(uint8_t* buf, uint32_t len);
uint32_t read(uint8_t* buf, uint32_t len);
void write(const uint8_t* buf, uint32_t len);
uint32_t write_partial(const uint8_t* buf, uint32_t len);
void flush();
uint8_t* borrow(uint8_t* buf, uint32_t* len);
void consume(uint32_t len);
private:
TQIODeviceTransport(const TQIODeviceTransport&);
TQIODeviceTransport& operator=(const TQIODeviceTransport&);
boost::shared_ptr<QIODevice> dev_;
};
}
}
} // apache::thrift::transport

View File

@ -1,85 +0,0 @@
/*
* 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.
*/
#pragma once
#include <QObject>
#include <QTcpServer>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace protocol
{
class TProtocolFactory;
}
}
} // apache::thrift::protocol
namespace apache
{
namespace thrift
{
namespace async
{
class TAsyncProcessor;
/**
* Server that uses Qt to listen for connections.
* Simply give it a QTcpServer that is listening, along with an async
* processor and a protocol factory, and then run the Qt event loop.
*/
class TQTcpServer : public QObject
{
Q_OBJECT
public:
TQTcpServer(boost::shared_ptr<QTcpServer> server,
boost::shared_ptr<TAsyncProcessor> processor,
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
QT_PREPEND_NAMESPACE(QObject)* parent = NULL);
virtual ~TQTcpServer();
private Q_SLOTS:
void processIncoming();
void beginDecode();
void socketClosed();
private:
TQTcpServer(const TQTcpServer&);
TQTcpServer& operator=(const TQTcpServer&);
class ConnectionContext;
void finish(boost::shared_ptr<ConnectionContext> ctx, bool healthy);
boost::shared_ptr<QTcpServer> server_;
boost::shared_ptr<TAsyncProcessor> processor_;
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
std::map<QT_PREPEND_NAMESPACE(QTcpSocket)*, boost::shared_ptr<ConnectionContext> > ctxMap_;
};
}
}
} // apache::thrift::async

File diff suppressed because it is too large Load Diff

View File

@ -1,343 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/TProcessor.h>
#include <thrift/transport/TServerTransport.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace server
{
using apache::thrift::TProcessor;
using apache::thrift::protocol::TBinaryProtocolFactory;
using apache::thrift::protocol::TProtocol;
using apache::thrift::protocol::TProtocolFactory;
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportFactory;
/**
* Virtual interface class that can handle events from the server core. To
* use this you should subclass it and implement the methods that you care
* about. Your subclass can also store local data that you may care about,
* such as additional "arguments" to these methods (stored in the object
* instance's state).
*/
class TServerEventHandler
{
public:
virtual ~TServerEventHandler() {}
/**
* Called before the server begins.
*/
virtual void preServe() {}
/**
* Called when a new client has connected and is about to being processing.
*/
virtual void* createContext(boost::shared_ptr<TProtocol> input,
boost::shared_ptr<TProtocol> output)
{
(void)input;
(void)output;
return NULL;
}
/**
* Called when a client has finished request-handling to delete server
* context.
*/
virtual void deleteContext(void* serverContext,
boost::shared_ptr<TProtocol>input,
boost::shared_ptr<TProtocol>output)
{
(void)serverContext;
(void)input;
(void)output;
}
/**
* Called when a client is about to call the processor.
*/
virtual void processContext(void* serverContext,
boost::shared_ptr<TTransport> transport)
{
(void)serverContext;
(void)transport;
}
protected:
/**
* Prevent direct instantiation.
*/
TServerEventHandler() {}
};
/**
* Thrift server.
*
*/
class TServer : public concurrency::Runnable
{
public:
virtual ~TServer() {}
virtual void serve() = 0;
virtual void stop() {}
// Allows running the server as a Runnable thread
virtual void run()
{
serve();
}
boost::shared_ptr<TProcessorFactory> getProcessorFactory()
{
return processorFactory_;
}
boost::shared_ptr<TServerTransport> getServerTransport()
{
return serverTransport_;
}
boost::shared_ptr<TTransportFactory> getInputTransportFactory()
{
return inputTransportFactory_;
}
boost::shared_ptr<TTransportFactory> getOutputTransportFactory()
{
return outputTransportFactory_;
}
boost::shared_ptr<TProtocolFactory> getInputProtocolFactory()
{
return inputProtocolFactory_;
}
boost::shared_ptr<TProtocolFactory> getOutputProtocolFactory()
{
return outputProtocolFactory_;
}
boost::shared_ptr<TServerEventHandler> getEventHandler()
{
return eventHandler_;
}
protected:
template<typename ProcessorFactory>
TServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)):
processorFactory_(processorFactory)
{
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(
new TTransportFactory()));
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(
new TTransportFactory()));
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(
new TBinaryProtocolFactory()));
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(
new TBinaryProtocolFactory()));
}
template<typename Processor>
TServer(const boost::shared_ptr<Processor>& processor,
THRIFT_OVERLOAD_IF(Processor, TProcessor)):
processorFactory_(new TSingletonProcessorFactory(processor))
{
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
template<typename ProcessorFactory>
TServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)):
processorFactory_(processorFactory),
serverTransport_(serverTransport)
{
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(
new TTransportFactory()));
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(
new TTransportFactory()));
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(
new TBinaryProtocolFactory()));
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(
new TBinaryProtocolFactory()));
}
template<typename Processor>
TServer(const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
THRIFT_OVERLOAD_IF(Processor, TProcessor)):
processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport)
{
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
template<typename ProcessorFactory>
TServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)):
processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
outputTransportFactory_(transportFactory),
inputProtocolFactory_(protocolFactory),
outputProtocolFactory_(protocolFactory) {}
template<typename Processor>
TServer(const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(Processor, TProcessor)):
processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
outputTransportFactory_(transportFactory),
inputProtocolFactory_(protocolFactory),
outputProtocolFactory_(protocolFactory) {}
template<typename ProcessorFactory>
TServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)):
processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(inputTransportFactory),
outputTransportFactory_(outputTransportFactory),
inputProtocolFactory_(inputProtocolFactory),
outputProtocolFactory_(outputProtocolFactory) {}
template<typename Processor>
TServer(const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
THRIFT_OVERLOAD_IF(Processor, TProcessor)):
processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport),
inputTransportFactory_(inputTransportFactory),
outputTransportFactory_(outputTransportFactory),
inputProtocolFactory_(inputProtocolFactory),
outputProtocolFactory_(outputProtocolFactory) {}
/**
* Get a TProcessor to handle calls on a particular connection.
*
* This method should only be called once per connection (never once per
* call). This allows the TProcessorFactory to return a different processor
* for each connection if it desires.
*/
boost::shared_ptr<TProcessor> getProcessor(
boost::shared_ptr<TProtocol> inputProtocol,
boost::shared_ptr<TProtocol> outputProtocol,
boost::shared_ptr<TTransport> transport)
{
TConnectionInfo connInfo;
connInfo.input = inputProtocol;
connInfo.output = outputProtocol;
connInfo.transport = transport;
return processorFactory_->getProcessor(connInfo);
}
// Class variables
boost::shared_ptr<TProcessorFactory> processorFactory_;
boost::shared_ptr<TServerTransport> serverTransport_;
boost::shared_ptr<TTransportFactory> inputTransportFactory_;
boost::shared_ptr<TTransportFactory> outputTransportFactory_;
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;
boost::shared_ptr<TServerEventHandler> eventHandler_;
public:
void setInputTransportFactory(boost::shared_ptr<TTransportFactory> inputTransportFactory)
{
inputTransportFactory_ = inputTransportFactory;
}
void setOutputTransportFactory(boost::shared_ptr<TTransportFactory> outputTransportFactory)
{
outputTransportFactory_ = outputTransportFactory;
}
void setInputProtocolFactory(boost::shared_ptr<TProtocolFactory> inputProtocolFactory)
{
inputProtocolFactory_ = inputProtocolFactory;
}
void setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory> outputProtocolFactory)
{
outputProtocolFactory_ = outputProtocolFactory;
}
void setServerEventHandler(boost::shared_ptr<TServerEventHandler> eventHandler)
{
eventHandler_ = eventHandler;
}
};
/**
* Helper function to increase the max file descriptors limit
* for the current process and all of its children.
* By default, tries to increase it to as much as 2^24.
*/
int increase_max_fds(int max_fds = (1 << 24));
}
}
} // apache::thrift::server

View File

@ -1,240 +0,0 @@
/*
* 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.
*/
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TTransportException.h>
#include <string>
#include <iostream>
namespace apache
{
namespace thrift
{
namespace server
{
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using boost::shared_ptr;
/**
* A simple single-threaded application server. Perfect for unit tests!
*
*/
void TSimpleServer::serve()
{
shared_ptr<TTransport> client;
shared_ptr<TTransport> inputTransport;
shared_ptr<TTransport> outputTransport;
shared_ptr<TProtocol> inputProtocol;
shared_ptr<TProtocol> outputProtocol;
// Start the server listening
serverTransport_->listen();
// Run the preServe event
if (eventHandler_)
{
eventHandler_->preServe();
}
// Fetch client from server
while (!stop_)
{
try
{
client = serverTransport_->accept();
inputTransport = inputTransportFactory_->getTransport(client);
outputTransport = outputTransportFactory_->getTransport(client);
inputProtocol = inputProtocolFactory_->getProtocol(inputTransport);
outputProtocol = outputProtocolFactory_->getProtocol(outputTransport);
}
catch (TTransportException& ttx)
{
if (inputTransport)
{
inputTransport->close();
}
if (outputTransport)
{
outputTransport->close();
}
if (client)
{
client->close();
}
if (!stop_ || ttx.getType() != TTransportException::INTERRUPTED)
{
string errStr = string("TServerTransport died on accept: ") + ttx.what();
GlobalOutput(errStr.c_str());
}
continue;
}
catch (TException& tx)
{
if (inputTransport)
{
inputTransport->close();
}
if (outputTransport)
{
outputTransport->close();
}
if (client)
{
client->close();
}
string errStr = string("Some kind of accept exception: ") + tx.what();
GlobalOutput(errStr.c_str());
continue;
}
catch (string s)
{
if (inputTransport)
{
inputTransport->close();
}
if (outputTransport)
{
outputTransport->close();
}
if (client)
{
client->close();
}
string errStr = string("Some kind of accept exception: ") + s;
GlobalOutput(errStr.c_str());
break;
}
// Get the processor
shared_ptr<TProcessor> processor = getProcessor(inputProtocol,
outputProtocol, client);
void* connectionContext = NULL;
if (eventHandler_)
{
connectionContext = eventHandler_->createContext(inputProtocol, outputProtocol);
}
try
{
for (;;)
{
if (eventHandler_)
{
eventHandler_->processContext(connectionContext, client);
}
if (!processor->process(inputProtocol, outputProtocol,
connectionContext) ||
// Peek ahead, is the remote side closed?
!inputProtocol->getTransport()->peek())
{
break;
}
}
}
catch (const TTransportException& ttx)
{
string errStr = string("TSimpleServer client died: ") + ttx.what();
GlobalOutput(errStr.c_str());
}
catch (const std::exception& x)
{
GlobalOutput.printf("TSimpleServer exception: %s: %s",
typeid(x).name(), x.what());
}
catch (...)
{
GlobalOutput("TSimpleServer uncaught exception.");
}
if (eventHandler_)
{
eventHandler_->deleteContext(connectionContext, inputProtocol, outputProtocol);
}
try
{
inputTransport->close();
}
catch (const TTransportException& ttx)
{
string errStr = string("TSimpleServer input close failed: ")
+ ttx.what();
GlobalOutput(errStr.c_str());
}
try
{
outputTransport->close();
}
catch (const TTransportException& ttx)
{
string errStr = string("TSimpleServer output close failed: ")
+ ttx.what();
GlobalOutput(errStr.c_str());
}
try
{
client->close();
}
catch (const TTransportException& ttx)
{
string errStr = string("TSimpleServer client close failed: ")
+ ttx.what();
GlobalOutput(errStr.c_str());
}
}
if (stop_)
{
try
{
serverTransport_->close();
}
catch (TTransportException& ttx)
{
string errStr = string("TServerTransport failed on close: ") + ttx.what();
GlobalOutput(errStr.c_str());
}
stop_ = false;
}
}
}
}
} // apache::thrift::server

View File

@ -1,109 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/server/TServer.h>
#include <thrift/transport/TServerTransport.h>
namespace apache
{
namespace thrift
{
namespace server
{
/**
* This is the most basic simple server. It is single-threaded and runs a
* continuous loop of accepting a single connection, processing requests on
* that connection until it closes, and then repeating. It is a good example
* of how to extend the TServer interface.
*
*/
class TSimpleServer : public TServer
{
public:
template<typename ProcessorFactory>
TSimpleServer(
const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)) :
TServer(processorFactory, serverTransport, transportFactory,
protocolFactory),
stop_(false) {}
template<typename Processor>
TSimpleServer(
const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(Processor, TProcessor)) :
TServer(processor, serverTransport, transportFactory, protocolFactory),
stop_(false) {}
template<typename ProcessorFactory>
TSimpleServer(
const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)) :
TServer(processorFactory, serverTransport,
inputTransportFactory, outputTransportFactory,
inputProtocolFactory, outputProtocolFactory),
stop_(false) {}
template<typename Processor>
TSimpleServer(
const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
THRIFT_OVERLOAD_IF(Processor, TProcessor)) :
TServer(processor, serverTransport,
inputTransportFactory, outputTransportFactory,
inputProtocolFactory, outputProtocolFactory),
stop_(false) {}
~TSimpleServer() {}
void serve();
void stop()
{
stop_ = true;
serverTransport_->interrupt();
}
protected:
bool stop_;
};
}
}
} // apache::thrift::server

View File

@ -1,143 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/server/TServer.h>
#include <thrift/transport/TServerTransport.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace server
{
using apache::thrift::concurrency::ThreadManager;
using apache::thrift::protocol::TProtocolFactory;
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransportFactory;
class TThreadPoolServer : public TServer
{
public:
class Task;
template<typename ProcessorFactory>
TThreadPoolServer(
const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
const boost::shared_ptr<ThreadManager>& threadManager,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)) :
TServer(processorFactory, serverTransport, transportFactory,
protocolFactory),
threadManager_(threadManager),
stop_(false),
timeout_(0),
taskExpiration_(0) {}
template<typename Processor>
TThreadPoolServer(
const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
const boost::shared_ptr<ThreadManager>& threadManager,
THRIFT_OVERLOAD_IF(Processor, TProcessor)) :
TServer(processor, serverTransport, transportFactory, protocolFactory),
threadManager_(threadManager),
stop_(false),
timeout_(0),
taskExpiration_(0) {}
template<typename ProcessorFactory>
TThreadPoolServer(
const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
const boost::shared_ptr<ThreadManager>& threadManager,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)) :
TServer(processorFactory, serverTransport,
inputTransportFactory, outputTransportFactory,
inputProtocolFactory, outputProtocolFactory),
threadManager_(threadManager),
stop_(false),
timeout_(0),
taskExpiration_(0) {}
template<typename Processor>
TThreadPoolServer(
const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
const boost::shared_ptr<ThreadManager>& threadManager,
THRIFT_OVERLOAD_IF(Processor, TProcessor)) :
TServer(processor, serverTransport,
inputTransportFactory, outputTransportFactory,
inputProtocolFactory, outputProtocolFactory),
threadManager_(threadManager),
stop_(false),
timeout_(0),
taskExpiration_(0) {}
virtual ~TThreadPoolServer();
virtual void serve();
virtual int64_t getTimeout() const;
virtual void setTimeout(int64_t value);
virtual void stop()
{
stop_ = true;
serverTransport_->interrupt();
}
virtual int64_t getTaskExpiration() const;
virtual void setTaskExpiration(int64_t value);
protected:
boost::shared_ptr<ThreadManager> threadManager_;
volatile bool stop_;
volatile int64_t timeout_;
volatile int64_t taskExpiration_;
};
}
}
} // apache::thrift::server

View File

@ -1,156 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/server/TServer.h>
#include <thrift/transport/TServerTransport.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace server
{
using apache::thrift::TProcessor;
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransportFactory;
using apache::thrift::concurrency::Monitor;
using apache::thrift::concurrency::ThreadFactory;
class TThreadedServer : public TServer
{
public:
class Task;
template<typename ProcessorFactory>
TThreadedServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory));
template<typename ProcessorFactory>
TThreadedServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
const boost::shared_ptr<ThreadFactory>& threadFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory));
template<typename Processor>
TThreadedServer(const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(Processor, TProcessor));
template<typename Processor>
TThreadedServer(const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
const boost::shared_ptr<ThreadFactory>& threadFactory,
THRIFT_OVERLOAD_IF(Processor, TProcessor));
virtual ~TThreadedServer();
virtual void serve();
void stop()
{
stop_ = true;
serverTransport_->interrupt();
}
protected:
void init();
boost::shared_ptr<ThreadFactory> threadFactory_;
volatile bool stop_;
Monitor tasksMonitor_;
std::set<Task*> tasks_;
};
template<typename ProcessorFactory>
TThreadedServer::TThreadedServer(
const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF_DEFN(ProcessorFactory, TProcessorFactory)) :
TServer(processorFactory, serverTransport, transportFactory,
protocolFactory)
{
init();
}
template<typename ProcessorFactory>
TThreadedServer::TThreadedServer(
const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
const boost::shared_ptr<ThreadFactory>& threadFactory,
THRIFT_OVERLOAD_IF_DEFN(ProcessorFactory, TProcessorFactory)) :
TServer(processorFactory, serverTransport, transportFactory,
protocolFactory),
threadFactory_(threadFactory)
{
init();
}
template<typename Processor>
TThreadedServer::TThreadedServer(
const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF_DEFN(Processor, TProcessor)) :
TServer(processor, serverTransport, transportFactory, protocolFactory)
{
init();
}
template<typename Processor>
TThreadedServer::TThreadedServer(
const boost::shared_ptr<Processor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
const boost::shared_ptr<ThreadFactory>& threadFactory,
THRIFT_OVERLOAD_IF_DEFN(Processor, TProcessor)) :
TServer(processor, serverTransport, transportFactory, protocolFactory),
threadFactory_(threadFactory)
{
init();
}
}
}
} // apache::thrift::server

View File

@ -1,425 +0,0 @@
/* lib/cpp/src/thrift/config.h. Generated from config.hin by configure. */
/* config.hin. Generated from configure.ac by autoheader. */
#pragma once
/* Define if the AI_ADDRCONFIG symbol is unavailable */
/* #undef AI_ADDRCONFIG */
/* Possible value for SIGNED_RIGHT_SHIFT_IS */
#define ARITHMETIC_RIGHT_SHIFT 1
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if you have the `alarm' function. */
#define HAVE_ALARM 1
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* define if the Boost library is available */
#define HAVE_BOOST /**/
/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1
/* Define to 1 if you have the `clock_gettime' function. */
#define HAVE_CLOCK_GETTIME 1
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
don't. */
#define HAVE_DECL_STRERROR_R 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `fork' function. */
#define HAVE_FORK 1
/* Define to 1 if you have the `ftruncate' function. */
#define HAVE_FTRUNCATE 1
/* Define to 1 if you have the `gethostbyname' function. */
#define HAVE_GETHOSTBYNAME 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* define if libevent is available */
/* #undef HAVE_LIBEVENT */
/* Define to 1 if you have the <libintl.h> header file. */
#define HAVE_LIBINTL_H 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1
/* Define to 1 if you have the `rt' library (-lrt). */
#define HAVE_LIBRT 1
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `mkdir' function. */
#define HAVE_MKDIR 1
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <openssl/rand.h> header file. */
#define HAVE_OPENSSL_RAND_H 1
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#define HAVE_OPENSSL_SSL_H 1
/* Define to 1 if you have the <openssl/x509v3.h> header file. */
#define HAVE_OPENSSL_X509V3_H 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Define to 1 if the system has the type `ptrdiff_t'. */
#define HAVE_PTRDIFF_T 1
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC 1
/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1
/* Define to 1 if you have the `sched_get_priority_max' function. */
#define HAVE_SCHED_GET_PRIORITY_MAX 1
/* Define to 1 if you have the `sched_get_priority_min' function. */
#define HAVE_SCHED_GET_PRIORITY_MIN 1
/* Define to 1 if you have the <sched.h> header file. */
#define HAVE_SCHED_H 1
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the `sqrt' function. */
#define HAVE_SQRT 1
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
/* Define to 1 if stdbool.h conforms to C99. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the `strerror_r' function. */
#define HAVE_STRERROR_R 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/poll.h> header file. */
#define HAVE_SYS_POLL_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `vfork' function. */
#define HAVE_VFORK 1
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1
/* Define to 1 if you have the <wchar.h> header file. */
#define HAVE_WCHAR_H 1
/* Define to 1 if `fork' works. */
#define HAVE_WORKING_FORK 1
/* Define to 1 if `vfork' works. */
#define HAVE_WORKING_VFORK 1
/* define if zlib is available */
#define HAVE_ZLIB /**/
/* Define to 1 if the system has the type `_Bool'. */
/* #undef HAVE__BOOL */
/* Possible value for SIGNED_RIGHT_SHIFT_IS */
#define LOGICAL_RIGHT_SHIFT 2
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "thrift"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "thrift"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "thrift 0.9.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "thrift"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.9.1"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to the type of arg 1 for `select'. */
#define SELECT_TYPE_ARG1 int
/* Define to the type of args 2, 3 and 4 for `select'. */
#define SELECT_TYPE_ARG234 (fd_set *)
/* Define to the type of arg 5 for `select'. */
#define SELECT_TYPE_ARG5 (struct timeval *)
/* Indicates the effect of the right shift operator on negative signed
integers */
#define SIGNED_RIGHT_SHIFT_IS 1
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if strerror_r returns char *. */
#define STRERROR_R_CHAR_P 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */
/* Possible value for SIGNED_RIGHT_SHIFT_IS */
#define UNKNOWN_RIGHT_SHIFT 3
/* experimental --enable-boostthreads that replaces POSIX pthread by
boost::thread */
/* #undef USE_BOOST_THREAD */
/* Version number of package */
#define VERSION "0.9.1"
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#define YYTEXT_POINTER 1
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT32_T */
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT64_T */
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to the type of a signed integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
/* #undef int16_t */
/* Define to the type of a signed integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef int32_t */
/* Define to the type of a signed integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef int64_t */
/* Define to the type of a signed integer type of width exactly 8 bits if such
a type exists and the standard includes do not define it. */
/* #undef int8_t */
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef mode_t */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
/* Define to the type of an unsigned integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint16_t */
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint32_t */
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint64_t */
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */
/* Define as `fork' if `vfork' does not work. */
/* #undef vfork */
/* Define to empty if the keyword `volatile' does not work. Warning: valid
code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */

View File

@ -1,94 +0,0 @@
/*
* 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.
*/
#pragma once
#ifdef _WIN32
# define THRIFT_GET_SOCKET_ERROR ::WSAGetLastError()
# define THRIFT_EINPROGRESS WSAEINPROGRESS
# define THRIFT_EAGAIN WSAEWOULDBLOCK
# define THRIFT_EINTR WSAEINTR
# define THRIFT_ECONNRESET WSAECONNRESET
# define THRIFT_ENOTCONN WSAENOTCONN
# define THRIFT_ETIMEDOUT WSAETIMEDOUT
# define THRIFT_EWOULDBLOCK WSAEWOULDBLOCK
# define THRIFT_EPIPE WSAECONNRESET
# define THRIFT_NO_SOCKET_CACHING SO_EXCLUSIVEADDRUSE
# define THRIFT_SOCKET SOCKET
# define THRIFT_INVALID_SOCKET INVALID_SOCKET
# define THRIFT_SOCKETPAIR thrift_socketpair
# define THRIFT_FCNTL thrift_fcntl
# define THRIFT_O_NONBLOCK 1
# define THRIFT_F_GETFL 0
# define THRIFT_F_SETFL 1
# define THRIFT_GETTIMEOFDAY thrift_gettimeofday
# define THRIFT_CLOSESOCKET closesocket
# define THRIFT_GAI_STRERROR gai_strerrorA
# define THRIFT_SSIZET ptrdiff_t
# define THRIFT_SNPRINTF _snprintf
# define THRIFT_SLEEP_SEC thrift_sleep
# define THRIFT_SLEEP_USEC thrift_usleep
# define THRIFT_TIMESPEC thrift_timespec
# define THRIFT_CTIME_R thrift_ctime_r
# define THRIFT_POLL thrift_poll
# if WINVER <= 0x0502 //XP, Server2003
# define THRIFT_POLLFD thrift_pollfd
# define THRIFT_POLLIN 0x0300
# define THRIFT_POLLOUT 0x0010
# else //Vista, Win7...
# define THRIFT_POLLFD pollfd
# define THRIFT_POLLIN POLLIN
# define THRIFT_POLLOUT POLLOUT
# endif //WINVER
# define THRIFT_SHUT_RDWR SD_BOTH
#else //not _WIN32
# include <errno.h>
# define THRIFT_GET_SOCKET_ERROR errno
# define THRIFT_EINTR EINTR
# define THRIFT_EINPROGRESS EINPROGRESS
# define THRIFT_ECONNRESET ECONNRESET
# define THRIFT_ENOTCONN ENOTCONN
# define THRIFT_ETIMEDOUT ETIMEDOUT
# define THRIFT_EWOULDBLOCK EWOULDBLOCK
# define THRIFT_EAGAIN EAGAIN
# define THRIFT_EPIPE EPIPE
# define THRIFT_NO_SOCKET_CACHING SO_REUSEADDR
# define THRIFT_SOCKET int
# define THRIFT_INVALID_SOCKET (-1)
# define THRIFT_SOCKETPAIR socketpair
# define THRIFT_FCNTL fcntl
# define THRIFT_O_NONBLOCK O_NONBLOCK
# define THRIFT_F_GETFL F_GETFL
# define THRIFT_F_SETFL F_SETFL
# define THRIFT_GETTIMEOFDAY gettimeofday
# define THRIFT_CLOSESOCKET close
# define THRIFT_GAI_STRERROR gai_strerror
# define THRIFT_SSIZET ssize_t
# define THRIFT_SNPRINTF snprintf
# define THRIFT_SLEEP_SEC sleep
# define THRIFT_SLEEP_USEC usleep
# define THRIFT_TIMESPEC timespec
# define THRIFT_CTIME_R ctime_r
# define THRIFT_POLL poll
# define THRIFT_POLLFD pollfd
# define THRIFT_POLLIN POLLIN
# define THRIFT_POLLOUT POLLOUT
# define THRIFT_SHUT_RDWR SHUT_RDWR
#endif

View File

@ -1,455 +0,0 @@
/*
* 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.
*/
#include <cassert>
#include <algorithm>
#include <thrift/transport/TBufferTransports.h>
using std::string;
namespace apache
{
namespace thrift
{
namespace transport
{
uint32_t TBufferedTransport::readSlow(uint8_t* buf, uint32_t len)
{
uint32_t have = static_cast<uint32_t>(rBound_ - rBase_);
// We should only take the slow path if we can't satisfy the read
// with the data already in the buffer.
assert(have < len);
// If we have some data in the buffer, copy it out and return it.
// We have to return it without attempting to read more, since we aren't
// guaranteed that the underlying transport actually has more data, so
// attempting to read from it could block.
if (have > 0)
{
memcpy(buf, rBase_, have);
setReadBuffer(rBuf_.get(), 0);
return have;
}
// No data is available in our buffer.
// Get more from underlying transport up to buffer size.
// Note that this makes a lot of sense if len < rBufSize_
// and almost no sense otherwise. TODO(dreiss): Fix that
// case (possibly including some readv hotness).
setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));
// Hand over whatever we have.
uint32_t give = (std::min)(len, static_cast<uint32_t>(rBound_ - rBase_));
memcpy(buf, rBase_, give);
rBase_ += give;
return give;
}
void TBufferedTransport::writeSlow(const uint8_t* buf, uint32_t len)
{
uint32_t have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
uint32_t space = static_cast<uint32_t>(wBound_ - wBase_);
// We should only take the slow path if we can't accomodate the write
// with the free space already in the buffer.
assert(wBound_ - wBase_ < static_cast<ptrdiff_t>(len));
// Now here's the tricky question: should we copy data from buf into our
// internal buffer and write it from there, or should we just write out
// the current internal buffer in one syscall and write out buf in another.
// If our currently buffered data plus buf is at least double our buffer
// size, we will have to do two syscalls no matter what (except in the
// degenerate case when our buffer is empty), so there is no use copying.
// Otherwise, there is sort of a sliding scale. If we have N-1 bytes
// buffered and need to write 2, it would be crazy to do two syscalls.
// On the other hand, if we have 2 bytes buffered and are writing 2N-3,
// we can save a syscall in the short term by loading up our buffer, writing
// it out, and copying the rest of the bytes into our buffer. Of course,
// if we get another 2-byte write, we haven't saved any syscalls at all,
// and have just copied nearly 2N bytes for nothing. Finding a perfect
// policy would require predicting the size of future writes, so we're just
// going to always eschew syscalls if we have less than 2N bytes to write.
// The case where we have to do two syscalls.
// This case also covers the case where the buffer is empty,
// but it is clearer (I think) to think of it as two separate cases.
if ((have_bytes + len >= 2 * wBufSize_) || (have_bytes == 0))
{
// TODO(dreiss): writev
if (have_bytes > 0)
{
transport_->write(wBuf_.get(), have_bytes);
}
transport_->write(buf, len);
wBase_ = wBuf_.get();
return;
}
// Fill up our internal buffer for a write.
memcpy(wBase_, buf, space);
buf += space;
len -= space;
transport_->write(wBuf_.get(), wBufSize_);
// Copy the rest into our buffer.
assert(len < wBufSize_);
memcpy(wBuf_.get(), buf, len);
wBase_ = wBuf_.get() + len;
return;
}
const uint8_t* TBufferedTransport::borrowSlow(uint8_t* buf, uint32_t* len)
{
(void) buf;
(void) len;
// Simply return NULL. We don't know if there is actually data available on
// the underlying transport, so calling read() might block.
return NULL;
}
void TBufferedTransport::flush()
{
// Write out any data waiting in the write buffer.
uint32_t have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
if (have_bytes > 0)
{
// Note that we reset wBase_ prior to the underlying write
// to ensure we're in a sane state (i.e. internal buffer cleaned)
// if the underlying write throws up an exception
wBase_ = wBuf_.get();
transport_->write(wBuf_.get(), have_bytes);
}
// Flush the underlying transport.
transport_->flush();
}
uint32_t TFramedTransport::readSlow(uint8_t* buf, uint32_t len)
{
uint32_t want = len;
uint32_t have = static_cast<uint32_t>(rBound_ - rBase_);
// We should only take the slow path if we can't satisfy the read
// with the data already in the buffer.
assert(have < want);
// If we have some data in the buffer, copy it out and return it.
// We have to return it without attempting to read more, since we aren't
// guaranteed that the underlying transport actually has more data, so
// attempting to read from it could block.
if (have > 0)
{
memcpy(buf, rBase_, have);
setReadBuffer(rBuf_.get(), 0);
return have;
}
// Read another frame.
if (!readFrame())
{
// EOF. No frame available.
return 0;
}
// TODO(dreiss): Should we warn when reads cross frames?
// Hand over whatever we have.
uint32_t give = (std::min)(want, static_cast<uint32_t>(rBound_ - rBase_));
memcpy(buf, rBase_, give);
rBase_ += give;
want -= give;
return (len - want);
}
bool TFramedTransport::readFrame()
{
// TODO(dreiss): Think about using readv here, even though it would
// result in (gasp) read-ahead.
// Read the size of the next frame.
// We can't use readAll(&sz, sizeof(sz)), since that always throws an
// exception on EOF. We want to throw an exception only if EOF occurs after
// partial size data.
int32_t sz;
uint32_t size_bytes_read = 0;
while (size_bytes_read < sizeof(sz))
{
uint8_t* szp = reinterpret_cast<uint8_t*>(&sz) + size_bytes_read;
uint32_t bytes_read = transport_->read(
szp,
static_cast<uint32_t>(sizeof(sz)) - size_bytes_read);
if (bytes_read == 0)
{
if (size_bytes_read == 0)
{
// EOF before any data was read.
return false;
}
else
{
// EOF after a partial frame header. Raise an exception.
throw TTransportException(TTransportException::END_OF_FILE,
"No more data to read after "
"partial frame header.");
}
}
size_bytes_read += bytes_read;
}
sz = ntohl(sz);
if (sz < 0)
{
throw TTransportException("Frame size has negative value");
}
// Read the frame payload, and reset markers.
if (sz > static_cast<int32_t>(rBufSize_))
{
rBuf_.reset(new uint8_t[sz]);
rBufSize_ = sz;
}
transport_->readAll(rBuf_.get(), sz);
setReadBuffer(rBuf_.get(), sz);
return true;
}
void TFramedTransport::writeSlow(const uint8_t* buf, uint32_t len)
{
// Double buffer size until sufficient.
uint32_t have = static_cast<uint32_t>(wBase_ - wBuf_.get());
uint32_t new_size = wBufSize_;
if (len + have < have /* overflow */ || len + have > 0x7fffffff)
{
throw TTransportException(TTransportException::BAD_ARGS,
"Attempted to write over 2 GB to TFramedTransport.");
}
while (new_size < len + have)
{
new_size = new_size > 0 ? new_size * 2 : 1;
}
// TODO(dreiss): Consider modifying this class to use malloc/free
// so we can use realloc here.
// Allocate new buffer.
uint8_t* new_buf = new uint8_t[new_size];
// Copy the old buffer to the new one.
memcpy(new_buf, wBuf_.get(), have);
// Now point buf to the new one.
wBuf_.reset(new_buf);
wBufSize_ = new_size;
wBase_ = wBuf_.get() + have;
wBound_ = wBuf_.get() + wBufSize_;
// Copy the data into the new buffer.
memcpy(wBase_, buf, len);
wBase_ += len;
}
void TFramedTransport::flush()
{
int32_t sz_hbo, sz_nbo;
assert(wBufSize_ > sizeof(sz_nbo));
// Slip the frame size into the start of the buffer.
sz_hbo = static_cast<uint32_t>(wBase_ - (wBuf_.get() + sizeof(sz_nbo)));
sz_nbo = (int32_t)htonl((uint32_t)(sz_hbo));
memcpy(wBuf_.get(), (uint8_t*)&sz_nbo, sizeof(sz_nbo));
if (sz_hbo > 0)
{
// Note that we reset wBase_ (with a pad for the frame size)
// prior to the underlying write to ensure we're in a sane state
// (i.e. internal buffer cleaned) if the underlying write throws
// up an exception
wBase_ = wBuf_.get() + sizeof(sz_nbo);
// Write size and frame body.
transport_->write(
wBuf_.get(),
static_cast<uint32_t>(sizeof(sz_nbo)) + sz_hbo);
}
// Flush the underlying transport.
transport_->flush();
}
uint32_t TFramedTransport::writeEnd()
{
return static_cast<uint32_t>(wBase_ - wBuf_.get());
}
const uint8_t* TFramedTransport::borrowSlow(uint8_t* buf, uint32_t* len)
{
(void) buf;
(void) len;
// Don't try to be clever with shifting buffers.
// If the fast path failed let the protocol use its slow path.
// Besides, who is going to try to borrow across messages?
return NULL;
}
uint32_t TFramedTransport::readEnd()
{
// include framing bytes
return static_cast<uint32_t>(rBound_ - rBuf_.get() + sizeof(uint32_t));
}
void TMemoryBuffer::computeRead(uint32_t len, uint8_t** out_start, uint32_t* out_give)
{
// Correct rBound_ so we can use the fast path in the future.
rBound_ = wBase_;
// Decide how much to give.
uint32_t give = (std::min)(len, available_read());
*out_start = rBase_;
*out_give = give;
// Preincrement rBase_ so the caller doesn't have to.
rBase_ += give;
}
uint32_t TMemoryBuffer::readSlow(uint8_t* buf, uint32_t len)
{
uint8_t* start;
uint32_t give;
computeRead(len, &start, &give);
// Copy into the provided buffer.
memcpy(buf, start, give);
return give;
}
uint32_t TMemoryBuffer::readAppendToString(std::string& str, uint32_t len)
{
// Don't get some stupid assertion failure.
if (buffer_ == NULL)
{
return 0;
}
uint8_t* start;
uint32_t give;
computeRead(len, &start, &give);
// Append to the provided string.
str.append((char*)start, give);
return give;
}
void TMemoryBuffer::ensureCanWrite(uint32_t len)
{
// Check available space
uint32_t avail = available_write();
if (len <= avail)
{
return;
}
if (!owner_)
{
throw TTransportException("Insufficient space in external MemoryBuffer");
}
// Grow the buffer as necessary.
uint32_t new_size = bufferSize_;
while (len > avail)
{
new_size = new_size > 0 ? new_size * 2 : 1;
avail = available_write() + (new_size - bufferSize_);
}
// Allocate into a new pointer so we don't bork ours if it fails.
void* new_buffer = std::realloc(buffer_, new_size);
if (new_buffer == NULL)
{
throw std::bad_alloc();
}
bufferSize_ = new_size;
ptrdiff_t offset = (uint8_t*)new_buffer - buffer_;
buffer_ += offset;
rBase_ += offset;
rBound_ += offset;
wBase_ += offset;
wBound_ = buffer_ + bufferSize_;
}
void TMemoryBuffer::writeSlow(const uint8_t* buf, uint32_t len)
{
ensureCanWrite(len);
// Copy into the buffer and increment wBase_.
memcpy(wBase_, buf, len);
wBase_ += len;
}
void TMemoryBuffer::wroteBytes(uint32_t len)
{
uint32_t avail = available_write();
if (len > avail)
{
throw TTransportException("Client wrote more bytes than size of buffer.");
}
wBase_ += len;
}
const uint8_t* TMemoryBuffer::borrowSlow(uint8_t* buf, uint32_t* len)
{
(void) buf;
rBound_ = wBase_;
if (available_read() >= *len)
{
*len = available_read();
return rBase_;
}
return NULL;
}
}
}
} // apache::thrift::transport

View File

@ -1,824 +0,0 @@
/*
* 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.
*/
#pragma once
#include <cstring>
#include <boost/scoped_array.hpp>
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TVirtualTransport.h>
#ifdef __GNUC__
#define TDB_LIKELY(val) (__builtin_expect((val), 1))
#define TDB_UNLIKELY(val) (__builtin_expect((val), 0))
#else
#define TDB_LIKELY(val) (val)
#define TDB_UNLIKELY(val) (val)
#endif
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Base class for all transports that use read/write buffers for performance.
*
* TBufferBase is designed to implement the fast-path "memcpy" style
* operations that work in the common case. It does so with small and
* (eventually) nonvirtual, inlinable methods. TBufferBase is an abstract
* class. Subclasses are expected to define the "slow path" operations
* that have to be done when the buffers are full or empty.
*
*/
class TBufferBase : public TVirtualTransport<TBufferBase>
{
public:
/**
* Fast-path read.
*
* When we have enough data buffered to fulfill the read, we can satisfy it
* with a single memcpy, then adjust our internal pointers. If the buffer
* is empty, we call out to our slow path, implemented by a subclass.
* This method is meant to eventually be nonvirtual and inlinable.
*/
uint32_t read(uint8_t* buf, uint32_t len)
{
uint8_t* new_rBase = rBase_ + len;
if (TDB_LIKELY(new_rBase <= rBound_))
{
std::memcpy(buf, rBase_, len);
rBase_ = new_rBase;
return len;
}
return readSlow(buf, len);
}
/**
* Shortcutted version of readAll.
*/
uint32_t readAll(uint8_t* buf, uint32_t len)
{
uint8_t* new_rBase = rBase_ + len;
if (TDB_LIKELY(new_rBase <= rBound_))
{
std::memcpy(buf, rBase_, len);
rBase_ = new_rBase;
return len;
}
return apache::thrift::transport::readAll(*this, buf, len);
}
/**
* Fast-path write.
*
* When we have enough empty space in our buffer to accomodate the write, we
* can satisfy it with a single memcpy, then adjust our internal pointers.
* If the buffer is full, we call out to our slow path, implemented by a
* subclass. This method is meant to eventually be nonvirtual and
* inlinable.
*/
void write(const uint8_t* buf, uint32_t len)
{
uint8_t* new_wBase = wBase_ + len;
if (TDB_LIKELY(new_wBase <= wBound_))
{
std::memcpy(wBase_, buf, len);
wBase_ = new_wBase;
return;
}
writeSlow(buf, len);
}
/**
* Fast-path borrow. A lot like the fast-path read.
*/
const uint8_t* borrow(uint8_t* buf, uint32_t* len)
{
if (TDB_LIKELY(static_cast<ptrdiff_t>(*len) <= rBound_ - rBase_))
{
// With strict aliasing, writing to len shouldn't force us to
// refetch rBase_ from memory. TODO(dreiss): Verify this.
*len = static_cast<uint32_t>(rBound_ - rBase_);
return rBase_;
}
return borrowSlow(buf, len);
}
/**
* Consume doesn't require a slow path.
*/
void consume(uint32_t len)
{
if (TDB_LIKELY(static_cast<ptrdiff_t>(len) <= rBound_ - rBase_))
{
rBase_ += len;
}
else
{
throw TTransportException(TTransportException::BAD_ARGS,
"consume did not follow a borrow.");
}
}
protected:
/// Slow path read.
virtual uint32_t readSlow(uint8_t* buf, uint32_t len) = 0;
/// Slow path write.
virtual void writeSlow(const uint8_t* buf, uint32_t len) = 0;
/**
* Slow path borrow.
*
* POSTCONDITION: return == NULL || rBound_ - rBase_ >= *len
*/
virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) = 0;
/**
* Trivial constructor.
*
* Initialize pointers safely. Constructing is not a very
* performance-sensitive operation, so it is okay to just leave it to
* the concrete class to set up pointers correctly.
*/
TBufferBase()
: rBase_(NULL)
, rBound_(NULL)
, wBase_(NULL)
, wBound_(NULL)
{}
/// Convenience mutator for setting the read buffer.
void setReadBuffer(uint8_t* buf, uint32_t len)
{
rBase_ = buf;
rBound_ = buf + len;
}
/// Convenience mutator for setting the write buffer.
void setWriteBuffer(uint8_t* buf, uint32_t len)
{
wBase_ = buf;
wBound_ = buf + len;
}
virtual ~TBufferBase() {}
/// Reads begin here.
uint8_t* rBase_;
/// Reads may extend to just before here.
uint8_t* rBound_;
/// Writes begin here.
uint8_t* wBase_;
/// Writes may extend to just before here.
uint8_t* wBound_;
};
/**
* Buffered transport. For reads it will read more data than is requested
* and will serve future data out of a local buffer. For writes, data is
* stored to an in memory buffer before being written out.
*
*/
class TBufferedTransport
: public TVirtualTransport<TBufferedTransport, TBufferBase>
{
public:
static const int DEFAULT_BUFFER_SIZE = 512;
/// Use default buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport)
: transport_(transport)
, rBufSize_(DEFAULT_BUFFER_SIZE)
, wBufSize_(DEFAULT_BUFFER_SIZE)
, rBuf_(new uint8_t[rBufSize_])
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
/// Use specified buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport, uint32_t sz)
: transport_(transport)
, rBufSize_(sz)
, wBufSize_(sz)
, rBuf_(new uint8_t[rBufSize_])
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
/// Use specified read and write buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport, uint32_t rsz, uint32_t wsz)
: transport_(transport)
, rBufSize_(rsz)
, wBufSize_(wsz)
, rBuf_(new uint8_t[rBufSize_])
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
void open()
{
transport_->open();
}
bool isOpen()
{
return transport_->isOpen();
}
bool peek()
{
if (rBase_ == rBound_)
{
setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));
}
return (rBound_ > rBase_);
}
void close()
{
flush();
transport_->close();
}
virtual uint32_t readSlow(uint8_t* buf, uint32_t len);
virtual void writeSlow(const uint8_t* buf, uint32_t len);
void flush();
/**
* The following behavior is currently implemented by TBufferedTransport,
* but that may change in a future version:
* 1/ If len is at most rBufSize_, borrow will never return NULL.
* Depending on the underlying transport, it could throw an exception
* or hang forever.
* 2/ Some borrow requests may copy bytes internally. However,
* if len is at most rBufSize_/2, none of the copied bytes
* will ever have to be copied again. For optimial performance,
* stay under this limit.
*/
virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
boost::shared_ptr<TTransport> getUnderlyingTransport()
{
return transport_;
}
/*
* TVirtualTransport provides a default implementation of readAll().
* We want to use the TBufferBase version instead.
*/
uint32_t readAll(uint8_t* buf, uint32_t len)
{
return TBufferBase::readAll(buf, len);
}
protected:
void initPointers()
{
setReadBuffer(rBuf_.get(), 0);
setWriteBuffer(wBuf_.get(), wBufSize_);
// Write size never changes.
}
boost::shared_ptr<TTransport> transport_;
uint32_t rBufSize_;
uint32_t wBufSize_;
boost::scoped_array<uint8_t> rBuf_;
boost::scoped_array<uint8_t> wBuf_;
};
/**
* Wraps a transport into a buffered one.
*
*/
class TBufferedTransportFactory : public TTransportFactory
{
public:
TBufferedTransportFactory() {}
virtual ~TBufferedTransportFactory() {}
/**
* Wraps the transport into a buffered one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans)
{
return boost::shared_ptr<TTransport>(new TBufferedTransport(trans));
}
};
/**
* Framed transport. All writes go into an in-memory buffer until flush is
* called, at which point the transport writes the length of the entire
* binary chunk followed by the data payload. This allows the receiver on the
* other end to always do fixed-length reads.
*
*/
class TFramedTransport
: public TVirtualTransport<TFramedTransport, TBufferBase>
{
public:
static const int DEFAULT_BUFFER_SIZE = 512;
/// Use default buffer sizes.
TFramedTransport(boost::shared_ptr<TTransport> transport)
: transport_(transport)
, rBufSize_(0)
, wBufSize_(DEFAULT_BUFFER_SIZE)
, rBuf_()
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
TFramedTransport(boost::shared_ptr<TTransport> transport, uint32_t sz)
: transport_(transport)
, rBufSize_(0)
, wBufSize_(sz)
, rBuf_()
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
void open()
{
transport_->open();
}
bool isOpen()
{
return transport_->isOpen();
}
bool peek()
{
return (rBase_ < rBound_) || transport_->peek();
}
void close()
{
flush();
transport_->close();
}
virtual uint32_t readSlow(uint8_t* buf, uint32_t len);
virtual void writeSlow(const uint8_t* buf, uint32_t len);
virtual void flush();
uint32_t readEnd();
uint32_t writeEnd();
const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
boost::shared_ptr<TTransport> getUnderlyingTransport()
{
return transport_;
}
/*
* TVirtualTransport provides a default implementation of readAll().
* We want to use the TBufferBase version instead.
*/
uint32_t readAll(uint8_t* buf, uint32_t len)
{
return TBufferBase::readAll(buf, len);
}
protected:
/**
* Reads a frame of input from the underlying stream.
*
* Returns true if a frame was read successfully, or false on EOF.
* (Raises a TTransportException if EOF occurs after a partial frame.)
*/
bool readFrame();
void initPointers()
{
setReadBuffer(NULL, 0);
setWriteBuffer(wBuf_.get(), wBufSize_);
// Pad the buffer so we can insert the size later.
int32_t pad = 0;
this->write((uint8_t*)&pad, sizeof(pad));
}
boost::shared_ptr<TTransport> transport_;
uint32_t rBufSize_;
uint32_t wBufSize_;
boost::scoped_array<uint8_t> rBuf_;
boost::scoped_array<uint8_t> wBuf_;
};
/**
* Wraps a transport into a framed one.
*
*/
class TFramedTransportFactory : public TTransportFactory
{
public:
TFramedTransportFactory() {}
virtual ~TFramedTransportFactory() {}
/**
* Wraps the transport into a framed one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans)
{
return boost::shared_ptr<TTransport>(new TFramedTransport(trans));
}
};
/**
* A memory buffer is a tranpsort that simply reads from and writes to an
* in memory buffer. Anytime you call write on it, the data is simply placed
* into a buffer, and anytime you call read, data is read from that buffer.
*
* The buffers are allocated using C constructs malloc,realloc, and the size
* doubles as necessary. We've considered using scoped
*
*/
class TMemoryBuffer : public TVirtualTransport<TMemoryBuffer, TBufferBase>
{
private:
// Common initialization done by all constructors.
void initCommon(uint8_t* buf, uint32_t size, bool owner, uint32_t wPos)
{
if (buf == NULL && size != 0)
{
assert(owner);
buf = (uint8_t*)std::malloc(size);
if (buf == NULL)
{
throw std::bad_alloc();
}
}
buffer_ = buf;
bufferSize_ = size;
rBase_ = buffer_;
rBound_ = buffer_ + wPos;
// TODO(dreiss): Investigate NULL-ing this if !owner.
wBase_ = buffer_ + wPos;
wBound_ = buffer_ + bufferSize_;
owner_ = owner;
// rBound_ is really an artifact. In principle, it should always be
// equal to wBase_. We update it in a few places (computeRead, etc.).
}
public:
static const uint32_t defaultSize = 1024;
/**
* This enum specifies how a TMemoryBuffer should treat
* memory passed to it via constructors or resetBuffer.
*
* OBSERVE:
* TMemoryBuffer will simply store a pointer to the memory.
* It is the callers responsibility to ensure that the pointer
* remains valid for the lifetime of the TMemoryBuffer,
* and that it is properly cleaned up.
* Note that no data can be written to observed buffers.
*
* COPY:
* TMemoryBuffer will make an internal copy of the buffer.
* The caller has no responsibilities.
*
* TAKE_OWNERSHIP:
* TMemoryBuffer will become the "owner" of the buffer,
* and will be responsible for freeing it.
* The membory must have been allocated with malloc.
*/
enum MemoryPolicy
{
OBSERVE = 1
, COPY = 2
, TAKE_OWNERSHIP = 3
};
/**
* Construct a TMemoryBuffer with a default-sized buffer,
* owned by the TMemoryBuffer object.
*/
TMemoryBuffer()
{
initCommon(NULL, defaultSize, true, 0);
}
/**
* Construct a TMemoryBuffer with a buffer of a specified size,
* owned by the TMemoryBuffer object.
*
* @param sz The initial size of the buffer.
*/
TMemoryBuffer(uint32_t sz)
{
initCommon(NULL, sz, true, 0);
}
/**
* Construct a TMemoryBuffer with buf as its initial contents.
*
* @param buf The initial contents of the buffer.
* Note that, while buf is a non-const pointer,
* TMemoryBuffer will not write to it if policy == OBSERVE,
* so it is safe to const_cast<uint8_t*>(whatever).
* @param sz The size of @c buf.
* @param policy See @link MemoryPolicy @endlink .
*/
TMemoryBuffer(uint8_t* buf, uint32_t sz, MemoryPolicy policy = OBSERVE)
{
if (buf == NULL && sz != 0)
{
throw TTransportException(TTransportException::BAD_ARGS,
"TMemoryBuffer given null buffer with non-zero size.");
}
switch (policy)
{
case OBSERVE:
case TAKE_OWNERSHIP:
initCommon(buf, sz, policy == TAKE_OWNERSHIP, sz);
break;
case COPY:
initCommon(NULL, sz, true, 0);
this->write(buf, sz);
break;
default:
throw TTransportException(TTransportException::BAD_ARGS,
"Invalid MemoryPolicy for TMemoryBuffer");
}
}
~TMemoryBuffer()
{
if (owner_)
{
std::free(buffer_);
}
}
bool isOpen()
{
return true;
}
bool peek()
{
return (rBase_ < wBase_);
}
void open() {}
void close() {}
// TODO(dreiss): Make bufPtr const.
void getBuffer(uint8_t** bufPtr, uint32_t* sz)
{
*bufPtr = rBase_;
*sz = static_cast<uint32_t>(wBase_ - rBase_);
}
std::string getBufferAsString()
{
if (buffer_ == NULL)
{
return "";
}
uint8_t* buf;
uint32_t sz;
getBuffer(&buf, &sz);
return std::string((char*)buf, (std::string::size_type)sz);
}
void appendBufferToString(std::string& str)
{
if (buffer_ == NULL)
{
return;
}
uint8_t* buf;
uint32_t sz;
getBuffer(&buf, &sz);
str.append((char*)buf, sz);
}
void resetBuffer()
{
rBase_ = buffer_;
rBound_ = buffer_;
wBase_ = buffer_;
// It isn't safe to write into a buffer we don't own.
if (!owner_)
{
wBound_ = wBase_;
bufferSize_ = 0;
}
}
/// See constructor documentation.
void resetBuffer(uint8_t* buf, uint32_t sz, MemoryPolicy policy = OBSERVE)
{
// Use a variant of the copy-and-swap trick for assignment operators.
// This is sub-optimal in terms of performance for two reasons:
// 1/ The constructing and swapping of the (small) values
// in the temporary object takes some time, and is not necessary.
// 2/ If policy == COPY, we allocate the new buffer before
// freeing the old one, precluding the possibility of
// reusing that memory.
// I doubt that either of these problems could be optimized away,
// but the second is probably no a common case, and the first is minor.
// I don't expect resetBuffer to be a common operation, so I'm willing to
// bite the performance bullet to make the method this simple.
// Construct the new buffer.
TMemoryBuffer new_buffer(buf, sz, policy);
// Move it into ourself.
this->swap(new_buffer);
// Our old self gets destroyed.
}
/// See constructor documentation.
void resetBuffer(uint32_t sz)
{
// Construct the new buffer.
TMemoryBuffer new_buffer(sz);
// Move it into ourself.
this->swap(new_buffer);
// Our old self gets destroyed.
}
std::string readAsString(uint32_t len)
{
std::string str;
(void)readAppendToString(str, len);
return str;
}
uint32_t readAppendToString(std::string& str, uint32_t len);
// return number of bytes read
uint32_t readEnd()
{
//This cast should be safe, because buffer_'s size is a uint32_t
uint32_t bytes = static_cast<uint32_t>(rBase_ - buffer_);
if (rBase_ == wBase_)
{
resetBuffer();
}
return bytes;
}
// Return number of bytes written
uint32_t writeEnd()
{
//This cast should be safe, because buffer_'s size is a uint32_t
return static_cast<uint32_t>(wBase_ - buffer_);
}
uint32_t available_read() const
{
// Remember, wBase_ is the real rBound_.
return static_cast<uint32_t>(wBase_ - rBase_);
}
uint32_t available_write() const
{
return static_cast<uint32_t>(wBound_ - wBase_);
}
// Returns a pointer to where the client can write data to append to
// the TMemoryBuffer, and ensures the buffer is big enough to accomodate a
// write of the provided length. The returned pointer is very convenient for
// passing to read(), recv(), or similar. You must call wroteBytes() as soon
// as data is written or the buffer will not be aware that data has changed.
uint8_t* getWritePtr(uint32_t len)
{
ensureCanWrite(len);
return wBase_;
}
// Informs the buffer that the client has written 'len' bytes into storage
// that had been provided by getWritePtr().
void wroteBytes(uint32_t len);
/*
* TVirtualTransport provides a default implementation of readAll().
* We want to use the TBufferBase version instead.
*/
uint32_t readAll(uint8_t* buf, uint32_t len)
{
return TBufferBase::readAll(buf, len);
}
protected:
void swap(TMemoryBuffer& that)
{
using std::swap;
swap(buffer_, that.buffer_);
swap(bufferSize_, that.bufferSize_);
swap(rBase_, that.rBase_);
swap(rBound_, that.rBound_);
swap(wBase_, that.wBase_);
swap(wBound_, that.wBound_);
swap(owner_, that.owner_);
}
// Make sure there's at least 'len' bytes available for writing.
void ensureCanWrite(uint32_t len);
// Compute the position and available data for reading.
void computeRead(uint32_t len, uint8_t** out_start, uint32_t* out_give);
uint32_t readSlow(uint8_t* buf, uint32_t len);
void writeSlow(const uint8_t* buf, uint32_t len);
const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
// Data buffer
uint8_t* buffer_;
// Allocated buffer size
uint32_t bufferSize_;
// Is this object the owner of the buffer?
bool owner_;
// Don't forget to update constrctors, initCommon, and swap if
// you add new members.
};
}
}
} // apache::thrift::transport

View File

@ -1,93 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TVirtualTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Dead-simple wrapper around a file descriptor.
*
*/
class TFDTransport : public TVirtualTransport<TFDTransport>
{
public:
enum ClosePolicy
{
NO_CLOSE_ON_DESTROY = 0
, CLOSE_ON_DESTROY = 1
};
TFDTransport(int fd, ClosePolicy close_policy = NO_CLOSE_ON_DESTROY)
: fd_(fd)
, close_policy_(close_policy)
{}
~TFDTransport()
{
if (close_policy_ == CLOSE_ON_DESTROY)
{
close();
}
}
bool isOpen()
{
return fd_ >= 0;
}
void open() {}
void close();
uint32_t read(uint8_t* buf, uint32_t len);
void write(const uint8_t* buf, uint32_t len);
void setFD(int fd)
{
fd_ = fd;
}
int getFD()
{
return fd_;
}
protected:
int fd_;
ClosePolicy close_policy_;
};
}
}
} // apache::thrift::transport

View File

@ -1,529 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TTransport.h>
#include <thrift/Thrift.h>
#include <thrift/TProcessor.h>
#include <string>
#include <stdio.h>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <thrift/concurrency/Mutex.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/concurrency/Thread.h>
namespace apache
{
namespace thrift
{
namespace transport
{
using apache::thrift::TProcessor;
using apache::thrift::protocol::TProtocolFactory;
using apache::thrift::concurrency::Mutex;
using apache::thrift::concurrency::Monitor;
// Data pertaining to a single event
typedef struct eventInfo
{
uint8_t* eventBuff_;
uint32_t eventSize_;
uint32_t eventBuffPos_;
eventInfo(): eventBuff_(NULL), eventSize_(0), eventBuffPos_(0) {};
~eventInfo()
{
if (eventBuff_)
{
delete[] eventBuff_;
}
}
} eventInfo;
// information about current read state
typedef struct readState
{
eventInfo* event_;
// keep track of event size
uint8_t eventSizeBuff_[4];
uint8_t eventSizeBuffPos_;
bool readingSize_;
// read buffer variables
int32_t bufferPtr_;
int32_t bufferLen_;
// last successful dispatch point
int32_t lastDispatchPtr_;
void resetState(uint32_t lastDispatchPtr)
{
readingSize_ = true;
eventSizeBuffPos_ = 0;
lastDispatchPtr_ = lastDispatchPtr;
}
void resetAllValues()
{
resetState(0);
bufferPtr_ = 0;
bufferLen_ = 0;
if (event_)
{
delete (event_);
}
event_ = 0;
}
inline uint32_t getEventSize()
{
const void* buffer = reinterpret_cast<const void*>(eventSizeBuff_);
return *reinterpret_cast<const uint32_t*>(buffer);
}
readState()
{
event_ = 0;
resetAllValues();
}
~readState()
{
if (event_)
{
delete (event_);
}
}
} readState;
/**
* TFileTransportBuffer - buffer class used by TFileTransport for queueing up events
* to be written to disk. Should be used in the following way:
* 1) Buffer created
* 2) Buffer written to (addEvent)
* 3) Buffer read from (getNext)
* 4) Buffer reset (reset)
* 5) Go back to 2, or destroy buffer
*
* The buffer should never be written to after it is read from, unless it is reset first.
* Note: The above rules are enforced mainly for debugging its sole client TFileTransport
* which uses the buffer in this way.
*
*/
class TFileTransportBuffer
{
public:
TFileTransportBuffer(uint32_t size);
~TFileTransportBuffer();
bool addEvent(eventInfo* event);
eventInfo* getNext();
void reset();
bool isFull();
bool isEmpty();
private:
TFileTransportBuffer(); // should not be used
enum mode
{
WRITE,
READ
};
mode bufferMode_;
uint32_t writePoint_;
uint32_t readPoint_;
uint32_t size_;
eventInfo** buffer_;
};
/**
* Abstract interface for transports used to read files
*/
class TFileReaderTransport : virtual public TTransport
{
public:
virtual int32_t getReadTimeout() = 0;
virtual void setReadTimeout(int32_t readTimeout) = 0;
virtual uint32_t getNumChunks() = 0;
virtual uint32_t getCurChunk() = 0;
virtual void seekToChunk(int32_t chunk) = 0;
virtual void seekToEnd() = 0;
};
/**
* Abstract interface for transports used to write files
*/
class TFileWriterTransport : virtual public TTransport
{
public:
virtual uint32_t getChunkSize() = 0;
virtual void setChunkSize(uint32_t chunkSize) = 0;
};
/**
* File implementation of a transport. Reads and writes are done to a
* file on disk.
*
*/
class TFileTransport : public TFileReaderTransport,
public TFileWriterTransport
{
public:
TFileTransport(std::string path, bool readOnly = false);
~TFileTransport();
// TODO: what is the correct behaviour for this?
// the log file is generally always open
bool isOpen()
{
return true;
}
void write(const uint8_t* buf, uint32_t len);
void flush();
uint32_t readAll(uint8_t* buf, uint32_t len);
uint32_t read(uint8_t* buf, uint32_t len);
bool peek();
// log-file specific functions
void seekToChunk(int32_t chunk);
void seekToEnd();
uint32_t getNumChunks();
uint32_t getCurChunk();
// for changing the output file
void resetOutputFile(int fd, std::string filename, off_t offset);
// Setter/Getter functions for user-controllable options
void setReadBuffSize(uint32_t readBuffSize)
{
if (readBuffSize)
{
readBuffSize_ = readBuffSize;
}
}
uint32_t getReadBuffSize()
{
return readBuffSize_;
}
static const int32_t TAIL_READ_TIMEOUT = -1;
static const int32_t NO_TAIL_READ_TIMEOUT = 0;
void setReadTimeout(int32_t readTimeout)
{
readTimeout_ = readTimeout;
}
int32_t getReadTimeout()
{
return readTimeout_;
}
void setChunkSize(uint32_t chunkSize)
{
if (chunkSize)
{
chunkSize_ = chunkSize;
}
}
uint32_t getChunkSize()
{
return chunkSize_;
}
void setEventBufferSize(uint32_t bufferSize)
{
if (bufferAndThreadInitialized_)
{
GlobalOutput("Cannot change the buffer size after writer thread started");
return;
}
eventBufferSize_ = bufferSize;
}
uint32_t getEventBufferSize()
{
return eventBufferSize_;
}
void setFlushMaxUs(uint32_t flushMaxUs)
{
if (flushMaxUs)
{
flushMaxUs_ = flushMaxUs;
}
}
uint32_t getFlushMaxUs()
{
return flushMaxUs_;
}
void setFlushMaxBytes(uint32_t flushMaxBytes)
{
if (flushMaxBytes)
{
flushMaxBytes_ = flushMaxBytes;
}
}
uint32_t getFlushMaxBytes()
{
return flushMaxBytes_;
}
void setMaxEventSize(uint32_t maxEventSize)
{
maxEventSize_ = maxEventSize;
}
uint32_t getMaxEventSize()
{
return maxEventSize_;
}
void setMaxCorruptedEvents(uint32_t maxCorruptedEvents)
{
maxCorruptedEvents_ = maxCorruptedEvents;
}
uint32_t getMaxCorruptedEvents()
{
return maxCorruptedEvents_;
}
void setEofSleepTimeUs(uint32_t eofSleepTime)
{
if (eofSleepTime)
{
eofSleepTime_ = eofSleepTime;
}
}
uint32_t getEofSleepTimeUs()
{
return eofSleepTime_;
}
/*
* Override TTransport *_virt() functions to invoke our implementations.
* We cannot use TVirtualTransport to provide these, since we need to inherit
* virtually from TTransport.
*/
virtual uint32_t read_virt(uint8_t* buf, uint32_t len)
{
return this->read(buf, len);
}
virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len)
{
return this->readAll(buf, len);
}
virtual void write_virt(const uint8_t* buf, uint32_t len)
{
this->write(buf, len);
}
private:
// helper functions for writing to a file
void enqueueEvent(const uint8_t* buf, uint32_t eventLen);
bool swapEventBuffers(struct timeval* deadline);
bool initBufferAndWriteThread();
// control for writer thread
static void* startWriterThread(void* ptr)
{
static_cast<TFileTransport*>(ptr)->writerThread();
return NULL;
}
void writerThread();
// helper functions for reading from a file
eventInfo* readEvent();
// event corruption-related functions
bool isEventCorrupted();
void performRecovery();
// Utility functions
void openLogFile();
void getNextFlushTime(struct timeval* ts_next_flush);
// Class variables
readState readState_;
uint8_t* readBuff_;
eventInfo* currentEvent_;
uint32_t readBuffSize_;
static const uint32_t DEFAULT_READ_BUFF_SIZE = 1 * 1024 * 1024;
int32_t readTimeout_;
static const int32_t DEFAULT_READ_TIMEOUT_MS = 200;
// size of chunks that file will be split up into
uint32_t chunkSize_;
static const uint32_t DEFAULT_CHUNK_SIZE = 16 * 1024 * 1024;
// size of event buffers
uint32_t eventBufferSize_;
static const uint32_t DEFAULT_EVENT_BUFFER_SIZE = 10000;
// max number of microseconds that can pass without flushing
uint32_t flushMaxUs_;
static const uint32_t DEFAULT_FLUSH_MAX_US = 3000000;
// max number of bytes that can be written without flushing
uint32_t flushMaxBytes_;
static const uint32_t DEFAULT_FLUSH_MAX_BYTES = 1000 * 1024;
// max event size
uint32_t maxEventSize_;
static const uint32_t DEFAULT_MAX_EVENT_SIZE = 0;
// max number of corrupted events per chunk
uint32_t maxCorruptedEvents_;
static const uint32_t DEFAULT_MAX_CORRUPTED_EVENTS = 0;
// sleep duration when EOF is hit
uint32_t eofSleepTime_;
static const uint32_t DEFAULT_EOF_SLEEP_TIME_US = 500 * 1000;
// sleep duration when a corrupted event is encountered
uint32_t corruptedEventSleepTime_;
static const uint32_t DEFAULT_CORRUPTED_SLEEP_TIME_US = 1 * 1000 * 1000;
// sleep duration in seconds when an IO error is encountered in the writer thread
uint32_t writerThreadIOErrorSleepTime_;
static const uint32_t DEFAULT_WRITER_THREAD_SLEEP_TIME_US = 60 * 1000 * 1000;
// writer thread
apache::thrift::concurrency::PlatformThreadFactory threadFactory_;
boost::shared_ptr<apache::thrift::concurrency::Thread> writerThread_;
// buffers to hold data before it is flushed. Each element of the buffer stores a msg that
// needs to be written to the file. The buffers are swapped by the writer thread.
TFileTransportBuffer* dequeueBuffer_;
TFileTransportBuffer* enqueueBuffer_;
// conditions used to block when the buffer is full or empty
Monitor notFull_, notEmpty_;
volatile bool closing_;
// To keep track of whether the buffer has been flushed
Monitor flushed_;
volatile bool forceFlush_;
// Mutex that is grabbed when enqueueing and swapping the read/write buffers
Mutex mutex_;
// File information
std::string filename_;
int fd_;
// Whether the writer thread and buffers have been initialized
bool bufferAndThreadInitialized_;
// Offset within the file
off_t offset_;
// event corruption information
uint32_t lastBadChunk_;
uint32_t numCorruptedEventsInChunk_;
bool readOnly_;
};
// Exception thrown when EOF is hit
class TEOFException : public TTransportException
{
public:
TEOFException():
TTransportException(TTransportException::END_OF_FILE) {};
};
// wrapper class to process events from a file containing thrift events
class TFileProcessor
{
public:
/**
* Constructor that defaults output transport to null transport
*
* @param processor processes log-file events
* @param protocolFactory protocol factory
* @param inputTransport file transport
*/
TFileProcessor(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocolFactory> protocolFactory,
boost::shared_ptr<TFileReaderTransport> inputTransport);
TFileProcessor(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocolFactory> inputProtocolFactory,
boost::shared_ptr<TProtocolFactory> outputProtocolFactory,
boost::shared_ptr<TFileReaderTransport> inputTransport);
/**
* Constructor
*
* @param processor processes log-file events
* @param protocolFactory protocol factory
* @param inputTransport input file transport
* @param output output transport
*/
TFileProcessor(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocolFactory> protocolFactory,
boost::shared_ptr<TFileReaderTransport> inputTransport,
boost::shared_ptr<TTransport> outputTransport);
/**
* processes events from the file
*
* @param numEvents number of events to process (0 for unlimited)
* @param tail tails the file if true
*/
void process(uint32_t numEvents, bool tail);
/**
* process events until the end of the chunk
*
*/
void processChunk();
private:
boost::shared_ptr<TProcessor> processor_;
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;
boost::shared_ptr<TFileReaderTransport> inputTransport_;
boost::shared_ptr<TTransport> outputTransport_;
};
}
}
} // apache::thrift::transport

View File

@ -1,55 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/THttpTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
class THttpClient : public THttpTransport
{
public:
THttpClient(boost::shared_ptr<TTransport> transport, std::string host, std::string path = "");
THttpClient(std::string host, int port, std::string path = "");
virtual ~THttpClient();
virtual void flush();
protected:
std::string host_;
std::string path_;
virtual void parseHeader(char* header);
virtual bool parseStatusLine(char* status);
};
}
}
} // apache::thrift::transport

View File

@ -1,72 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/THttpTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
class THttpServer : public THttpTransport
{
public:
THttpServer(boost::shared_ptr<TTransport> transport);
virtual ~THttpServer();
virtual void flush();
protected:
void readHeaders();
virtual void parseHeader(char* header);
virtual bool parseStatusLine(char* status);
std::string getTimeRFC1123();
};
/**
* Wraps a transport into HTTP protocol
*/
class THttpServerTransportFactory : public TTransportFactory
{
public:
THttpServerTransportFactory() {}
virtual ~THttpServerTransportFactory() {}
/**
* Wraps the transport into a buffered one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans)
{
return boost::shared_ptr<TTransport>(new THttpServer(trans));
}
};
}
}
} // apache::thrift::transport

View File

@ -1,117 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TVirtualTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* HTTP implementation of the thrift transport. This was irritating
* to write, but the alternatives in C++ land are daunting. Linking CURL
* requires 23 dynamic libraries last time I checked (WTF?!?). All we have
* here is a VERY basic HTTP/1.1 client which supports HTTP 100 Continue,
* chunked transfer encoding, keepalive, etc. Tested against Apache.
*/
class THttpTransport : public TVirtualTransport<THttpTransport>
{
public:
THttpTransport(boost::shared_ptr<TTransport> transport);
virtual ~THttpTransport();
void open()
{
transport_->open();
}
bool isOpen()
{
return transport_->isOpen();
}
bool peek()
{
return transport_->peek();
}
void close()
{
transport_->close();
}
uint32_t read(uint8_t* buf, uint32_t len);
uint32_t readEnd();
void write(const uint8_t* buf, uint32_t len);
virtual void flush() = 0;
protected:
boost::shared_ptr<TTransport> transport_;
TMemoryBuffer writeBuffer_;
TMemoryBuffer readBuffer_;
bool readHeaders_;
bool chunked_;
bool chunkedDone_;
uint32_t chunkSize_;
uint32_t contentLength_;
char* httpBuf_;
uint32_t httpPos_;
uint32_t httpBufLen_;
uint32_t httpBufSize_;
virtual void init();
uint32_t readMoreData();
char* readLine();
void readHeaders();
virtual void parseHeader(char* header) = 0;
virtual bool parseStatusLine(char* status) = 0;
uint32_t readChunked();
void readChunkedFooters();
uint32_t parseChunkSize(char* line);
uint32_t readContent(uint32_t size);
void refill();
void shift();
static const char* CRLF;
static const int CRLF_LEN;
};
}
}
} // apache::thrift::transport

View File

@ -1,102 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TVirtualTransport.h>
#ifndef _WIN32
# include <thrift/transport/TSocket.h>
#endif
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Windows Pipes implementation of the TTransport interface.
*
*/
#ifdef _WIN32
class TPipe : public TVirtualTransport<TPipe>
{
public:
// Constructs a new pipe object.
TPipe();
// Named pipe constructors -
explicit TPipe(HANDLE Pipe); //HANDLE is a void*
//need a const char * overload so string literals don't go to the HANDLE overload
explicit TPipe(const char* pipename);
explicit TPipe(const std::string& pipename);
// Anonymous pipe -
TPipe(HANDLE PipeRd, HANDLE PipeWrt);
// Destroys the pipe object, closing it if necessary.
virtual ~TPipe();
// Returns whether the pipe is open & valid.
virtual bool isOpen();
// Checks whether more data is available in the pipe.
virtual bool peek();
// Creates and opens the named/anonymous pipe.
virtual void open();
// Shuts down communications on the pipe.
virtual void close();
// Reads from the pipe.
virtual uint32_t read(uint8_t* buf, uint32_t len);
// Writes to the pipe.
virtual void write(const uint8_t* buf, uint32_t len);
//Accessors
std::string getPipename();
void setPipename(const std::string& pipename);
HANDLE getPipeHandle(); //doubles as the read handle for anon pipe
void setPipeHandle(HANDLE pipehandle);
HANDLE getWrtPipeHandle();
void setWrtPipeHandle(HANDLE pipehandle);
long getConnectTimeout();
void setConnectTimeout(long seconds);
private:
std::string pipename_;
//Named pipe handles are R/W, while anonymous pipes are one or the other (half duplex).
HANDLE Pipe_, PipeWrt_;
long TimeoutSeconds_;
bool isAnonymous;
};
#else
typedef TSocket TPipe;
#endif
}
}
} // apache::thrift::transport

View File

@ -1,99 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TServerTransport.h>
#include <boost/shared_ptr.hpp>
#ifndef _WIN32
# include "TServerSocket.h"
#endif
#define TPIPE_SERVER_MAX_CONNS_DEFAULT 10
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Windows Pipes implementation of TServerTransport.
*/
#ifdef _WIN32
class TPipeServer : public TServerTransport
{
public:
//Constructors
// Named Pipe -
TPipeServer(const std::string& pipename, uint32_t bufsize);
TPipeServer(const std::string& pipename, uint32_t bufsize, uint32_t maxconnections);
TPipeServer(const std::string& pipename);
// Anonymous pipe -
TPipeServer(int bufsize);
TPipeServer();
//Destructor
~TPipeServer();
//Standard transport callbacks
void interrupt();
void close();
protected:
boost::shared_ptr<TTransport> acceptImpl();
bool TCreateNamedPipe();
bool TCreateAnonPipe();
void createWakeupEvent();
public:
//Accessors
std::string getPipename();
void setPipename(const std::string& pipename);
int getBufferSize();
void setBufferSize(int bufsize);
HANDLE getPipeHandle(); //Named Pipe R/W -or- Anonymous pipe Read handle
HANDLE getWrtPipeHandle();
HANDLE getClientRdPipeHandle();
HANDLE getClientWrtPipeHandle();
bool getAnonymous();
void setAnonymous(bool anon);
private:
std::string pipename_;
uint32_t bufsize_;
HANDLE Pipe_; //Named Pipe (R/W) or Anonymous Pipe (R)
uint32_t maxconns_;
HANDLE PipeW_; //Anonymous Pipe (W)
HANDLE ClientAnonRead, ClientAnonWrite; //Client side anonymous pipe handles
HANDLE wakeup; // wake up event
//? Do we need duplicates to send to client?
bool isAnonymous;
bool stop_; // stop flag
};
#else //_WIN32
//*NIX named pipe implementation uses domain socket
typedef TServerSocket TPipeServer;
#endif
}
}
} // apache::thrift::transport

View File

@ -1,65 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <thrift/transport/TServerSocket.h>
namespace apache
{
namespace thrift
{
namespace transport
{
class TSSLSocketFactory;
/**
* Server socket that accepts SSL connections.
*/
class TSSLServerSocket: public TServerSocket
{
public:
/**
* Constructor.
*
* @param port Listening port
* @param factory SSL socket factory implementation
*/
TSSLServerSocket(int port, boost::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor.
*
* @param port Listening port
* @param sendTimeout Socket send timeout
* @param recvTimeout Socket receive timeout
* @param factory SSL socket factory implementation
*/
TSSLServerSocket(int port, int sendTimeout, int recvTimeout,
boost::shared_ptr<TSSLSocketFactory> factory);
protected:
boost::shared_ptr<TSocket> createSocket(int socket);
boost::shared_ptr<TSSLSocketFactory> factory_;
};
}
}
}

View File

@ -1,357 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#include <boost/shared_ptr.hpp>
#include <openssl/ssl.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/transport/TSocket.h>
namespace apache
{
namespace thrift
{
namespace transport
{
class AccessManager;
class SSLContext;
/**
* OpenSSL implementation for SSL socket interface.
*/
class TSSLSocket: public TSocket
{
public:
~TSSLSocket();
/**
* TTransport interface.
*/
bool isOpen();
bool peek();
void open();
void close();
uint32_t read(uint8_t* buf, uint32_t len);
void write(const uint8_t* buf, uint32_t len);
void flush();
/**
* Set whether to use client or server side SSL handshake protocol.
*
* @param flag Use server side handshake protocol if true.
*/
void server(bool flag)
{
server_ = flag;
}
/**
* Determine whether the SSL socket is server or client mode.
*/
bool server() const
{
return server_;
}
/**
* Set AccessManager.
*
* @param manager Instance of AccessManager
*/
virtual void access(boost::shared_ptr<AccessManager> manager)
{
access_ = manager;
}
protected:
/**
* Constructor.
*/
TSSLSocket(boost::shared_ptr<SSLContext> ctx);
/**
* Constructor, create an instance of TSSLSocket given an existing socket.
*
* @param socket An existing socket
*/
TSSLSocket(boost::shared_ptr<SSLContext> ctx, int socket);
/**
* Constructor.
*
* @param host Remote host name
* @param port Remote port number
*/
TSSLSocket(boost::shared_ptr<SSLContext> ctx,
std::string host,
int port);
/**
* Authorize peer access after SSL handshake completes.
*/
virtual void authorize();
/**
* Initiate SSL handshake if not already initiated.
*/
void checkHandshake();
bool server_;
SSL* ssl_;
boost::shared_ptr<SSLContext> ctx_;
boost::shared_ptr<AccessManager> access_;
friend class TSSLSocketFactory;
};
/**
* SSL socket factory. SSL sockets should be created via SSL factory.
*/
class TSSLSocketFactory
{
public:
/**
* Constructor/Destructor
*/
TSSLSocketFactory();
virtual ~TSSLSocketFactory();
/**
* Create an instance of TSSLSocket with a fresh new socket.
*/
virtual boost::shared_ptr<TSSLSocket> createSocket();
/**
* Create an instance of TSSLSocket with the given socket.
*
* @param socket An existing socket.
*/
virtual boost::shared_ptr<TSSLSocket> createSocket(int socket);
/**
* Create an instance of TSSLSocket.
*
* @param host Remote host to be connected to
* @param port Remote port to be connected to
*/
virtual boost::shared_ptr<TSSLSocket> createSocket(const std::string& host,
int port);
/**
* Set ciphers to be used in SSL handshake process.
*
* @param ciphers A list of ciphers
*/
virtual void ciphers(const std::string& enable);
/**
* Enable/Disable authentication.
*
* @param required Require peer to present valid certificate if true
*/
virtual void authenticate(bool required);
/**
* Load server certificate.
*
* @param path Path to the certificate file
* @param format Certificate file format
*/
virtual void loadCertificate(const char* path, const char* format = "PEM");
/**
* Load private key.
*
* @param path Path to the private key file
* @param format Private key file format
*/
virtual void loadPrivateKey(const char* path, const char* format = "PEM");
/**
* Load trusted certificates from specified file.
*
* @param path Path to trusted certificate file
*/
virtual void loadTrustedCertificates(const char* path);
/**
* Default randomize method.
*/
virtual void randomize();
/**
* Override default OpenSSL password callback with getPassword().
*/
void overrideDefaultPasswordCallback();
/**
* Set/Unset server mode.
*
* @param flag Server mode if true
*/
virtual void server(bool flag)
{
server_ = flag;
}
/**
* Determine whether the socket is in server or client mode.
*
* @return true, if server mode, or, false, if client mode
*/
virtual bool server() const
{
return server_;
}
/**
* Set AccessManager.
*
* @param manager The AccessManager instance
*/
virtual void access(boost::shared_ptr<AccessManager> manager)
{
access_ = manager;
}
protected:
boost::shared_ptr<SSLContext> ctx_;
static void initializeOpenSSL();
static void cleanupOpenSSL();
/**
* Override this method for custom password callback. It may be called
* multiple times at any time during a session as necessary.
*
* @param password Pass collected password to OpenSSL
* @param size Maximum length of password including NULL character
*/
virtual void getPassword(std::string& /* password */, int /* size */) {}
private:
bool server_;
boost::shared_ptr<AccessManager> access_;
static bool initialized;
static concurrency::Mutex mutex_;
static uint64_t count_;
void setup(boost::shared_ptr<TSSLSocket> ssl);
static int passwordCallback(char* password, int size, int, void* data);
};
/**
* SSL exception.
*/
class TSSLException: public TTransportException
{
public:
TSSLException(const std::string& message):
TTransportException(TTransportException::INTERNAL_ERROR, message) {}
virtual const char* what() const throw()
{
if (message_.empty())
{
return "TSSLException";
}
else
{
return message_.c_str();
}
}
};
/**
* Wrap OpenSSL SSL_CTX into a class.
*/
class SSLContext
{
public:
SSLContext();
virtual ~SSLContext();
SSL* createSSL();
SSL_CTX* get()
{
return ctx_;
}
private:
SSL_CTX* ctx_;
};
/**
* Callback interface for access control. It's meant to verify the remote host.
* It's constructed when application starts and set to TSSLSocketFactory
* instance. It's passed onto all TSSLSocket instances created by this factory
* object.
*/
class AccessManager
{
public:
enum Decision
{
DENY = -1, // deny access
SKIP = 0, // cannot make decision, move on to next (if any)
ALLOW = 1 // allow access
};
/**
* Destructor
*/
virtual ~AccessManager() {}
/**
* Determine whether the peer should be granted access or not. It's called
* once after the SSL handshake completes successfully, before peer certificate
* is examined.
*
* If a valid decision (ALLOW or DENY) is returned, the peer certificate is
* not to be verified.
*
* @param sa Peer IP address
* @return True if the peer is trusted, false otherwise
*/
virtual Decision verify(const sockaddr_storage& /* sa */ ) throw()
{
return DENY;
}
/**
* Determine whether the peer should be granted access or not. It's called
* every time a DNS subjectAltName/common name is extracted from peer's
* certificate.
*
* @param host Client mode: host name returned by TSocket::getHost()
* Server mode: host name returned by TSocket::getPeerHost()
* @param name SubjectAltName or common name extracted from peer certificate
* @param size Length of name
* @return True if the peer is trusted, false otherwise
*
* Note: The "name" parameter may be UTF8 encoded.
*/
virtual Decision verify(const std::string& /* host */, const char* /* name */, int /* size */)
throw()
{
return DENY;
}
/**
* Determine whether the peer should be granted access or not. It's called
* every time an IP subjectAltName is extracted from peer's certificate.
*
* @param sa Peer IP address retrieved from the underlying socket
* @param data IP address extracted from certificate
* @param size Length of the IP address
* @return True if the peer is trusted, false otherwise
*/
virtual Decision verify(const sockaddr_storage& /* sa */, const char* /* data */, int /* size */)
throw()
{
return DENY;
}
};
typedef AccessManager::Decision Decision;
class DefaultClientAccessManager: public AccessManager
{
public:
// AccessManager interface
Decision verify(const sockaddr_storage& sa) throw();
Decision verify(const std::string& host, const char* name, int size) throw();
Decision verify(const sockaddr_storage& sa, const char* data, int size) throw();
};
}
}
}

View File

@ -1,609 +0,0 @@
/*
* 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.
*/
#include <thrift/thrift-config.h>
#include <cstring>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/PlatformSocket.h>
#include <boost/shared_ptr.hpp>
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#ifndef SOCKOPT_CAST_T
# ifndef _WIN32
# define SOCKOPT_CAST_T void
# else
# define SOCKOPT_CAST_T char
# endif // _WIN32
#endif
template<class T>
inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v)
{
return reinterpret_cast<const SOCKOPT_CAST_T*>(v);
}
template<class T>
inline SOCKOPT_CAST_T* cast_sockopt(T* v)
{
return reinterpret_cast<SOCKOPT_CAST_T*>(v);
}
namespace apache
{
namespace thrift
{
namespace transport
{
using namespace std;
using boost::shared_ptr;
TServerSocket::TServerSocket(int port) :
port_(port),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(0),
recvTimeout_(0),
accTimeout_(-1),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
intSock1_(THRIFT_INVALID_SOCKET),
intSock2_(THRIFT_INVALID_SOCKET) {}
TServerSocket::TServerSocket(int port, int sendTimeout, int recvTimeout) :
port_(port),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(sendTimeout),
recvTimeout_(recvTimeout),
accTimeout_(-1),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
intSock1_(THRIFT_INVALID_SOCKET),
intSock2_(THRIFT_INVALID_SOCKET) {}
TServerSocket::TServerSocket(string path) :
port_(0),
path_(path),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(0),
recvTimeout_(0),
accTimeout_(-1),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
intSock1_(THRIFT_INVALID_SOCKET),
intSock2_(THRIFT_INVALID_SOCKET) {}
TServerSocket::~TServerSocket()
{
close();
}
void TServerSocket::setSendTimeout(int sendTimeout)
{
sendTimeout_ = sendTimeout;
}
void TServerSocket::setRecvTimeout(int recvTimeout)
{
recvTimeout_ = recvTimeout;
}
void TServerSocket::setAcceptTimeout(int accTimeout)
{
accTimeout_ = accTimeout;
}
void TServerSocket::setAcceptBacklog(int accBacklog)
{
acceptBacklog_ = accBacklog;
}
void TServerSocket::setRetryLimit(int retryLimit)
{
retryLimit_ = retryLimit;
}
void TServerSocket::setRetryDelay(int retryDelay)
{
retryDelay_ = retryDelay;
}
void TServerSocket::setTcpSendBuffer(int tcpSendBuffer)
{
tcpSendBuffer_ = tcpSendBuffer;
}
void TServerSocket::setTcpRecvBuffer(int tcpRecvBuffer)
{
tcpRecvBuffer_ = tcpRecvBuffer;
}
void TServerSocket::listen()
{
THRIFT_SOCKET sv[2];
if (-1 == THRIFT_SOCKETPAIR(AF_LOCAL, SOCK_STREAM, 0, sv))
{
GlobalOutput.perror("TServerSocket::listen() socketpair() ", THRIFT_GET_SOCKET_ERROR);
intSock1_ = THRIFT_INVALID_SOCKET;
intSock2_ = THRIFT_INVALID_SOCKET;
}
else
{
intSock1_ = sv[1];
intSock2_ = sv[0];
}
struct addrinfo hints, *res, *res0;
int error;
char port[sizeof("65536") + 1];
std::memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
sprintf(port, "%d", port_);
// Wildcard address
error = getaddrinfo(NULL, port, &hints, &res0);
if (error)
{
GlobalOutput.printf("getaddrinfo %d: %s", error, THRIFT_GAI_STRERROR(error));
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket.");
}
// Pick the ipv6 address first since ipv4 addresses can be mapped
// into ipv6 space.
for (res = res0; res; res = res->ai_next)
{
if (res->ai_family == AF_INET6 || res->ai_next == NULL)
break;
}
if (! path_.empty())
{
serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP);
}
else
{
serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
}
if (serverSocket_ == THRIFT_INVALID_SOCKET)
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() socket() ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy);
}
// Set THRIFT_NO_SOCKET_CACHING to prevent 2MSL delay on accept
int one = 1;
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, THRIFT_NO_SOCKET_CACHING,
cast_sockopt(&one), sizeof(one)))
{
//ignore errors coming out of this setsockopt on Windows. This is because
//SO_EXCLUSIVEADDRUSE requires admin privileges on WinXP, but we don't
//want to force servers to be an admin.
#ifndef _WIN32
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set THRIFT_NO_SOCKET_CACHING", errno_copy);
#endif
}
// Set TCP buffer sizes
if (tcpSendBuffer_ > 0)
{
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_SNDBUF,
cast_sockopt(&tcpSendBuffer_), sizeof(tcpSendBuffer_)))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", errno_copy);
}
}
if (tcpRecvBuffer_ > 0)
{
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_RCVBUF,
cast_sockopt(&tcpRecvBuffer_), sizeof(tcpRecvBuffer_)))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", errno_copy);
}
}
// Defer accept
#ifdef TCP_DEFER_ACCEPT
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, TCP_DEFER_ACCEPT,
&one, sizeof(one)))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT", errno_copy);
}
#endif // #ifdef TCP_DEFER_ACCEPT
#ifdef IPV6_V6ONLY
if (res->ai_family == AF_INET6 && path_.empty())
{
int zero = 0;
if (-1 == setsockopt(serverSocket_, IPPROTO_IPV6, IPV6_V6ONLY,
cast_sockopt(&zero), sizeof(zero)))
{
GlobalOutput.perror("TServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR);
}
}
#endif // #ifdef IPV6_V6ONLY
// Turn linger off, don't want to block on calls to close
struct linger ling = {0, 0};
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER,
cast_sockopt(&ling), sizeof(ling)))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_LINGER ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy);
}
// Unix Sockets do not need that
if (path_.empty())
{
// TCP Nodelay, speed over bandwidth
if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY,
cast_sockopt(&one), sizeof(one)))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy);
}
}
// Set NONBLOCK on the accept socket
int flags = THRIFT_FCNTL(serverSocket_, THRIFT_F_GETFL, 0);
if (flags == -1)
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy);
}
if (-1 == THRIFT_FCNTL(serverSocket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy);
}
// prepare the port information
// we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't
// always seem to work. The client can configure the retry variables.
int retries = 0;
if (! path_.empty())
{
#ifndef _WIN32
// Unix Domain Socket
struct sockaddr_un address;
socklen_t len;
if (path_.length() > sizeof(address.sun_path))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path too long");
}
address.sun_family = AF_UNIX;
THRIFT_SNPRINTF(address.sun_path, sizeof(address.sun_path), "%s", path_.c_str());
len = sizeof(address);
do
{
if (0 == ::bind(serverSocket_, (struct sockaddr*) &address, len))
{
break;
}
// use short circuit evaluation here to only sleep if we need to
}
while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
#else
GlobalOutput.perror("TSocket::open() Unix Domain socket path not supported on windows", -99);
throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported");
#endif
}
else
{
do
{
if (0 == ::bind(serverSocket_, res->ai_addr, static_cast<int>(res->ai_addrlen)))
{
break;
}
// use short circuit evaluation here to only sleep if we need to
}
while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
// free addrinfo
freeaddrinfo(res0);
}
// throw an error if we failed to bind properly
if (retries > retryLimit_)
{
char errbuf[1024];
if (! path_.empty())
{
sprintf(errbuf, "TServerSocket::listen() PATH %s", path_.c_str());
}
else
{
sprintf(errbuf, "TServerSocket::listen() BIND %d", port_);
}
GlobalOutput(errbuf);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not bind",
THRIFT_GET_SOCKET_ERROR);
}
// Call listen
if (-1 == ::listen(serverSocket_, acceptBacklog_))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() listen() ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);
}
// The socket is now listening!
}
shared_ptr<TTransport> TServerSocket::acceptImpl()
{
if (serverSocket_ == THRIFT_INVALID_SOCKET)
{
throw TTransportException(TTransportException::NOT_OPEN, "TServerSocket not listening");
}
struct THRIFT_POLLFD fds[2];
int maxEintrs = 5;
int numEintrs = 0;
while (true)
{
std::memset(fds, 0, sizeof(fds));
fds[0].fd = serverSocket_;
fds[0].events = THRIFT_POLLIN;
if (intSock2_ != THRIFT_INVALID_SOCKET)
{
fds[1].fd = intSock2_;
fds[1].events = THRIFT_POLLIN;
}
/*
TODO: if THRIFT_EINTR is received, we'll restart the timeout.
To be accurate, we need to fix this in the future.
*/
int ret = THRIFT_POLL(fds, 2, accTimeout_);
if (ret < 0)
{
// error cases
if (THRIFT_GET_SOCKET_ERROR == THRIFT_EINTR && (numEintrs++ < maxEintrs))
{
// THRIFT_EINTR needs to be handled manually and we can tolerate
// a certain number
continue;
}
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::acceptImpl() THRIFT_POLL() ", errno_copy);
throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy);
}
else if (ret > 0)
{
// Check for an interrupt signal
if (intSock2_ != THRIFT_INVALID_SOCKET
&& (fds[1].revents & THRIFT_POLLIN))
{
int8_t buf;
if (-1 == recv(intSock2_, cast_sockopt(&buf), sizeof(int8_t), 0))
{
GlobalOutput.perror("TServerSocket::acceptImpl() recv() interrupt ", THRIFT_GET_SOCKET_ERROR);
}
throw TTransportException(TTransportException::INTERRUPTED);
}
// Check for the actual server socket being ready
if (fds[0].revents & THRIFT_POLLIN)
{
break;
}
}
else
{
GlobalOutput("TServerSocket::acceptImpl() THRIFT_POLL 0");
throw TTransportException(TTransportException::UNKNOWN);
}
}
struct sockaddr_storage clientAddress;
int size = sizeof(clientAddress);
THRIFT_SOCKET clientSocket = ::accept(serverSocket_,
(struct sockaddr*) &clientAddress,
(socklen_t*) &size);
if (clientSocket == -1)
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::acceptImpl() ::accept() ", errno_copy);
throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy);
}
// Make sure client socket is blocking
int flags = THRIFT_FCNTL(clientSocket, THRIFT_F_GETFL, 0);
if (flags == -1)
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy);
throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_GETFL)", errno_copy);
}
if (-1 == THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags & ~THRIFT_O_NONBLOCK))
{
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_SETFL ~THRIFT_O_NONBLOCK ", errno_copy);
throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_SETFL)", errno_copy);
}
shared_ptr<TSocket> client = createSocket(clientSocket);
if (sendTimeout_ > 0)
{
client->setSendTimeout(sendTimeout_);
}
if (recvTimeout_ > 0)
{
client->setRecvTimeout(recvTimeout_);
}
client->setCachedAddress((sockaddr*) &clientAddress, size);
return client;
}
shared_ptr<TSocket> TServerSocket::createSocket(THRIFT_SOCKET clientSocket)
{
return shared_ptr<TSocket>(new TSocket(clientSocket));
}
void TServerSocket::interrupt()
{
if (intSock1_ != THRIFT_INVALID_SOCKET)
{
int8_t byte = 0;
if (-1 == send(intSock1_, cast_sockopt(&byte), sizeof(int8_t), 0))
{
GlobalOutput.perror("TServerSocket::interrupt() send() ", THRIFT_GET_SOCKET_ERROR);
}
}
}
void TServerSocket::close()
{
if (serverSocket_ != THRIFT_INVALID_SOCKET)
{
shutdown(serverSocket_, THRIFT_SHUT_RDWR);
::THRIFT_CLOSESOCKET(serverSocket_);
}
if (intSock1_ != THRIFT_INVALID_SOCKET)
{
::THRIFT_CLOSESOCKET(intSock1_);
}
if (intSock2_ != THRIFT_INVALID_SOCKET)
{
::THRIFT_CLOSESOCKET(intSock2_);
}
serverSocket_ = THRIFT_INVALID_SOCKET;
intSock1_ = THRIFT_INVALID_SOCKET;
intSock2_ = THRIFT_INVALID_SOCKET;
}
}
}
} // apache::thrift::transport

View File

@ -1,92 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TServerTransport.h>
#include <thrift/transport/PlatformSocket.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace transport
{
class TSocket;
/**
* Server socket implementation of TServerTransport. Wrapper around a unix
* socket listen and accept calls.
*
*/
class TServerSocket : public TServerTransport
{
public:
const static int DEFAULT_BACKLOG = 1024;
TServerSocket(int port);
TServerSocket(int port, int sendTimeout, int recvTimeout);
TServerSocket(std::string path);
~TServerSocket();
void setSendTimeout(int sendTimeout);
void setRecvTimeout(int recvTimeout);
void setAcceptTimeout(int accTimeout);
void setAcceptBacklog(int accBacklog);
void setRetryLimit(int retryLimit);
void setRetryDelay(int retryDelay);
void setTcpSendBuffer(int tcpSendBuffer);
void setTcpRecvBuffer(int tcpRecvBuffer);
void listen();
void close();
void interrupt();
protected:
boost::shared_ptr<TTransport> acceptImpl();
virtual boost::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client);
private:
int port_;
std::string path_;
THRIFT_SOCKET serverSocket_;
int acceptBacklog_;
int sendTimeout_;
int recvTimeout_;
int accTimeout_;
int retryLimit_;
int retryDelay_;
int tcpSendBuffer_;
int tcpRecvBuffer_;
THRIFT_SOCKET intSock1_;
THRIFT_SOCKET intSock2_;
};
}
}
} // apache::thrift::transport

View File

@ -1,102 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TTransportException.h>
#include <boost/shared_ptr.hpp>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Server transport framework. A server needs to have some facility for
* creating base transports to read/write from.
*
*/
class TServerTransport
{
public:
virtual ~TServerTransport() {}
/**
* Starts the server transport listening for new connections. Prior to this
* call most transports will not return anything when accept is called.
*
* @throws TTransportException if we were unable to listen
*/
virtual void listen() {}
/**
* Gets a new dynamically allocated transport object and passes it to the
* caller. Note that it is the explicit duty of the caller to free the
* allocated object. The returned TTransport object must always be in the
* opened state. NULL should never be returned, instead an Exception should
* always be thrown.
*
* @return A new TTransport object
* @throws TTransportException if there is an error
*/
boost::shared_ptr<TTransport> accept()
{
boost::shared_ptr<TTransport> result = acceptImpl();
if (!result)
{
throw TTransportException("accept() may not return NULL");
}
return result;
}
/**
* For "smart" TServerTransport implementations that work in a multi
* threaded context this can be used to break out of an accept() call.
* It is expected that the transport will throw a TTransportException
* with the interrupted error code.
*/
virtual void interrupt() {}
/**
* Closes this transport such that future calls to accept will do nothing.
*/
virtual void close() = 0;
protected:
TServerTransport() {}
/**
* Subclasses should implement this function for accept.
*
* @return A newly allocated TTransport object
* @throw TTransportException If an error occurs
*/
virtual boost::shared_ptr<TTransport> acceptImpl() = 0;
};
}
}
} // apache::thrift::transport

View File

@ -1,119 +0,0 @@
/*
* 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.
*/
#pragma once
#include <cstdlib>
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TVirtualTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
namespace test
{
/**
* This class is only meant for testing. It wraps another transport.
* Calls to read are passed through with some probability. Otherwise,
* the read amount is randomly reduced before being passed through.
*
*/
class TShortReadTransport : public TVirtualTransport<TShortReadTransport>
{
public:
TShortReadTransport(boost::shared_ptr<TTransport> transport, double full_prob)
: transport_(transport)
, fullProb_(full_prob)
{}
bool isOpen()
{
return transport_->isOpen();
}
bool peek()
{
return transport_->peek();
}
void open()
{
transport_->open();
}
void close()
{
transport_->close();
}
uint32_t read(uint8_t* buf, uint32_t len)
{
if (len == 0)
{
return 0;
}
if (rand() / (double)RAND_MAX >= fullProb_)
{
len = 1 + rand() % len;
}
return transport_->read(buf, len);
}
void write(const uint8_t* buf, uint32_t len)
{
transport_->write(buf, len);
}
void flush()
{
transport_->flush();
}
const uint8_t* borrow(uint8_t* buf, uint32_t* len)
{
return transport_->borrow(buf, len);
}
void consume(uint32_t len)
{
return transport_->consume(len);
}
boost::shared_ptr<TTransport> getUnderlyingTransport()
{
return transport_;
}
protected:
boost::shared_ptr<TTransport> transport_;
double fullProb_;
};
}
}
}
} // apache::thrift::transport::test

View File

@ -1,47 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/transport/TFDTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Dead-simple wrapper around a file.
*
* Writeable files are opened with O_CREAT and O_APPEND
*/
class TSimpleFileTransport : public TFDTransport
{
public:
TSimpleFileTransport(const std::string& path,
bool read = true,
bool write = false);
};
}
}
} // apache::thrift::transport

File diff suppressed because it is too large Load Diff

View File

@ -1,317 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TVirtualTransport.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/PlatformSocket.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* TCP Socket implementation of the TTransport interface.
*
*/
class TSocket : public TVirtualTransport<TSocket>
{
public:
/**
* Constructs a new socket. Note that this does NOT actually connect the
* socket.
*
*/
TSocket();
/**
* Constructs a new socket. Note that this does NOT actually connect the
* socket.
*
* @param host An IP address or hostname to connect to
* @param port The port to connect on
*/
TSocket(std::string host, int port);
/**
* Constructs a new Unix domain socket.
* Note that this does NOT actually connect the socket.
*
* @param path The Unix domain socket e.g. "/tmp/ThriftTest.binary.thrift"
*/
TSocket(std::string path);
/**
* Destroyes the socket object, closing it if necessary.
*/
virtual ~TSocket();
/**
* Whether the socket is alive.
*
* @return Is the socket alive?
*/
virtual bool isOpen();
/**
* Calls select on the socket to see if there is more data available.
*/
virtual bool peek();
/**
* Creates and opens the UNIX socket.
*
* @throws TTransportException If the socket could not connect
*/
virtual void open();
/**
* Shuts down communications on the socket.
*/
virtual void close();
/**
* Reads from the underlying socket.
*/
virtual uint32_t read(uint8_t* buf, uint32_t len);
/**
* Writes to the underlying socket. Loops until done or fail.
*/
virtual void write(const uint8_t* buf, uint32_t len);
/**
* Writes to the underlying socket. Does single send() and returns result.
*/
uint32_t write_partial(const uint8_t* buf, uint32_t len);
/**
* Get the host that the socket is connected to
*
* @return string host identifier
*/
std::string getHost();
/**
* Get the port that the socket is connected to
*
* @return int port number
*/
int getPort();
/**
* Set the host that socket will connect to
*
* @param host host identifier
*/
void setHost(std::string host);
/**
* Set the port that socket will connect to
*
* @param port port number
*/
void setPort(int port);
/**
* Controls whether the linger option is set on the socket.
*
* @param on Whether SO_LINGER is on
* @param linger If linger is active, the number of seconds to linger for
*/
void setLinger(bool on, int linger);
/**
* Whether to enable/disable Nagle's algorithm.
*
* @param noDelay Whether or not to disable the algorithm.
* @return
*/
void setNoDelay(bool noDelay);
/**
* Set the connect timeout
*/
void setConnTimeout(int ms);
/**
* Set the receive timeout
*/
void setRecvTimeout(int ms);
/**
* Set the send timeout
*/
void setSendTimeout(int ms);
/**
* Set the max number of recv retries in case of an THRIFT_EAGAIN
* error
*/
void setMaxRecvRetries(int maxRecvRetries);
/**
* Get socket information formated as a string <Host: x Port: x>
*/
std::string getSocketInfo();
/**
* Returns the DNS name of the host to which the socket is connected
*/
std::string getPeerHost();
/**
* Returns the address of the host to which the socket is connected
*/
std::string getPeerAddress();
/**
* Returns the port of the host to which the socket is connected
**/
int getPeerPort();
/**
* Returns the underlying socket file descriptor.
*/
THRIFT_SOCKET getSocketFD()
{
return socket_;
}
/**
* (Re-)initialize a TSocket for the supplied descriptor. This is only
* intended for use by TNonblockingServer -- other use may result in
* unfortunate surprises.
*
* @param fd the descriptor for an already-connected socket
*/
void setSocketFD(THRIFT_SOCKET fd);
/*
* Returns a cached copy of the peer address.
*/
sockaddr* getCachedAddress(socklen_t* len) const;
/**
* Sets whether to use a low minimum TCP retransmission timeout.
*/
static void setUseLowMinRto(bool useLowMinRto);
/**
* Gets whether to use a low minimum TCP retransmission timeout.
*/
static bool getUseLowMinRto();
/**
* Constructor to create socket from raw UNIX handle.
*/
TSocket(THRIFT_SOCKET socket);
/**
* Set a cache of the peer address (used when trivially available: e.g.
* accept() or connect()). Only caches IPV4 and IPV6; unset for others.
*/
void setCachedAddress(const sockaddr* addr, socklen_t len);
protected:
/** connect, called by open */
void openConnection(struct addrinfo* res);
/** Host to connect to */
std::string host_;
/** Peer hostname */
std::string peerHost_;
/** Peer address */
std::string peerAddress_;
/** Peer port */
int peerPort_;
/** Port number to connect on */
int port_;
/** UNIX domain socket path */
std::string path_;
/** Underlying UNIX socket handle */
THRIFT_SOCKET socket_;
/** Connect timeout in ms */
int connTimeout_;
/** Send timeout in ms */
int sendTimeout_;
/** Recv timeout in ms */
int recvTimeout_;
/** Linger on */
bool lingerOn_;
/** Linger val */
int lingerVal_;
/** Nodelay */
bool noDelay_;
/** Recv EGAIN retries */
int maxRecvRetries_;
/** Recv timeout timeval */
struct timeval recvTimeval_;
/** Cached peer address */
union
{
sockaddr_in ipv4;
sockaddr_in6 ipv6;
} cachedPeerAddr_;
/** Whether to use low minimum TCP retransmission timeout */
static bool useLowMinRto_;
private:
void unix_open();
void local_open();
};
}
}
} // apache::thrift::transport

View File

@ -1,203 +0,0 @@
/*
* 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.
*/
#pragma once
#include <vector>
#include <thrift/transport/TSocket.h>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Class to hold server information for TSocketPool
*
*/
class TSocketPoolServer
{
public:
/**
* Default constructor for server info
*/
TSocketPoolServer();
/**
* Constructor for TSocketPool server
*/
TSocketPoolServer(const std::string& host, int port);
// Host name
std::string host_;
// Port to connect on
int port_;
// Socket for the server
THRIFT_SOCKET socket_;
// Last time connecting to this server failed
time_t lastFailTime_;
// Number of consecutive times connecting to this server failed
int consecutiveFailures_;
};
/**
* TCP Socket implementation of the TTransport interface.
*
*/
class TSocketPool : public TSocket
{
public:
/**
* Socket pool constructor
*/
TSocketPool();
/**
* Socket pool constructor
*
* @param hosts list of host names
* @param ports list of port names
*/
TSocketPool(const std::vector<std::string>& hosts,
const std::vector<int>& ports);
/**
* Socket pool constructor
*
* @param servers list of pairs of host name and port
*/
TSocketPool(const std::vector<std::pair<std::string, int> >& servers);
/**
* Socket pool constructor
*
* @param servers list of TSocketPoolServers
*/
TSocketPool(const std::vector< boost::shared_ptr<TSocketPoolServer> >& servers);
/**
* Socket pool constructor
*
* @param host single host
* @param port single port
*/
TSocketPool(const std::string& host, int port);
/**
* Destroyes the socket object, closing it if necessary.
*/
virtual ~TSocketPool();
/**
* Add a server to the pool
*/
void addServer(const std::string& host, int port);
/**
* Add a server to the pool
*/
void addServer(boost::shared_ptr<TSocketPoolServer>& server);
/**
* Set list of servers in this pool
*/
void setServers(const std::vector< boost::shared_ptr<TSocketPoolServer> >& servers);
/**
* Get list of servers in this pool
*/
void getServers(std::vector< boost::shared_ptr<TSocketPoolServer> >& servers);
/**
* Sets how many times to keep retrying a host in the connect function.
*/
void setNumRetries(int numRetries);
/**
* Sets how long to wait until retrying a host if it was marked down
*/
void setRetryInterval(int retryInterval);
/**
* Sets how many times to keep retrying a host before marking it as down.
*/
void setMaxConsecutiveFailures(int maxConsecutiveFailures);
/**
* Turns randomization in connect order on or off.
*/
void setRandomize(bool randomize);
/**
* Whether to always try the last server.
*/
void setAlwaysTryLast(bool alwaysTryLast);
/**
* Creates and opens the UNIX socket.
*/
void open();
/*
* Closes the UNIX socket
*/
void close();
protected:
void setCurrentServer(const boost::shared_ptr<TSocketPoolServer>& server);
/** List of servers to connect to */
std::vector< boost::shared_ptr<TSocketPoolServer> > servers_;
/** Current server */
boost::shared_ptr<TSocketPoolServer> currentServer_;
/** How many times to retry each host in connect */
int numRetries_;
/** Retry interval in seconds, how long to not try a host if it has been
* marked as down.
*/
time_t retryInterval_;
/** Max consecutive failures before marking a host down. */
int maxConsecutiveFailures_;
/** Try hosts in order? or Randomized? */
bool randomize_;
/** Always try last host, even if marked down? */
bool alwaysTryLast_;
};
}
}
} // apache::thrift::transport

View File

@ -1,300 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/Thrift.h>
#include <boost/shared_ptr.hpp>
#include <thrift/transport/TTransportException.h>
#include <string>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Helper template to hoist readAll implementation out of TTransport
*/
template <class Transport_>
uint32_t readAll(Transport_ &trans, uint8_t* buf, uint32_t len)
{
uint32_t have = 0;
uint32_t get = 0;
while (have < len)
{
get = trans.read(buf + have, len - have);
if (get <= 0)
{
throw TTransportException(TTransportException::END_OF_FILE,
"No more data to read.");
}
have += get;
}
return have;
}
/**
* Generic interface for a method of transporting data. A TTransport may be
* capable of either reading or writing, but not necessarily both.
*
*/
class TTransport
{
public:
/**
* Virtual deconstructor.
*/
virtual ~TTransport() {}
/**
* Whether this transport is open.
*/
virtual bool isOpen()
{
return false;
}
/**
* Tests whether there is more data to read or if the remote side is
* still open. By default this is true whenever the transport is open,
* but implementations should add logic to test for this condition where
* possible (i.e. on a socket).
* This is used by a server to check if it should listen for another
* request.
*/
virtual bool peek()
{
return isOpen();
}
/**
* Opens the transport for communications.
*
* @return bool Whether the transport was successfully opened
* @throws TTransportException if opening failed
*/
virtual void open()
{
throw TTransportException(TTransportException::NOT_OPEN, "Cannot open base TTransport.");
}
/**
* Closes the transport.
*/
virtual void close()
{
throw TTransportException(TTransportException::NOT_OPEN, "Cannot close base TTransport.");
}
/**
* Attempt to read up to the specified number of bytes into the string.
*
* @param buf Reference to the location to write the data
* @param len How many bytes to read
* @return How many bytes were actually read
* @throws TTransportException If an error occurs
*/
uint32_t read(uint8_t* buf, uint32_t len)
{
T_VIRTUAL_CALL();
return read_virt(buf, len);
}
virtual uint32_t read_virt(uint8_t* /* buf */, uint32_t /* len */)
{
throw TTransportException(TTransportException::NOT_OPEN,
"Base TTransport cannot read.");
}
/**
* Reads the given amount of data in its entirety no matter what.
*
* @param s Reference to location for read data
* @param len How many bytes to read
* @return How many bytes read, which must be equal to size
* @throws TTransportException If insufficient data was read
*/
uint32_t readAll(uint8_t* buf, uint32_t len)
{
T_VIRTUAL_CALL();
return readAll_virt(buf, len);
}
virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len)
{
return apache::thrift::transport::readAll(*this, buf, len);
}
/**
* Called when read is completed.
* This can be over-ridden to perform a transport-specific action
* e.g. logging the request to a file
*
* @return number of bytes read if available, 0 otherwise.
*/
virtual uint32_t readEnd()
{
// default behaviour is to do nothing
return 0;
}
/**
* Writes the string in its entirety to the buffer.
*
* Note: You must call flush() to ensure the data is actually written,
* and available to be read back in the future. Destroying a TTransport
* object does not automatically flush pending data--if you destroy a
* TTransport object with written but unflushed data, that data may be
* discarded.
*
* @param buf The data to write out
* @throws TTransportException if an error occurs
*/
void write(const uint8_t* buf, uint32_t len)
{
T_VIRTUAL_CALL();
write_virt(buf, len);
}
virtual void write_virt(const uint8_t* /* buf */, uint32_t /* len */)
{
throw TTransportException(TTransportException::NOT_OPEN,
"Base TTransport cannot write.");
}
/**
* Called when write is completed.
* This can be over-ridden to perform a transport-specific action
* at the end of a request.
*
* @return number of bytes written if available, 0 otherwise
*/
virtual uint32_t writeEnd()
{
// default behaviour is to do nothing
return 0;
}
/**
* Flushes any pending data to be written. Typically used with buffered
* transport mechanisms.
*
* @throws TTransportException if an error occurs
*/
virtual void flush()
{
// default behaviour is to do nothing
}
/**
* Attempts to return a pointer to \c len bytes, possibly copied into \c buf.
* Does not consume the bytes read (i.e.: a later read will return the same
* data). This method is meant to support protocols that need to read
* variable-length fields. They can attempt to borrow the maximum amount of
* data that they will need, then consume (see next method) what they
* actually use. Some transports will not support this method and others
* will fail occasionally, so protocols must be prepared to use read if
* borrow fails.
*
* @oaram buf A buffer where the data can be stored if needed.
* If borrow doesn't return buf, then the contents of
* buf after the call are undefined. This parameter may be
* NULL to indicate that the caller is not supplying storage,
* but would like a pointer into an internal buffer, if
* available.
* @param len *len should initially contain the number of bytes to borrow.
* If borrow succeeds, *len will contain the number of bytes
* available in the returned pointer. This will be at least
* what was requested, but may be more if borrow returns
* a pointer to an internal buffer, rather than buf.
* If borrow fails, the contents of *len are undefined.
* @return If the borrow succeeds, return a pointer to the borrowed data.
* This might be equal to \c buf, or it might be a pointer into
* the transport's internal buffers.
* @throws TTransportException if an error occurs
*/
const uint8_t* borrow(uint8_t* buf, uint32_t* len)
{
T_VIRTUAL_CALL();
return borrow_virt(buf, len);
}
virtual const uint8_t* borrow_virt(uint8_t* /* buf */, uint32_t* /* len */)
{
return NULL;
}
/**
* Remove len bytes from the transport. This should always follow a borrow
* of at least len bytes, and should always succeed.
* TODO(dreiss): Is there any transport that could borrow but fail to
* consume, or that would require a buffer to dump the consumed data?
*
* @param len How many bytes to consume
* @throws TTransportException If an error occurs
*/
void consume(uint32_t len)
{
T_VIRTUAL_CALL();
consume_virt(len);
}
virtual void consume_virt(uint32_t /* len */)
{
throw TTransportException(TTransportException::NOT_OPEN,
"Base TTransport cannot consume.");
}
protected:
/**
* Simple constructor.
*/
TTransport() {}
};
/**
* Generic factory class to make an input and output transport out of a
* source transport. Commonly used inside servers to make input and output
* streams out of raw clients.
*
*/
class TTransportFactory
{
public:
TTransportFactory() {}
virtual ~TTransportFactory() {}
/**
* Default implementation does nothing, just returns the transport given.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans)
{
return trans;
}
};
}
}
} // apache::thrift::transport

View File

@ -1,145 +0,0 @@
/*
* 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.
*/
#pragma once
#include <string>
#include <thrift/Thrift.h>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Class to encapsulate all the possible types of transport errors that may
* occur in various transport systems. This provides a sort of generic
* wrapper around the vague UNIX E_ error codes that lets a common code
* base of error handling to be used for various types of transports, i.e.
* pipes etc.
*
*/
class TTransportException : public apache::thrift::TException
{
public:
/**
* Error codes for the various types of exceptions.
*/
enum TTransportExceptionType
{
UNKNOWN = 0
, NOT_OPEN = 1
, TIMED_OUT = 2
, END_OF_FILE = 3
, INTERRUPTED = 4
, BAD_ARGS = 5
, CORRUPTED_DATA = 6
, INTERNAL_ERROR = 7
};
TTransportException() :
apache::thrift::TException(),
type_(UNKNOWN) {}
TTransportException(TTransportExceptionType type) :
apache::thrift::TException(),
type_(type) {}
TTransportException(const std::string& message) :
apache::thrift::TException(message),
type_(UNKNOWN) {}
TTransportException(TTransportExceptionType type, const std::string& message) :
apache::thrift::TException(message),
type_(type) {}
TTransportException(TTransportExceptionType type,
const std::string& message,
int errno_copy) :
apache::thrift::TException(message + ": " + TOutput::strerror_s(errno_copy)),
type_(type) {}
virtual ~TTransportException() throw() {}
/**
* Returns an error code that provides information about the type of error
* that has occurred.
*
* @return Error code
*/
TTransportExceptionType getType() const throw()
{
return type_;
}
virtual const char* what() const throw()
{
if (message_.empty())
{
switch (type_)
{
case UNKNOWN :
return "TTransportException: Unknown transport exception";
case NOT_OPEN :
return "TTransportException: Transport not open";
case TIMED_OUT :
return "TTransportException: Timed out";
case END_OF_FILE :
return "TTransportException: End of file";
case INTERRUPTED :
return "TTransportException: Interrupted";
case BAD_ARGS :
return "TTransportException: Invalid arguments";
case CORRUPTED_DATA :
return "TTransportException: Corrupted Data";
case INTERNAL_ERROR :
return "TTransportException: Internal error";
default :
return "TTransportException: (Invalid exception type)";
}
}
else
{
return message_.c_str();
}
}
protected:
/** Just like strerror_r but returns a C++ string object. */
std::string strerror_s(int errno_copy);
/** Error code */
TTransportExceptionType type_;
};
}
}
} // apache::thrift::transport

View File

@ -1,387 +0,0 @@
/*
* 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.
*/
#pragma once
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <thrift/transport/TTransport.h>
// Include the buffered transports that used to be defined here.
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TFileTransport.h>
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* The null transport is a dummy transport that doesn't actually do anything.
* It's sort of an analogy to /dev/null, you can never read anything from it
* and it will let you write anything you want to it, though it won't actually
* go anywhere.
*
*/
class TNullTransport : public TVirtualTransport<TNullTransport>
{
public:
TNullTransport() {}
~TNullTransport() {}
bool isOpen()
{
return true;
}
void open() {}
void write(const uint8_t* /* buf */, uint32_t /* len */)
{
return;
}
};
/**
* TPipedTransport. This transport allows piping of a request from one
* transport to another either when readEnd() or writeEnd(). The typical
* use case for this is to log a request or a reply to disk.
* The underlying buffer expands to a keep a copy of the entire
* request/response.
*
*/
class TPipedTransport : virtual public TTransport
{
public:
TPipedTransport(boost::shared_ptr<TTransport> srcTrans,
boost::shared_ptr<TTransport> dstTrans) :
srcTrans_(srcTrans),
dstTrans_(dstTrans),
rBufSize_(512), rPos_(0), rLen_(0),
wBufSize_(512), wLen_(0)
{
// default is to to pipe the request when readEnd() is called
pipeOnRead_ = true;
pipeOnWrite_ = false;
rBuf_ = (uint8_t*) std::malloc(sizeof(uint8_t) * rBufSize_);
if (rBuf_ == NULL)
{
throw std::bad_alloc();
}
wBuf_ = (uint8_t*) std::malloc(sizeof(uint8_t) * wBufSize_);
if (wBuf_ == NULL)
{
throw std::bad_alloc();
}
}
TPipedTransport(boost::shared_ptr<TTransport> srcTrans,
boost::shared_ptr<TTransport> dstTrans,
uint32_t sz) :
srcTrans_(srcTrans),
dstTrans_(dstTrans),
rBufSize_(512), rPos_(0), rLen_(0),
wBufSize_(sz), wLen_(0)
{
rBuf_ = (uint8_t*) std::malloc(sizeof(uint8_t) * rBufSize_);
if (rBuf_ == NULL)
{
throw std::bad_alloc();
}
wBuf_ = (uint8_t*) std::malloc(sizeof(uint8_t) * wBufSize_);
if (wBuf_ == NULL)
{
throw std::bad_alloc();
}
}
~TPipedTransport()
{
std::free(rBuf_);
std::free(wBuf_);
}
bool isOpen()
{
return srcTrans_->isOpen();
}
bool peek()
{
if (rPos_ >= rLen_)
{
// Double the size of the underlying buffer if it is full
if (rLen_ == rBufSize_)
{
rBufSize_ *= 2;
rBuf_ = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_);
}
// try to fill up the buffer
rLen_ += srcTrans_->read(rBuf_ + rPos_, rBufSize_ - rPos_);
}
return (rLen_ > rPos_);
}
void open()
{
srcTrans_->open();
}
void close()
{
srcTrans_->close();
}
void setPipeOnRead(bool pipeVal)
{
pipeOnRead_ = pipeVal;
}
void setPipeOnWrite(bool pipeVal)
{
pipeOnWrite_ = pipeVal;
}
uint32_t read(uint8_t* buf, uint32_t len);
uint32_t readEnd()
{
if (pipeOnRead_)
{
dstTrans_->write(rBuf_, rPos_);
dstTrans_->flush();
}
srcTrans_->readEnd();
// If requests are being pipelined, copy down our read-ahead data,
// then reset our state.
int read_ahead = rLen_ - rPos_;
uint32_t bytes = rPos_;
memcpy(rBuf_, rBuf_ + rPos_, read_ahead);
rPos_ = 0;
rLen_ = read_ahead;
return bytes;
}
void write(const uint8_t* buf, uint32_t len);
uint32_t writeEnd()
{
if (pipeOnWrite_)
{
dstTrans_->write(wBuf_, wLen_);
dstTrans_->flush();
}
return wLen_;
}
void flush();
boost::shared_ptr<TTransport> getTargetTransport()
{
return dstTrans_;
}
/*
* Override TTransport *_virt() functions to invoke our implementations.
* We cannot use TVirtualTransport to provide these, since we need to inherit
* virtually from TTransport.
*/
virtual uint32_t read_virt(uint8_t* buf, uint32_t len)
{
return this->read(buf, len);
}
virtual void write_virt(const uint8_t* buf, uint32_t len)
{
this->write(buf, len);
}
protected:
boost::shared_ptr<TTransport> srcTrans_;
boost::shared_ptr<TTransport> dstTrans_;
uint8_t* rBuf_;
uint32_t rBufSize_;
uint32_t rPos_;
uint32_t rLen_;
uint8_t* wBuf_;
uint32_t wBufSize_;
uint32_t wLen_;
bool pipeOnRead_;
bool pipeOnWrite_;
};
/**
* Wraps a transport into a pipedTransport instance.
*
*/
class TPipedTransportFactory : public TTransportFactory
{
public:
TPipedTransportFactory() {}
TPipedTransportFactory(boost::shared_ptr<TTransport> dstTrans)
{
initializeTargetTransport(dstTrans);
}
virtual ~TPipedTransportFactory() {}
/**
* Wraps the base transport into a piped transport.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> srcTrans)
{
return boost::shared_ptr<TTransport>(new TPipedTransport(srcTrans, dstTrans_));
}
virtual void initializeTargetTransport(boost::shared_ptr<TTransport> dstTrans)
{
if (dstTrans_.get() == NULL)
{
dstTrans_ = dstTrans;
}
else
{
throw TException("Target transport already initialized");
}
}
protected:
boost::shared_ptr<TTransport> dstTrans_;
};
/**
* TPipedFileTransport. This is just like a TTransport, except that
* it is a templatized class, so that clients who rely on a specific
* TTransport can still access the original transport.
*
*/
class TPipedFileReaderTransport : public TPipedTransport,
public TFileReaderTransport
{
public:
TPipedFileReaderTransport(boost::shared_ptr<TFileReaderTransport> srcTrans, boost::shared_ptr<TTransport> dstTrans);
~TPipedFileReaderTransport();
// TTransport functions
bool isOpen();
bool peek();
void open();
void close();
uint32_t read(uint8_t* buf, uint32_t len);
uint32_t readAll(uint8_t* buf, uint32_t len);
uint32_t readEnd();
void write(const uint8_t* buf, uint32_t len);
uint32_t writeEnd();
void flush();
// TFileReaderTransport functions
int32_t getReadTimeout();
void setReadTimeout(int32_t readTimeout);
uint32_t getNumChunks();
uint32_t getCurChunk();
void seekToChunk(int32_t chunk);
void seekToEnd();
/*
* Override TTransport *_virt() functions to invoke our implementations.
* We cannot use TVirtualTransport to provide these, since we need to inherit
* virtually from TTransport.
*/
virtual uint32_t read_virt(uint8_t* buf, uint32_t len)
{
return this->read(buf, len);
}
virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len)
{
return this->readAll(buf, len);
}
virtual void write_virt(const uint8_t* buf, uint32_t len)
{
this->write(buf, len);
}
protected:
// shouldn't be used
TPipedFileReaderTransport();
boost::shared_ptr<TFileReaderTransport> srcTrans_;
};
/**
* Creates a TPipedFileReaderTransport from a filepath and a destination transport
*
*/
class TPipedFileReaderTransportFactory : public TPipedTransportFactory
{
public:
TPipedFileReaderTransportFactory() {}
TPipedFileReaderTransportFactory(boost::shared_ptr<TTransport> dstTrans)
: TPipedTransportFactory(dstTrans)
{}
virtual ~TPipedFileReaderTransportFactory() {}
boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> srcTrans)
{
boost::shared_ptr<TFileReaderTransport> pFileReaderTransport = boost::dynamic_pointer_cast<TFileReaderTransport>(srcTrans);
if (pFileReaderTransport.get() != NULL)
{
return getFileReaderTransport(pFileReaderTransport);
}
else
{
return boost::shared_ptr<TTransport>();
}
}
boost::shared_ptr<TFileReaderTransport> getFileReaderTransport(boost::shared_ptr<TFileReaderTransport> srcTrans)
{
return boost::shared_ptr<TFileReaderTransport>(new TPipedFileReaderTransport(srcTrans, dstTrans_));
}
};
}
}
} // apache::thrift::transport

View File

@ -1,164 +0,0 @@
/*
* 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.
*/
#pragma once
#include <thrift/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().)
*/
class TTransportDefaults : public TTransport
{
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>
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

View File

@ -1,276 +0,0 @@
/*
* 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.
*/
#pragma once
#include <boost/lexical_cast.hpp>
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TVirtualTransport.h>
#include <zlib.h>
struct z_stream_s;
namespace apache
{
namespace thrift
{
namespace transport
{
class TZlibTransportException : public TTransportException
{
public:
TZlibTransportException(int status, const char* msg) :
TTransportException(TTransportException::INTERNAL_ERROR,
errorMessage(status, msg)),
zlib_status_(status),
zlib_msg_(msg == NULL ? "(null)" : msg) {}
virtual ~TZlibTransportException() throw() {}
int getZlibStatus()
{
return zlib_status_;
}
std::string getZlibMessage()
{
return zlib_msg_;
}
static std::string errorMessage(int status, const char* msg)
{
std::string rv = "zlib error: ";
if (msg)
{
rv += msg;
}
else
{
rv += "(no message)";
}
rv += " (status = ";
rv += boost::lexical_cast<std::string>(status);
rv += ")";
return rv;
}
int zlib_status_;
std::string zlib_msg_;
};
/**
* This transport uses zlib to compress on write and decompress on read
*
* TODO(dreiss): Don't do an extra copy of the compressed data if
* the underlying transport is TBuffered or TMemory.
*
*/
class TZlibTransport : public TVirtualTransport<TZlibTransport>
{
public:
/**
* @param transport The transport to read compressed data from
* and write compressed data to.
* @param urbuf_size Uncompressed buffer size for reading.
* @param crbuf_size Compressed buffer size for reading.
* @param uwbuf_size Uncompressed buffer size for writing.
* @param cwbuf_size Compressed buffer size for writing.
* @param comp_level Compression level (0=none[fast], 6=default, 9=max[slow]).
*/
TZlibTransport(boost::shared_ptr<TTransport> transport,
int urbuf_size = DEFAULT_URBUF_SIZE,
int crbuf_size = DEFAULT_CRBUF_SIZE,
int uwbuf_size = DEFAULT_UWBUF_SIZE,
int cwbuf_size = DEFAULT_CWBUF_SIZE,
int16_t comp_level = Z_DEFAULT_COMPRESSION) :
transport_(transport),
urpos_(0),
uwpos_(0),
input_ended_(false),
output_finished_(false),
urbuf_size_(urbuf_size),
crbuf_size_(crbuf_size),
uwbuf_size_(uwbuf_size),
cwbuf_size_(cwbuf_size),
urbuf_(NULL),
crbuf_(NULL),
uwbuf_(NULL),
cwbuf_(NULL),
rstream_(NULL),
wstream_(NULL),
comp_level_(comp_level)
{
if (uwbuf_size_ < MIN_DIRECT_DEFLATE_SIZE)
{
// Have to copy this into a local because of a linking issue.
int minimum = MIN_DIRECT_DEFLATE_SIZE;
throw TTransportException(
TTransportException::BAD_ARGS,
"TZLibTransport: uncompressed write buffer must be at least"
+ boost::lexical_cast<std::string>(minimum) + ".");
}
try
{
urbuf_ = new uint8_t[urbuf_size];
crbuf_ = new uint8_t[crbuf_size];
uwbuf_ = new uint8_t[uwbuf_size];
cwbuf_ = new uint8_t[cwbuf_size];
// Don't call this outside of the constructor.
initZlib();
}
catch (...)
{
delete[] urbuf_;
delete[] crbuf_;
delete[] uwbuf_;
delete[] cwbuf_;
throw;
}
}
// Don't call this outside of the constructor.
void initZlib();
/**
* TZlibTransport destructor.
*
* Warning: Destroying a TZlibTransport object may discard any written but
* unflushed data. You must explicitly call flush() or finish() to ensure
* that data is actually written and flushed to the underlying transport.
*/
~TZlibTransport();
bool isOpen();
bool peek();
void open()
{
transport_->open();
}
void close()
{
transport_->close();
}
uint32_t read(uint8_t* buf, uint32_t len);
void write(const uint8_t* buf, uint32_t len);
void flush();
/**
* Finalize the zlib stream.
*
* This causes zlib to flush any pending write data and write end-of-stream
* information, including the checksum. Once finish() has been called, no
* new data can be written to the stream.
*/
void finish();
const uint8_t* borrow(uint8_t* buf, uint32_t* len);
void consume(uint32_t len);
/**
* Verify the checksum at the end of the zlib stream.
*
* This may only be called after all data has been read.
* It verifies the checksum that was written by the finish() call.
*/
void verifyChecksum();
/**
* TODO(someone_smart): Choose smart defaults.
*/
static const int DEFAULT_URBUF_SIZE = 128;
static const int DEFAULT_CRBUF_SIZE = 1024;
static const int DEFAULT_UWBUF_SIZE = 128;
static const int DEFAULT_CWBUF_SIZE = 1024;
protected:
inline void checkZlibRv(int status, const char* msg);
inline void checkZlibRvNothrow(int status, const char* msg);
inline int readAvail();
void flushToTransport(int flush);
void flushToZlib(const uint8_t* buf, int len, int flush);
bool readFromZlib();
protected:
// Writes smaller than this are buffered up.
// Larger (or equal) writes are dumped straight to zlib.
static const uint32_t MIN_DIRECT_DEFLATE_SIZE = 32;
boost::shared_ptr<TTransport> transport_;
int urpos_;
int uwpos_;
/// True iff zlib has reached the end of the input stream.
bool input_ended_;
/// True iff we have finished the output stream.
bool output_finished_;
uint32_t urbuf_size_;
uint32_t crbuf_size_;
uint32_t uwbuf_size_;
uint32_t cwbuf_size_;
uint8_t* urbuf_;
uint8_t* crbuf_;
uint8_t* uwbuf_;
uint8_t* cwbuf_;
struct z_stream_s* rstream_;
struct z_stream_s* wstream_;
const int comp_level_;
};
/**
* Wraps a transport into a zlibbed one.
*
*/
class TZlibTransportFactory : public TTransportFactory
{
public:
TZlibTransportFactory() {}
virtual ~TZlibTransportFactory() {}
virtual boost::shared_ptr<TTransport> getTransport(
boost::shared_ptr<TTransport> trans)
{
return boost::shared_ptr<TTransport>(new TZlibTransport(trans));
}
};
}
}
} // apache::thrift::transport

View File

@ -1,114 +0,0 @@
/*
* 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.
*/
#include <thrift/windows/GetTimeOfDay.h>
#include <thrift/thrift-config.h>
// win32
#include <time.h>
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
# define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
# define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int thrift_gettimeofday(struct timeval* tv, struct timezone* tz)
{
FILETIME ft;
unsigned __int64 tmpres(0);
static int tzflag;
if (NULL != tv)
{
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tmpres /= 10; /*convert into microseconds*/
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
if (NULL != tz)
{
if (!tzflag)
{
_tzset();
tzflag++;
}
long time_zone(0);
errno_t err(_get_timezone(&time_zone));
if (err == NO_ERROR)
{
tz->tz_minuteswest = time_zone / 60;
}
else
{
return -1;
}
int day_light(0);
err = (_get_daylight(&day_light));
if (err == NO_ERROR)
{
tz->tz_dsttime = day_light;
return 0;
}
else
{
return -1;
}
}
return -1;
}
int thrift_sleep(unsigned int seconds)
{
::Sleep(seconds * 1000);
return 0;
}
int thrift_usleep(unsigned int microseconds)
{
unsigned int milliseconds = (microseconds + 999) / 1000;
::Sleep(milliseconds);
return 0;
}
char* thrift_ctime_r(const time_t* _clock, char* _buf)
{
strcpy(_buf, ctime(_clock));
return _buf;
}

View File

@ -1,42 +0,0 @@
/*
* 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.
*/
#pragma once
#if defined(_MSC_VER) && (_MSC_VER > 1200)
#pragma once
#endif // _MSC_VER
#ifndef _WIN32
#error This is a MSVC header only.
#endif
#include <thrift/thrift-config.h>
struct thrift_timespec
{
int64_t tv_sec;
int64_t tv_nsec;
};
int thrift_gettimeofday(struct timeval* tv, struct timezone* tz);
int thrift_sleep(unsigned int seconds);
int thrift_usleep(unsigned int micro_seconds);
char* thrift_ctime_r(const time_t* _clock, char* _buf);

View File

@ -1,42 +0,0 @@
/*
* 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.
*/
#pragma once
#if defined(_MSC_VER) && (_MSC_VER > 1200)
#pragma once
#endif // _MSC_VER
namespace apache
{
namespace thrift
{
class TEnumIterator;
inline bool operator == (const TEnumIterator&, const TEnumIterator&)
{
// Not entirely sure what the test should be here. It is only to enable
// iterator debugging and is not used in release mode.
return true;
}
}
} // apache::thrift

View File

@ -1,35 +0,0 @@
/*
* 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.
*/
#pragma once
#if defined(_MSC_VER) && (_MSC_VER > 1200)
#pragma once
#endif // _MSC_VER
#ifndef _WIN32
#error This is a MSVC header only.
#endif
// Win32
#include <Winsock2.h>
#include <thrift/thrift-config.h>
int thrift_socketpair(int d, int type, int protocol, THRIFT_SOCKET sv[2]);

View File

@ -1,81 +0,0 @@
/*
* 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.
*/
#include <thrift/windows/TWinsockSingleton.h>
// boost
#include <boost/assert.hpp>
#include <stdexcept>
namespace apache
{
namespace thrift
{
namespace transport
{
TWinsockSingleton::instance_ptr TWinsockSingleton::instance_ptr_(NULL);
#if USE_BOOST_THREAD
boost::once_flag TWinsockSingleton::flags_ = BOOST_ONCE_INIT;
#elif USE_STD_THREAD
std::once_flag TWinsockSingleton::flags_;
#else
#error For windows you must choose USE_BOOST_THREAD or USE_STD_THREAD
#endif
//------------------------------------------------------------------------------
TWinsockSingleton::TWinsockSingleton(void)
{
WORD version(MAKEWORD(2, 2));
WSAData data = {0};
int error(WSAStartup(version, &data));
if (error != 0)
{
BOOST_ASSERT(false);
throw std::runtime_error("Failed to initialise Winsock.");
}
}
//------------------------------------------------------------------------------
TWinsockSingleton::~TWinsockSingleton(void)
{
WSACleanup();
}
//------------------------------------------------------------------------------
void TWinsockSingleton::create(void)
{
#if USE_BOOST_THREAD
boost::call_once(init, flags_);
#elif USE_STD_THREAD
std::call_once(flags_, init);
#endif
}
//------------------------------------------------------------------------------
void TWinsockSingleton::init(void)
{
instance_ptr_.reset(new TWinsockSingleton);
}
}
}
} // apache::thrift::transport

View File

@ -1,93 +0,0 @@
/*
* 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.
*/
#pragma once
#if defined(_MSC_VER) && (_MSC_VER > 1200)
#pragma once
#endif // _MSC_VER
#ifndef _WIN32
#error This is a MSVC header only.
#endif
#include <thrift/thrift-config.h>
// boost
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#if USE_BOOST_THREAD
#include <boost/thread/once.hpp>
#elif USE_STD_THREAD
#include <mutex>
#else
#error For windows you must choose USE_BOOST_THREAD or USE_STD_THREAD
#endif
namespace apache
{
namespace thrift
{
namespace transport
{
/**
* Winsock2 must be intialised once only in order to create sockets. This class
* performs a one time initialisation when create is called.
*/
class TWinsockSingleton : private boost::noncopyable
{
public:
typedef boost::scoped_ptr<TWinsockSingleton> instance_ptr;
private:
TWinsockSingleton(void);
public:
~TWinsockSingleton(void);
public:
static void create(void);
private:
static void init(void);
private:
static instance_ptr instance_ptr_;
#if USE_BOOST_THREAD
static boost::once_flag flags_;
#elif USE_STD_THREAD
static std::once_flag flags_;
#else
#error Need a non-Boost non-C++11 way to track single initialization here.
#endif
};
}
}
} // apache::thrift::transport

View File

@ -1,117 +0,0 @@
/*
* 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.
*/
#include <thrift/windows/WinFcntl.h>
int thrift_fcntl(THRIFT_SOCKET fd, int cmd, int flags)
{
if (cmd != THRIFT_F_GETFL && cmd != THRIFT_F_SETFL)
{
return -1;
}
if (flags != THRIFT_O_NONBLOCK && flags != 0)
{
return -1;
}
if (cmd == THRIFT_F_GETFL)
{
return 0;
}
int res;
if (flags)
{
res = ioctlsocket(fd, FIONBIO, reinterpret_cast<u_long*>(&(flags = 1)));
}
else
{
res = ioctlsocket(fd, FIONBIO, reinterpret_cast<u_long*>(&(flags = 0)));
}
return res;
}
#if WINVER <= 0x0502 //XP, Server2003
int thrift_poll(THRIFT_POLLFD* fdArray, ULONG nfds, INT timeout)
{
fd_set read_fds, write_fds;
fd_set* read_fds_ptr = NULL;
fd_set* write_fds_ptr = NULL;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
for (ULONG i = 0; i < nfds; i++)
{
//Read (in) socket
if ((fdArray[i].events & THRIFT_POLLIN) == THRIFT_POLLIN)
{
read_fds_ptr = &read_fds;
FD_SET(fdArray[i].fd, &read_fds);
}
//Write (out) socket
else if ((fdArray[i].events & THRIFT_POLLOUT) == THRIFT_POLLOUT)
{
write_fds_ptr = &write_fds;
FD_SET(fdArray[i].fd, &write_fds);
}
}
timeval time_out;
timeval* time_out_ptr = NULL;
if (timeout >= 0)
{
timeval time_out = {timeout / 1000, timeout * 1000};
time_out_ptr = &time_out;
}
else //to avoid compiler warnings
{
(void)time_out;
(void)timeout;
}
int sktready = select(1, read_fds_ptr, write_fds_ptr, NULL, time_out_ptr);
if (sktready > 0)
{
for (ULONG i = 0; i < nfds; i++)
{
fdArray[i].revents = 0;
if (FD_ISSET(fdArray[i].fd, &read_fds))
fdArray[i].revents |= THRIFT_POLLIN;
if (FD_ISSET(fdArray[i].fd, &write_fds))
fdArray[i].revents |= THRIFT_POLLOUT;
}
}
return sktready;
}
#else //Vista, Win7...
int thrift_poll(THRIFT_POLLFD* fdArray, ULONG nfds, INT timeout)
{
return WSAPoll(fdArray, nfds, timeout);
}
#endif // WINVER

View File

@ -1,47 +0,0 @@
/*
* 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.
*/
#pragma once
#if defined(_MSC_VER) && (_MSC_VER > 1200)
#pragma once
#endif // _MSC_VER
#ifndef _WIN32
#error This is a MSVC header only.
#endif
// Win32
#include <Winsock2.h>
#include <thrift/transport/PlatformSocket.h>
#if WINVER <= 0x0502 //XP, Server2003
struct thrift_pollfd
{
THRIFT_SOCKET fd;
SHORT events;
SHORT revents;
};
#endif
extern "C" {
int thrift_fcntl(THRIFT_SOCKET fd, int cmd, int flags);
int thrift_poll(THRIFT_POLLFD* fdArray, ULONG nfds, INT timeout);
}

Some files were not shown because too many files have changed in this diff Show More