From: Roger Meier Date: Sat, 11 Feb 2012 19:09:30 +0000 (+0000) Subject: THRIFT-1348 C++ Qt bindings X-Git-Tag: 0.9.1~446 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=19a991528f8ed41319737ee758b79ae8b66cd9f7;p=common%2Fthrift.git THRIFT-1348 C++ Qt bindings Patch: Doug Rosvick qt-cleanup.patch applied git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1243124 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/lib/cpp/src/qt/TQIODeviceTransport.cpp b/lib/cpp/src/qt/TQIODeviceTransport.cpp index c5b53a8f..4172ed09 100644 --- a/lib/cpp/src/qt/TQIODeviceTransport.cpp +++ b/lib/cpp/src/qt/TQIODeviceTransport.cpp @@ -1,155 +1,157 @@ #include "TQIODeviceTransport.h" -#include - #include +#include -#include +#include +using boost::shared_ptr; + namespace apache { namespace thrift { namespace transport { - using boost::shared_ptr; - TQIODeviceTransport::TQIODeviceTransport(shared_ptr dev) - : dev_(dev) - { +TQIODeviceTransport::TQIODeviceTransport(shared_ptr dev) + : dev_(dev) +{ +} + +TQIODeviceTransport::~TQIODeviceTransport() +{ + dev_->close(); +} + +void TQIODeviceTransport::open() +{ + if (!isOpen()) { + throw TTransportException(TTransportException::NOT_OPEN, + "open(): underlying QIODevice isn't open"); } - - TQIODeviceTransport::~TQIODeviceTransport() - { - dev_->close(); - } - - void TQIODeviceTransport::open() - { - if (!isOpen()) { - throw TTransportException(TTransportException::NOT_OPEN, - "open(): underlying QIODevice isn't open"); - } - } - - bool TQIODeviceTransport::isOpen() - { - return dev_->isOpen(); - } - - bool TQIODeviceTransport::peek() - { - return dev_->bytesAvailable() > 0; - } - - void TQIODeviceTransport::close() - { - dev_->close(); - } - - uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len) { - uint32_t requestLen = len; - while (len) { - uint32_t readSize; - try { - readSize = read(buf, len); - } catch (...) { - if (len != requestLen) { - // something read already - return requestLen - len; - } - // error but nothing read yet - throw; - } - if (readSize == 0) { - // dev_->waitForReadyRead(50); - } else { - buf += readSize; - len -= readSize; +} + +bool TQIODeviceTransport::isOpen() +{ + return dev_->isOpen(); +} + +bool TQIODeviceTransport::peek() +{ + return dev_->bytesAvailable() > 0; +} + +void TQIODeviceTransport::close() +{ + dev_->close(); +} + +uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len) +{ + uint32_t requestLen = len; + while (len) { + uint32_t readSize; + try { + readSize = read(buf, len); + } catch (...) { + if (len != requestLen) { + // something read already + return requestLen - len; } + // error but nothing read yet + throw; + } + if (readSize == 0) { + dev_->waitForReadyRead(50); + } else { + buf += readSize; + len -= readSize; } - return requestLen; } + return requestLen; +} - uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len) - { - uint32_t actualSize; - qint64 readSize; +uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len) +{ + uint32_t actualSize; + qint64 readSize; - if (!dev_->isOpen()) { - throw TTransportException(TTransportException::NOT_OPEN, - "read(): underlying QIODevice is not open"); - } + if (!dev_->isOpen()) { + throw TTransportException(TTransportException::NOT_OPEN, + "read(): underlying QIODevice is not open"); + } - actualSize = (uint32_t)std::min((qint64)len, dev_->bytesAvailable()); - readSize = dev_->read(reinterpret_cast(buf), len); + actualSize = (uint32_t)std::min((qint64)len, dev_->bytesAvailable()); + readSize = dev_->read(reinterpret_cast(buf), actualSize); - if (readSize < 0) { - QAbstractSocket* socket; - if ((socket = qobject_cast(dev_.get()))) { - throw TTransportException(TTransportException::UNKNOWN, - "Failed to read() from QAbstractSocket", - socket->error()); - } + if (readSize < 0) { + QAbstractSocket* socket; + if ((socket = qobject_cast(dev_.get()))) { throw TTransportException(TTransportException::UNKNOWN, - "Failed to read from from QIODevice"); + "Failed to read() from QAbstractSocket", + socket->error()); } - - return (uint32_t)readSize; + throw TTransportException(TTransportException::UNKNOWN, + "Failed to read from from QIODevice"); } - void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len) - { - while (len) { - uint32_t written = write_partial(buf, len); - len -= written; - // dev_->waitForBytesWritten(50); - } - } + return (uint32_t)readSize; +} - uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len) - { - qint64 written; +void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len) +{ + while (len) { + uint32_t written = write_partial(buf, len); + len -= written; + dev_->waitForBytesWritten(50); + } +} - if (!dev_->isOpen()) { - throw TTransportException(TTransportException::NOT_OPEN, - "write_partial(): underlying QIODevice is not open"); - } +uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len) +{ + qint64 written; - written = dev_->write(reinterpret_cast(buf), len); - if (written < 0) { - QAbstractSocket* socket; - if ((socket = qobject_cast(dev_.get()))) { - throw TTransportException(TTransportException::UNKNOWN, - "write_partial(): failed to write to QAbstractSocket", socket->error()); - } + if (!dev_->isOpen()) { + throw TTransportException(TTransportException::NOT_OPEN, + "write_partial(): underlying QIODevice is not open"); + } + written = dev_->write(reinterpret_cast(buf), len); + if (written < 0) { + QAbstractSocket* socket; + if ((socket = qobject_cast(dev_.get()))) { throw TTransportException(TTransportException::UNKNOWN, - "write_partial(): failed to write to underlying QIODevice"); + "write_partial(): failed to write to QAbstractSocket", socket->error()); } - return (uint32_t)written; + throw TTransportException(TTransportException::UNKNOWN, + "write_partial(): failed to write to underlying QIODevice"); } - void TQIODeviceTransport::flush() - { - if (!dev_->isOpen()) { - throw TTransportException(TTransportException::NOT_OPEN, - "flush(): underlying QIODevice is not open"); - } - - QAbstractSocket* socket; + return (uint32_t)written; +} - if ((socket = qobject_cast(dev_.get()))) { - socket->flush(); - } else { - dev_->waitForBytesWritten(1); - } +void TQIODeviceTransport::flush() +{ + if (!dev_->isOpen()) { + throw TTransportException(TTransportException::NOT_OPEN, + "flush(): underlying QIODevice is not open"); } - uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len) - { - return NULL; - } + QAbstractSocket* socket; - void TQIODeviceTransport::consume(uint32_t len) - { - throw TTransportException(TTransportException::UNKNOWN); + if ((socket = qobject_cast(dev_.get()))) { + socket->flush(); + } else { + dev_->waitForBytesWritten(1); } +} + +uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len) +{ + return NULL; +} + +void TQIODeviceTransport::consume(uint32_t len) +{ + throw TTransportException(TTransportException::UNKNOWN); +} + }}} // apache::thrift::transport diff --git a/lib/cpp/src/qt/TQIODeviceTransport.h b/lib/cpp/src/qt/TQIODeviceTransport.h index 8ce7c782..5ee8f6d5 100644 --- a/lib/cpp/src/qt/TQIODeviceTransport.h +++ b/lib/cpp/src/qt/TQIODeviceTransport.h @@ -1,47 +1,44 @@ #ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ #define _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ 1 -#include - #include #include -namespace apache { namespace thrift { namespace protocol { -class TProtocol; -}}} // apache::thrift::protocol +class QIODevice; namespace apache { namespace thrift { namespace transport { - class TQIODeviceTransport : public apache::thrift::transport::TVirtualTransport { - public: - explicit TQIODeviceTransport(boost::shared_ptr dev); - ~TQIODeviceTransport(); - - void open(); - - bool isOpen(); - - bool peek(); - - void close(); - - uint32_t readAll(uint8_t *buf, uint32_t len); +/** + * Transport that operates on a QIODevice (socket, file, etc). + */ +class TQIODeviceTransport : public apache::thrift::transport::TVirtualTransport { + public: + explicit TQIODeviceTransport(boost::shared_ptr dev); + virtual ~TQIODeviceTransport(); - uint32_t read(uint8_t* buf, uint32_t len); + void open(); + bool isOpen(); + bool peek(); + void close(); - void write(const uint8_t* buf, uint32_t len); + uint32_t readAll(uint8_t *buf, uint32_t len); + uint32_t read(uint8_t* buf, uint32_t len); - uint32_t write_partial(const 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(); + void flush(); - uint8_t* borrow(uint8_t* buf, uint32_t* len); - void consume(uint32_t len); + uint8_t* borrow(uint8_t* buf, uint32_t* len); + void consume(uint32_t len); - private: - boost::shared_ptr dev_; - }; + private: + TQIODeviceTransport(const TQIODeviceTransport&); + TQIODeviceTransport& operator=(const TQIODeviceTransport&); + + boost::shared_ptr dev_; +}; }}} // apache::thrift::transport #endif // #ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ diff --git a/lib/cpp/src/qt/TQTcpServer.cpp b/lib/cpp/src/qt/TQTcpServer.cpp index 65ad68dc..733a3d81 100644 --- a/lib/cpp/src/qt/TQTcpServer.cpp +++ b/lib/cpp/src/qt/TQTcpServer.cpp @@ -1,11 +1,13 @@ -#include "TQTcpServer.h" -#include -#include +#include "TQTcpServer.h" +#include "TQIODeviceTransport.h" #include -#include "TQIODeviceTransport.h" +#include + +#include +#include using boost::shared_ptr; using apache::thrift::protocol::TProtocol; @@ -91,8 +93,7 @@ void TQTcpServer::beginDecode() QTcpSocket* connection(qobject_cast(sender())); Q_ASSERT(connection); - if (ctxMap_.find(connection) == ctxMap_.end()) - { + if (ctxMap_.find(connection) == ctxMap_.end()) { qWarning("[TQTcpServer] Got data on an unknown QTcpSocket"); return; } @@ -119,8 +120,7 @@ void TQTcpServer::socketClosed() QTcpSocket* connection(qobject_cast(sender())); Q_ASSERT(connection); - if (ctxMap_.find(connection) == ctxMap_.end()) - { + if (ctxMap_.find(connection) == ctxMap_.end()) { qWarning("[TQTcpServer] Unknown QTcpSocket closed"); return; } @@ -130,8 +130,7 @@ void TQTcpServer::socketClosed() void TQTcpServer::finish(shared_ptr ctx, bool healthy) { - if (!healthy) - { + if (!healthy) { qWarning("[TQTcpServer] Processor failed to process data successfully"); ctxMap_.erase(ctx->connection_.get()); } diff --git a/lib/cpp/src/qt/TQTcpServer.h b/lib/cpp/src/qt/TQTcpServer.h index 82bec399..78383575 100644 --- a/lib/cpp/src/qt/TQTcpServer.h +++ b/lib/cpp/src/qt/TQTcpServer.h @@ -6,10 +6,7 @@ #include -#include - namespace apache { namespace thrift { namespace protocol { -class TProtocol; class TProtocolFactory; }}} // apache::thrift::protocol @@ -17,6 +14,11 @@ 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: @@ -32,6 +34,9 @@ class TQTcpServer : public QObject { void socketClosed(); private: + TQTcpServer(const TQTcpServer&); + TQTcpServer& operator=(const TQTcpServer&); + class ConnectionContext; void finish(boost::shared_ptr ctx, bool healthy);