blob: 4172ed098e2a8d23031244046e91033588900aec [file] [log] [blame]
Roger Meier86e89862012-02-10 19:53:20 +00001#include "TQIODeviceTransport.h"
2
Roger Meier19a99152012-02-11 19:09:30 +00003#include <QAbstractSocket>
4#include <QIODevice>
5
Roger Meier86e89862012-02-10 19:53:20 +00006#include <transport/TBufferTransports.h>
7
Roger Meier19a99152012-02-11 19:09:30 +00008using boost::shared_ptr;
9
Roger Meier86e89862012-02-10 19:53:20 +000010namespace apache { namespace thrift { namespace transport {
Roger Meier86e89862012-02-10 19:53:20 +000011
Roger Meier19a99152012-02-11 19:09:30 +000012TQIODeviceTransport::TQIODeviceTransport(shared_ptr<QIODevice> dev)
13 : dev_(dev)
14{
15}
16
17TQIODeviceTransport::~TQIODeviceTransport()
18{
19 dev_->close();
20}
21
22void TQIODeviceTransport::open()
23{
24 if (!isOpen()) {
25 throw TTransportException(TTransportException::NOT_OPEN,
26 "open(): underlying QIODevice isn't open");
Roger Meier86e89862012-02-10 19:53:20 +000027 }
Roger Meier19a99152012-02-11 19:09:30 +000028}
Roger Meier86e89862012-02-10 19:53:20 +000029
Roger Meier19a99152012-02-11 19:09:30 +000030bool TQIODeviceTransport::isOpen()
31{
32 return dev_->isOpen();
33}
Roger Meier86e89862012-02-10 19:53:20 +000034
Roger Meier19a99152012-02-11 19:09:30 +000035bool TQIODeviceTransport::peek()
36{
37 return dev_->bytesAvailable() > 0;
38}
Roger Meier86e89862012-02-10 19:53:20 +000039
Roger Meier19a99152012-02-11 19:09:30 +000040void TQIODeviceTransport::close()
41{
42 dev_->close();
43}
Roger Meier86e89862012-02-10 19:53:20 +000044
Roger Meier19a99152012-02-11 19:09:30 +000045uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len)
46{
47 uint32_t requestLen = len;
48 while (len) {
49 uint32_t readSize;
50 try {
51 readSize = read(buf, len);
52 } catch (...) {
53 if (len != requestLen) {
54 // something read already
55 return requestLen - len;
Roger Meier86e89862012-02-10 19:53:20 +000056 }
Roger Meier19a99152012-02-11 19:09:30 +000057 // error but nothing read yet
58 throw;
Roger Meier86e89862012-02-10 19:53:20 +000059 }
Roger Meier19a99152012-02-11 19:09:30 +000060 if (readSize == 0) {
61 dev_->waitForReadyRead(50);
Roger Meier86e89862012-02-10 19:53:20 +000062 } else {
Roger Meier19a99152012-02-11 19:09:30 +000063 buf += readSize;
64 len -= readSize;
Roger Meier86e89862012-02-10 19:53:20 +000065 }
66 }
Roger Meier19a99152012-02-11 19:09:30 +000067 return requestLen;
68}
Roger Meier86e89862012-02-10 19:53:20 +000069
Roger Meier19a99152012-02-11 19:09:30 +000070uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len)
71{
72 uint32_t actualSize;
73 qint64 readSize;
74
75 if (!dev_->isOpen()) {
76 throw TTransportException(TTransportException::NOT_OPEN,
77 "read(): underlying QIODevice is not open");
Roger Meier86e89862012-02-10 19:53:20 +000078 }
79
Roger Meier19a99152012-02-11 19:09:30 +000080 actualSize = (uint32_t)std::min((qint64)len, dev_->bytesAvailable());
81 readSize = dev_->read(reinterpret_cast<char *>(buf), actualSize);
82
83 if (readSize < 0) {
84 QAbstractSocket* socket;
85 if ((socket = qobject_cast<QAbstractSocket* >(dev_.get()))) {
86 throw TTransportException(TTransportException::UNKNOWN,
87 "Failed to read() from QAbstractSocket",
88 socket->error());
89 }
90 throw TTransportException(TTransportException::UNKNOWN,
91 "Failed to read from from QIODevice");
Roger Meier86e89862012-02-10 19:53:20 +000092 }
Roger Meier19a99152012-02-11 19:09:30 +000093
94 return (uint32_t)readSize;
95}
96
97void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len)
98{
99 while (len) {
100 uint32_t written = write_partial(buf, len);
101 len -= written;
102 dev_->waitForBytesWritten(50);
103 }
104}
105
106uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len)
107{
108 qint64 written;
109
110 if (!dev_->isOpen()) {
111 throw TTransportException(TTransportException::NOT_OPEN,
112 "write_partial(): underlying QIODevice is not open");
113 }
114
115 written = dev_->write(reinterpret_cast<const char*>(buf), len);
116 if (written < 0) {
117 QAbstractSocket* socket;
118 if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
119 throw TTransportException(TTransportException::UNKNOWN,
120 "write_partial(): failed to write to QAbstractSocket", socket->error());
121 }
122
123 throw TTransportException(TTransportException::UNKNOWN,
124 "write_partial(): failed to write to underlying QIODevice");
125 }
126
127 return (uint32_t)written;
128}
129
130void TQIODeviceTransport::flush()
131{
132 if (!dev_->isOpen()) {
133 throw TTransportException(TTransportException::NOT_OPEN,
134 "flush(): underlying QIODevice is not open");
135 }
136
137 QAbstractSocket* socket;
138
139 if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
140 socket->flush();
141 } else {
142 dev_->waitForBytesWritten(1);
143 }
144}
145
146uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len)
147{
148 return NULL;
149}
150
151void TQIODeviceTransport::consume(uint32_t len)
152{
153 throw TTransportException(TTransportException::UNKNOWN);
154}
155
Roger Meier86e89862012-02-10 19:53:20 +0000156}}} // apache::thrift::transport
157