blob: c03894eeeadb1ddc41518dccaa709faadf811560 [file] [log] [blame]
Roger Meier7699b402012-04-08 18:18:44 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Roger Meier86e89862012-02-10 19:53:20 +000020#include "TQIODeviceTransport.h"
21
Roger Meier19a99152012-02-11 19:09:30 +000022#include <QAbstractSocket>
23#include <QIODevice>
24
Roger Meier86e89862012-02-10 19:53:20 +000025#include <transport/TBufferTransports.h>
26
Roger Meier19a99152012-02-11 19:09:30 +000027using boost::shared_ptr;
28
Roger Meier86e89862012-02-10 19:53:20 +000029namespace apache { namespace thrift { namespace transport {
Roger Meier86e89862012-02-10 19:53:20 +000030
Roger Meier19a99152012-02-11 19:09:30 +000031TQIODeviceTransport::TQIODeviceTransport(shared_ptr<QIODevice> dev)
32 : dev_(dev)
33{
34}
35
36TQIODeviceTransport::~TQIODeviceTransport()
37{
38 dev_->close();
39}
40
41void TQIODeviceTransport::open()
42{
43 if (!isOpen()) {
44 throw TTransportException(TTransportException::NOT_OPEN,
45 "open(): underlying QIODevice isn't open");
Roger Meier86e89862012-02-10 19:53:20 +000046 }
Roger Meier19a99152012-02-11 19:09:30 +000047}
Roger Meier86e89862012-02-10 19:53:20 +000048
Roger Meier19a99152012-02-11 19:09:30 +000049bool TQIODeviceTransport::isOpen()
50{
51 return dev_->isOpen();
52}
Roger Meier86e89862012-02-10 19:53:20 +000053
Roger Meier19a99152012-02-11 19:09:30 +000054bool TQIODeviceTransport::peek()
55{
56 return dev_->bytesAvailable() > 0;
57}
Roger Meier86e89862012-02-10 19:53:20 +000058
Roger Meier19a99152012-02-11 19:09:30 +000059void TQIODeviceTransport::close()
60{
61 dev_->close();
62}
Roger Meier86e89862012-02-10 19:53:20 +000063
Roger Meier19a99152012-02-11 19:09:30 +000064uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len)
65{
66 uint32_t requestLen = len;
67 while (len) {
68 uint32_t readSize;
69 try {
70 readSize = read(buf, len);
71 } catch (...) {
72 if (len != requestLen) {
73 // something read already
74 return requestLen - len;
Roger Meier86e89862012-02-10 19:53:20 +000075 }
Roger Meier19a99152012-02-11 19:09:30 +000076 // error but nothing read yet
77 throw;
Roger Meier86e89862012-02-10 19:53:20 +000078 }
Roger Meier19a99152012-02-11 19:09:30 +000079 if (readSize == 0) {
80 dev_->waitForReadyRead(50);
Roger Meier86e89862012-02-10 19:53:20 +000081 } else {
Roger Meier19a99152012-02-11 19:09:30 +000082 buf += readSize;
83 len -= readSize;
Roger Meier86e89862012-02-10 19:53:20 +000084 }
85 }
Roger Meier19a99152012-02-11 19:09:30 +000086 return requestLen;
87}
Roger Meier86e89862012-02-10 19:53:20 +000088
Roger Meier19a99152012-02-11 19:09:30 +000089uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len)
90{
91 uint32_t actualSize;
92 qint64 readSize;
93
94 if (!dev_->isOpen()) {
95 throw TTransportException(TTransportException::NOT_OPEN,
96 "read(): underlying QIODevice is not open");
Roger Meier86e89862012-02-10 19:53:20 +000097 }
98
Roger Meier19a99152012-02-11 19:09:30 +000099 actualSize = (uint32_t)std::min((qint64)len, dev_->bytesAvailable());
100 readSize = dev_->read(reinterpret_cast<char *>(buf), actualSize);
101
102 if (readSize < 0) {
103 QAbstractSocket* socket;
104 if ((socket = qobject_cast<QAbstractSocket* >(dev_.get()))) {
105 throw TTransportException(TTransportException::UNKNOWN,
106 "Failed to read() from QAbstractSocket",
107 socket->error());
108 }
109 throw TTransportException(TTransportException::UNKNOWN,
110 "Failed to read from from QIODevice");
Roger Meier86e89862012-02-10 19:53:20 +0000111 }
Roger Meier19a99152012-02-11 19:09:30 +0000112
113 return (uint32_t)readSize;
114}
115
116void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len)
117{
118 while (len) {
119 uint32_t written = write_partial(buf, len);
120 len -= written;
121 dev_->waitForBytesWritten(50);
122 }
123}
124
125uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len)
126{
127 qint64 written;
128
129 if (!dev_->isOpen()) {
130 throw TTransportException(TTransportException::NOT_OPEN,
131 "write_partial(): underlying QIODevice is not open");
132 }
133
134 written = dev_->write(reinterpret_cast<const char*>(buf), len);
135 if (written < 0) {
136 QAbstractSocket* socket;
137 if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
138 throw TTransportException(TTransportException::UNKNOWN,
139 "write_partial(): failed to write to QAbstractSocket", socket->error());
140 }
141
142 throw TTransportException(TTransportException::UNKNOWN,
143 "write_partial(): failed to write to underlying QIODevice");
144 }
145
146 return (uint32_t)written;
147}
148
149void TQIODeviceTransport::flush()
150{
151 if (!dev_->isOpen()) {
152 throw TTransportException(TTransportException::NOT_OPEN,
153 "flush(): underlying QIODevice is not open");
154 }
155
156 QAbstractSocket* socket;
157
158 if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
159 socket->flush();
160 } else {
161 dev_->waitForBytesWritten(1);
162 }
163}
164
165uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len)
166{
Roger Meier7699b402012-04-08 18:18:44 +0000167 (void) buf;
168 (void) len;
Roger Meier19a99152012-02-11 19:09:30 +0000169 return NULL;
170}
171
172void TQIODeviceTransport::consume(uint32_t len)
173{
Roger Meier7699b402012-04-08 18:18:44 +0000174 (void) len;
Roger Meier19a99152012-02-11 19:09:30 +0000175 throw TTransportException(TTransportException::UNKNOWN);
176}
177
Roger Meier86e89862012-02-10 19:53:20 +0000178}}} // apache::thrift::transport
179