/*! \internal */ qint64 QNetworkReplyImpl::readData(char *data, qint64 maxlen) { Q_D(QNetworkReplyImpl); // Special case code if we have the "zero copy" download buffer if (d->downloadBuffer) { qint64 maxAvail = qMin<qint64>(d->downloadBufferCurrentSize - d->downloadBufferReadPosition, maxlen); if (maxAvail == 0) return d->state == QNetworkReplyImplPrivate::Finished ? -1 : 0; // FIXME what about "Aborted" state? qMemCopy(data, d->downloadBuffer + d->downloadBufferReadPosition, maxAvail); d->downloadBufferReadPosition += maxAvail; return maxAvail; } if (d->readBuffer.isEmpty()) return d->state == QNetworkReplyImplPrivate::Finished ? -1 : 0; // FIXME what about "Aborted" state? d->backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite); if (maxlen == 1) { // optimization for getChar() *data = d->readBuffer.getChar(); if (d->backend && readBufferSize()) d->backend->emitReadBufferFreed(1); return 1; } maxlen = qMin<qint64>(maxlen, d->readBuffer.byteAmount()); qint64 bytesRead = d->readBuffer.read(data, maxlen); if (d->backend && readBufferSize()) d->backend->emitReadBufferFreed(bytesRead); return bytesRead; }
void GTcpSocket::setSpeed(qint64 in, qint64 out) { inspeed = in; outspeed = out; lastSize = readBufferSize(); if(inspeed*2 < readBufferSize())return; setReadBufferSize(in*2); }
void GTcpSocket::setDownSpeed(qint64 spd) { inspeed = spd; if(inspeed*2 < readBufferSize())return; lastSize = readBufferSize(); setReadBufferSize(inspeed*2); }
unsigned KBufferedIO::consumeReadBuffer(unsigned nbytes, char *destbuffer, bool discard) { { register unsigned u = readBufferSize(); if (nbytes > u) nbytes = u; // we can't consume more than there is } QByteArray *buf; unsigned copied = 0; unsigned index = inBufIndex; buf = inBuf.first(); while (nbytes && buf) { // should we copy it all? unsigned to_copy = buf->size() - index; if (to_copy > nbytes) to_copy = nbytes; if (destbuffer) memcpy(destbuffer + copied, buf->data() + index, to_copy); nbytes -= to_copy; copied += to_copy; if (buf->size() - index > to_copy) { index += to_copy; break; // we aren't copying everything, that means that's // all the user wants } else { index = 0; if (discard) { inBuf.remove(); buf = inBuf.first(); } else buf = inBuf.next(); } } if (discard) inBufIndex = index; return copied; }
void GTcpSocket::transferAct() { if(shedule_now)return; //если уже идет обмен с внешними буферами, то выходим if(!t_flag) return; //если флаг паузы, то выходим - не переносим ничего и никуда shedule_now = true; //устанавливаем признак выполнения данного метода int interval = 1000; //начальный интервал для подсчета лимита байт на скачивания/передачи if(this->state() != QAbstractSocket::ConnectedState && QSslSocket::bytesAvailable() == 0) { shedule_now = false; if(inbuf->size() > 0)emit readyToRead(); return; } //если сокет был отсоединен и нету данных во внешнем буфеое, то выходим if(!watcher->isNull()) //если таймер запускается не впервые interval = qMin(watcher->elapsed(), interval);//то выбираем наименьшее между начальным значением и интервалом с момента прошлой передачи данных watcher->start(); qint64 inLimit = (inspeed * interval)/1000; //высчитываем лимит приема/передачи qint64 outLimit = (outspeed * interval)/1000; if(outLimit == 0) outLimit = outbuf->size(); // если не утсновлено ограничение на отдачу, то передается все cодержимое выходного буфера qint64 bytesToRead; if(state() != QAbstractSocket::ConnectedState) { bytesToRead = QSslSocket::bytesAvailable(); if(bytesToRead > 2097152 /*2MB*/)bytesToRead = 2097152; } else { bytesToRead = qMin<qint64>(inLimit, QSslSocket::bytesAvailable()); if(QSslSocket::bytesAvailable() > 0) timeout->start(); else if(timeout->elapsed() > timeout_interval*1000 && !timeout->isNull()) { emit error(QSslSocket::SocketTimeoutError); close(); shedule_now = false; return; } } qint64 bytesToWrite = qMin<qint64>(outLimit, outbuf->size()); if(inspeed*2 < readBufferSize()) { qint64 dif = QSslSocket::bytesAvailable() - inspeed*2; if(dif > 50) setReadBufferSize(readBufferSize()-50); else setReadBufferSize(readBufferSize()-dif); } if(inspeed != 0) { int old_size = inbuf->size(); inbuf->resize(old_size + bytesToRead); QSslSocket::readData(inbuf->data() + old_size, bytesToRead); } QSslSocket::writeData(outbuf->data(), bytesToWrite); outbuf->remove(0, bytesToWrite); flush(); shedule_now = false; if(bytesToRead > 0 && inspeed !=0 )emit readyToRead(); else if (inspeed == 0 && QSslSocket::bytesAvailable()!= 0) emit readyToRead(); }
int KBufferedIO::bytesAvailable() const { return readBufferSize(); }
void Pillow::HttpClient::device_readyRead() { if (!responsePending()) { // Not supposed to be receiving data at this point. Just // ignore it and close the connection. _device->close(); return; } qint64 bytesAvailable = _device->bytesAvailable(); if (bytesAvailable == 0) return; if (_buffer.capacity() < _buffer.size() + bytesAvailable) _buffer.reserve(_buffer.size() + bytesAvailable); qint64 bufferSize = readBufferSize(); if (bufferSize > 0) bytesAvailable = bufferSize - _content.size(); if (bytesAvailable <= 0) { // Nothing to read or no space in buffers. Wait for more data or more space in buffers. return; } qint64 bytesRead = _device->read(_buffer.data() + _buffer.size(), bytesAvailable); _buffer.data_ptr()->size += bytesRead; int consumed = inject(_buffer); if (responsePending()) { // Response is still pending. One of the following: // 1. Got a parser error. (where hasError) // 2. Waiting for more data to complete the current request. (where _pendingRequest is null and consumed == buffer.size) // 3. Waiting for the real response after a 100-continue response. (where _pendingRequest is null and consumed < buffer.size, because parser will stop consuming after the 100-continue). if (!hasError()) { if (consumed < _buffer.size()) { // We had multiple responses in the buffer? // It was a 100 Continue since we are still response pending. consumed += inject(_buffer.constData() + consumed, _buffer.size() - consumed); if (consumed < _buffer.size()) { qWarning() << "Left some unconsumed data in the buffer:" << (_buffer.size() - consumed); } } else { // Just waiting for more data to consume. } } if (hasError()) // Re-check for error in case we injected again in the 100 Continue case above. { _error = ResponseInvalidError; _device->close(); _responsePending = false; emit finished(); } } // Reuse the read buffer if it is not overly large. if (_buffer.capacity() > 128 * 1024) _buffer.clear(); else _buffer.data_ptr()->size = 0; // Response completed or got aborted in a callback. if (!responsePending() && !_pendingRequest.method.isNull()) { // Plus we got a new request while in callback. Pillow::HttpClientRequest r = _pendingRequest; _pendingRequest = Pillow::HttpClientRequest(); // Clear it. request(r); } }
/* * Header format: * * Pos Type Data * ------------------------- * 0 quint8 Type * 1 quint32 Optional id * 5 quint32 Data size * ------------------------- * Total size: 9 bytes */ void LocalSocketPrivate::readData() { // qDebug("[%p] LocalSocketPrivate::readData()", this); // Try to read data disableReadNotifier(); // Reset data size m_currentReadDataBuffer.clear(); int numRead = 0; int nRead = 0; do { // Resize read buffer if(m_currentReadDataBuffer.isEmpty()) { m_currentReadDataBuffer.resize(1024); } else if (readBufferSize() - m_currentReadDataBuffer.size() < 1024) { // We cannot use additional 1 KiB space anymore break; } else { // Add 1 KiB up to readBufferSize() m_currentReadDataBuffer.resize(m_currentReadDataBuffer.size() + 1024); } nRead = read(m_currentReadDataBuffer.data() + m_currentReadDataBuffer.size() - 1024, 1024); numRead += nRead; } while(nRead == 1024); enableReadNotifier(); // Handle read data if(numRead > 0) { m_currentReadData.append(m_currentReadDataBuffer.constData(), numRead); // Analyze read data while(!m_currentReadData.isEmpty()) { // qDebug("[%p] LocalSocketPrivate::readData() - reading data", this); // Read package size if available if(!m_currentRequiredReadDataSize && m_currentReadData.size() >= HEADER_SIZE) { memcpy((char*)&m_currentRequiredReadDataSize, m_currentReadData.constData() + (HEADER_SIZE - sizeof(quint32)), sizeof(m_currentRequiredReadDataSize)); // Add header size m_currentRequiredReadDataSize += HEADER_SIZE; } // Check if we can read a package if(!m_currentRequiredReadDataSize || m_currentReadData.size() < m_currentRequiredReadDataSize) { // qDebug("[%p] LocalSocketPrivate::readData() - Cannot read package yet: %d/%d", this, m_currentReadData.size(), m_currentRequiredReadDataSize); break; } // static int _r_count = 0; // _r_count++; // qDebug("[%p] LocalSocketPrivate::readData() - count: %d", this, _r_count); // Read meta data int dataPos = 0; quint8 readVarType; quint32 readVarOptId; quint32 readVarDataSize; // Type memcpy((char*)&readVarType, m_currentReadData.constData() + dataPos, sizeof(readVarType)); dataPos += sizeof(readVarType); // Optional id memcpy((char*)&readVarOptId, m_currentReadData.constData() + dataPos, sizeof(readVarOptId)); dataPos += sizeof(readVarOptId); // Data size memcpy((char*)&readVarDataSize, m_currentReadData.constData() + dataPos, sizeof(readVarDataSize)); dataPos += sizeof(readVarDataSize); Variant readVar((Variant::Type)readVarType); readVar.setOptionalId(readVarOptId); // Set data if(readVarDataSize) { readVar.setValue(m_currentReadData.mid(dataPos, readVarDataSize)); dataPos += readVarDataSize; } // Remove data from buffer m_currentReadData.remove(0, dataPos); m_currentRequiredReadDataSize = 0; // Append to temporary read buffer if necessary if(readVar.type() == Variant::SocketDescriptor || !m_tempReadBuffer.isEmpty()) m_tempReadBuffer.append(readVar); else { { QWriteLocker writeLock(&m_readBufferLock); m_readBuffer.append(readVar); } // We have read a package emit(readyRead()); } } } checkTempReadData(true); // Lower read buffer size if(m_currentReadDataBuffer.size() > 1024) m_currentReadDataBuffer.resize(1024); // qDebug("[%p] LocalSocketPrivate::~readData()", this); }