src/protocol/TJSONProtocol.cpp \
src/protocol/TBase64Utils.cpp \
src/transport/TTransportException.cpp \
+ src/transport/TFDTransport.cpp \
src/transport/TFileTransport.cpp \
src/transport/THttpClient.cpp \
src/transport/TSocket.cpp \
include_transportdir = $(include_thriftdir)/transport
include_transport_HEADERS = \
+ src/transport/TFDTransport.h \
src/transport/TFileTransport.h \
src/transport/TServerSocket.h \
src/transport/TServerTransport.h \
--- /dev/null
+// Copyright (c) 2006- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#include <cerrno>
+#include <exception>
+
+#include <transport/TFDTransport.h>
+
+#include <unistd.h>
+
+using namespace std;
+
+namespace facebook { namespace thrift { namespace transport {
+
+void TFDTransport::close() {
+ if (!isOpen()) {
+ return;
+ }
+
+ int rv = ::close(fd_);
+ int errno_copy = errno;
+ fd_ = -1;
+ // Have to check uncaught_exception because this is called in the destructor.
+ if (rv < 0 && !std::uncaught_exception()) {
+ throw TTransportException(TTransportException::UNKNOWN,
+ "TFDTransport::close()",
+ errno_copy);
+ }
+}
+
+uint32_t TFDTransport::read(uint8_t* buf, uint32_t len) {
+ ssize_t rv = ::read(fd_, buf, len);
+ if (rv < 0) {
+ int errno_copy = errno;
+ throw TTransportException(TTransportException::UNKNOWN,
+ "TFDTransport::read()",
+ errno_copy);
+ }
+ return rv;
+}
+
+void TFDTransport::write(const uint8_t* buf, uint32_t len) {
+ while (len > 0) {
+ ssize_t rv = ::write(fd_, buf, len);
+
+ if (rv < 0) {
+ int errno_copy = errno;
+ throw TTransportException(TTransportException::UNKNOWN,
+ "TFDTransport::write()",
+ errno_copy);
+ } else if (rv == 0) {
+ throw TTransportException(TTransportException::END_OF_FILE,
+ "TFDTransport::write()");
+ }
+
+ buf += rv;
+ len -= rv;
+ }
+}
+
+}}} // facebook::thrift::transport
--- /dev/null
+// Copyright (c) 2006- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#ifndef _THRIFT_TRANSPORT_TFDTRANSPORT_H_
+#define _THRIFT_TRANSPORT_TFDTRANSPORT_H_ 1
+
+#include <string>
+#include <sys/time.h>
+
+#include "TTransport.h"
+#include "TServerSocket.h"
+
+namespace facebook { namespace thrift { namespace transport {
+
+/**
+ * Dead-simple wrapper around a file descriptor.
+ *
+ * @author David Reiss <dreiss@facebook.com>
+ */
+class TFDTransport : public TTransport {
+ 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_;
+};
+
+}}} // facebook::thrift::transport
+
+#endif // #ifndef _THRIFT_TRANSPORT_TFDTRANSPORT_H_
Benchmark_LDADD = libtestgencpp.la
check_PROGRAMS = \
+ TFDTransportTest \
DebugProtoTest \
JSONProtoTest \
OptionalRequiredTest \
UnitTests_LDADD = libtestgencpp.la
+#
+# TFDTransportTest
+#
+TFDTransportTest_SOURCES = \
+ TFDTransportTest.cpp
+
+TFDTransportTest_LDADD = \
+ $(top_srcdir)/lib/cpp/libthrift.la
+
#
# DebugProtoTest
#
--- /dev/null
+#include <cstdlib>
+#include <stdexcept>
+#include <Thrift.h>
+#include <transport/TFDTransport.h>
+using facebook::thrift::transport::TTransportException;
+using facebook::thrift::transport::TFDTransport;
+
+class DummyException : std::exception {
+};
+
+int main() {
+ {
+ TFDTransport t(256, TFDTransport::NO_CLOSE_ON_DESTROY);
+ }
+
+ try {
+ {
+ TFDTransport t(256, TFDTransport::CLOSE_ON_DESTROY);
+ }
+ std::abort();
+ } catch (TTransportException) {
+ }
+
+ try {
+ {
+ TFDTransport t(256, TFDTransport::CLOSE_ON_DESTROY);
+ throw DummyException();
+ }
+ std::abort();
+ } catch (TTransportException&) {
+ abort();
+ } catch (DummyException&) {
+ }
+
+ return 0;
+
+}