TcpSocketBuffer.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "TcpSocketBuffer.h"
00025 #include "Socket.h"
00026 #include "Imports.cpp"
00027
00029
00035 TcpSocketBuffer::TcpSocketBuffer (int readBufferSize, int writeBufferSize)
00036 : readBuffer (0), readSize (0), readStart (0), readEnd (0),
00037 writeBuffer (0), writeSize (0), writeStart (0), writeEnd (0),
00038 writeFlushEnd (0)
00039 {
00040 Q_ASSERT (readBufferSize >= 0);
00041 Q_ASSERT (writeBufferSize >= 0);
00042
00043 setReadBufferSize (readBufferSize);
00044 setWriteBufferSize (writeBufferSize);
00045 }
00046
00048 TcpSocketBuffer::~TcpSocketBuffer()
00049 {
00050 delete[] readBuffer;
00051 delete[] writeBuffer;
00052 }
00053
00055
00066 QByteArray TcpSocketBuffer::peek (int count) const
00067 {
00068 if (!canRead (count))
00069 return QByteArray();
00070 else {
00071 QByteArray res;
00072 res.resize (count);
00073 peek (res.data(), res.size());
00074 return res;
00075 }
00076 }
00077
00079
00090 QByteArray TcpSocketBuffer::peekAtMost (int count) const
00091 {
00092 return peek (std::min (count, readEnd - readStart));
00093 }
00094
00096
00110 QByteArray TcpSocketBuffer::peekTo (const QByteArray &delimiter) const
00111 {
00112 QByteArray allBytes = peekAll();
00113 int pos = allBytes.indexOf (delimiter);
00114 if (pos == -1)
00115 return QByteArray();
00116 else
00117 return allBytes.left (pos + delimiter.size());
00118 }
00119
00121
00127 QByteArray TcpSocketBuffer::peekAll() const
00128 {
00129 return peek (bytesToRead());
00130 }
00131
00133
00141 QByteArray TcpSocketBuffer::read (int count)
00142 {
00143 QByteArray res = peek (count);
00144 purgeReadBuffer (res.size());
00145 return res;
00146 }
00147
00149
00157 QByteArray TcpSocketBuffer::readAtMost (int count)
00158 {
00159 QByteArray res = peekAtMost (count);
00160 purgeReadBuffer (res.size());
00161 return res;
00162 }
00163
00165
00176 QByteArray TcpSocketBuffer::readTo (const QByteArray &delimiter)
00177 {
00178 QByteArray res = peekTo (delimiter);
00179 purgeReadBuffer (res.size());
00180 return res;
00181 }
00182
00184
00187 QByteArray TcpSocketBuffer::readAll()
00188 {
00189 QByteArray res = peekAll();
00190 purgeReadBuffer (res.size());
00191 return res;
00192 }
00193
00195
00198 void TcpSocketBuffer::tryReadFrom (Socket *socket)
00199 {
00200 int readSize = 0;
00201 while ((readSize = nextReadChunkSize()) > 0) {
00202 char *readBuffer = nextReadChunk();
00203 qint64 read = socket->read (readBuffer, readSize);
00204 if (read > 0)
00205 hasRead (read);
00206
00207 if (read < readSize)
00208 break;
00209 }
00210 }
00211
00213
00223 bool TcpSocketBuffer::canRead (int count) const
00224 {
00225 Q_ASSERT (count >= 0);
00226 return readStart + count <= readEnd;
00227 }
00228
00230
00245 void TcpSocketBuffer::peek (char *destination, int size) const
00246 {
00247 Q_ASSERT (canRead (size));
00248
00249 if (readStart + size <= readSize) {
00250 memcpy (destination, readBuffer + readStart, size);
00251 } else {
00252
00253 int count = readSize - readStart;
00254 memcpy (destination, readBuffer + readStart, count);
00255
00256 Q_ASSERT (size - count > 0);
00257 memcpy (destination + count, readBuffer, size - count);
00258 }
00259 }
00260
00262
00269 void TcpSocketBuffer::purgeReadBuffer (int count)
00270 {
00271 Q_ASSERT (canRead (count));
00272 readStart += count;
00273
00274
00275 if (readStart >= readSize) {
00276 readStart -= readSize;
00277 readEnd -= readSize;
00278 }
00279 }
00280
00282
00292 void TcpSocketBuffer::setReadBufferSize (int size)
00293 {
00294 Q_ASSERT (size >= 0);
00295 char *newBuffer = 0;
00296 if (size > 0)
00297 newBuffer = new char [size];
00298 delete[] readBuffer;
00299 readBuffer = newBuffer;
00300 readSize = size;
00301 readStart = readEnd = 0;
00302 }
00303
00305
00308 int TcpSocketBuffer::readBufferSize() const
00309 {
00310 return readSize;
00311 }
00312
00314
00317 int TcpSocketBuffer::bytesToRead() const
00318 {
00319 return readEnd - readStart;
00320 }
00321
00323
00329 char* TcpSocketBuffer::nextReadChunk() const
00330 {
00331 int readPos = (readEnd >= readSize) ? (readEnd - readSize) : readEnd;
00332 return readBuffer + readPos;
00333 }
00334
00336
00339 int TcpSocketBuffer::nextReadChunkSize() const
00340 {
00341 if (readEnd >= readSize)
00342 return readStart - (readEnd - readSize);
00343 else
00344 return readSize - readEnd;
00345 }
00346
00348
00358 void TcpSocketBuffer::hasRead (int count)
00359 {
00360 Q_ASSERT (count >= 0);
00361 Q_ASSERT (readEnd + count <= readStart + readSize);
00362 readEnd += count;
00363 }
00364
00366
00376 bool TcpSocketBuffer::write (const QByteArray &bytes, bool flush)
00377 {
00378 int size = bytes.size();
00379 if (!canWrite (size))
00380 return false;
00381 write (bytes.data(), size, flush);
00382 return true;
00383 }
00384
00386
00389 void TcpSocketBuffer::tryWriteTo (Socket *socket)
00390 {
00391 while (bytesToWrite() > 0) {
00392
00393 char *writeBuffer = nextWriteChunk();
00394 int writeSize = nextWriteChunkSize();
00395 qint64 written = socket->write (writeBuffer, writeSize);
00396 Q_ASSERT (written <= writeSize);
00397 if (written > 0)
00398 hasWritten (written);
00399
00400 if (written < writeSize)
00401 break;
00402 }
00403 }
00404
00406
00416 bool TcpSocketBuffer::canWrite (int count) const
00417 {
00418 Q_ASSERT (count >= 0);
00419 return writeEnd + count <= writeStart + writeSize;
00420 }
00421
00423
00443 void TcpSocketBuffer::write (const char *source, int size, bool flush)
00444 {
00445 Q_ASSERT (canWrite (size));
00446 int writePos = (writeEnd >= writeSize) ? (writeEnd - writeSize) : writeEnd;
00447 if (writePos + size <= writeSize) {
00448 memcpy (writeBuffer + writeEnd, source, size);
00449 } else {
00450 int count = writeSize - writeEnd;
00451 memcpy (writeBuffer + writePos, source, count);
00452 Q_ASSERT (size - count > 0);
00453 memcpy (writeBuffer, source + count, size - count);
00454 }
00455 writeEnd += size;
00456 if (flush)
00457 writeFlushEnd = writeEnd;
00458 }
00459
00461
00471 void TcpSocketBuffer::setWriteBufferSize (int size)
00472 {
00473 Q_ASSERT (size >= 0);
00474 char *newBuffer = 0;
00475 if (size > 0)
00476 newBuffer = new char [size];
00477 delete[] writeBuffer;
00478 writeBuffer = newBuffer;
00479 writeSize = size;
00480 writeStart = writeEnd = writeFlushEnd = 0;
00481 }
00482
00484
00487 int TcpSocketBuffer::writeBufferSize() const
00488 {
00489 return writeSize;
00490 }
00491
00493
00496 int TcpSocketBuffer::bytesToWrite() const
00497 {
00498 return writeEnd - writeStart;
00499 }
00500
00502
00508 char * TcpSocketBuffer::nextWriteChunk() const
00509 {
00510 return writeBuffer + writeStart;
00511 }
00512
00514
00517 int TcpSocketBuffer::nextWriteChunkSize() const
00518 {
00519 return std::min (writeSize - writeStart, writeFlushEnd - writeStart);
00520 }
00521
00523
00533 void TcpSocketBuffer::hasWritten (int count)
00534 {
00535 Q_ASSERT (count >= 0);
00536 Q_ASSERT (writeStart + count <= writeFlushEnd);
00537 Q_ASSERT (writeFlushEnd <= writeEnd);
00538 writeStart += count;
00539 if (writeStart >= writeSize) {
00540 writeStart -= writeSize;
00541 writeFlushEnd -= writeSize;
00542 writeEnd -= writeSize;
00543 }
00544 }