blob: c5b53a8f24c6c8274143605154e84117ed573c0d [file] [log] [blame]
Roger Meier86e89862012-02-10 19:53:20 +00001#include "TQIODeviceTransport.h"
2
3#include <transport/TBufferTransports.h>
4
5#include <QAbstractSocket>
6
7#include <iostream>
8
9namespace apache { namespace thrift { namespace transport {
10 using boost::shared_ptr;
11
12 TQIODeviceTransport::TQIODeviceTransport(shared_ptr<QIODevice> dev)
13 : dev_(dev)
14 {
15 }
16
17 TQIODeviceTransport::~TQIODeviceTransport()
18 {
19 dev_->close();
20 }
21
22 void TQIODeviceTransport::open()
23 {
24 if (!isOpen()) {
25 throw TTransportException(TTransportException::NOT_OPEN,
26 "open(): underlying QIODevice isn't open");
27 }
28 }
29
30 bool TQIODeviceTransport::isOpen()
31 {
32 return dev_->isOpen();
33 }
34
35 bool TQIODeviceTransport::peek()
36 {
37 return dev_->bytesAvailable() > 0;
38 }
39
40 void TQIODeviceTransport::close()
41 {
42 dev_->close();
43 }
44
45 uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len) {
46 uint32_t requestLen = len;
47 while (len) {
48 uint32_t readSize;
49 try {
50 readSize = read(buf, len);
51 } catch (...) {
52 if (len != requestLen) {
53 // something read already
54 return requestLen - len;
55 }
56 // error but nothing read yet
57 throw;
58 }
59 if (readSize == 0) {
60 // dev_->waitForReadyRead(50);
61 } else {
62 buf += readSize;
63 len -= readSize;
64 }
65 }
66 return requestLen;
67 }
68
69 uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len)
70 {
71 uint32_t actualSize;
72 qint64 readSize;
73
74 if (!dev_->isOpen()) {
75 throw TTransportException(TTransportException::NOT_OPEN,
76 "read(): underlying QIODevice is not open");
77 }
78
79 actualSize = (uint32_t)std::min((qint64)len, dev_->bytesAvailable());
80 readSize = dev_->read(reinterpret_cast<char *>(buf), len);
81
82 if (readSize < 0) {
83 QAbstractSocket* socket;
84 if ((socket = qobject_cast<QAbstractSocket* >(dev_.get()))) {
85 throw TTransportException(TTransportException::UNKNOWN,
86 "Failed to read() from QAbstractSocket",
87 socket->error());
88 }
89 throw TTransportException(TTransportException::UNKNOWN,
90 "Failed to read from from QIODevice");
91 }
92
93 return (uint32_t)readSize;
94 }
95
96 void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len)
97 {
98 while (len) {
99 uint32_t written = write_partial(buf, len);
100 len -= written;
101 // dev_->waitForBytesWritten(50);
102 }
103 }
104
105 uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len)
106 {
107 qint64 written;
108
109 if (!dev_->isOpen()) {
110 throw TTransportException(TTransportException::NOT_OPEN,
111 "write_partial(): underlying QIODevice is not open");
112 }
113
114 written = dev_->write(reinterpret_cast<const char*>(buf), len);
115 if (written < 0) {
116 QAbstractSocket* socket;
117 if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
118 throw TTransportException(TTransportException::UNKNOWN,
119 "write_partial(): failed to write to QAbstractSocket", socket->error());
120 }
121
122 throw TTransportException(TTransportException::UNKNOWN,
123 "write_partial(): failed to write to underlying QIODevice");
124 }
125
126 return (uint32_t)written;
127 }
128
129 void TQIODeviceTransport::flush()
130 {
131 if (!dev_->isOpen()) {
132 throw TTransportException(TTransportException::NOT_OPEN,
133 "flush(): underlying QIODevice is not open");
134 }
135
136 QAbstractSocket* socket;
137
138 if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
139 socket->flush();
140 } else {
141 dev_->waitForBytesWritten(1);
142 }
143 }
144
145 uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len)
146 {
147 return NULL;
148 }
149
150 void TQIODeviceTransport::consume(uint32_t len)
151 {
152 throw TTransportException(TTransportException::UNKNOWN);
153 }
154}}} // apache::thrift::transport
155