Ejemplo n.º 1
0
/*!
    \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;
}
Ejemplo n.º 2
0
void GTcpSocket::setSpeed(qint64 in, qint64 out)
{
    inspeed = in;
    outspeed = out;

    lastSize = readBufferSize();
    if(inspeed*2 < readBufferSize())return;
    setReadBufferSize(in*2);
}
Ejemplo n.º 3
0
void GTcpSocket::setDownSpeed(qint64 spd)
{

    inspeed = spd;

    if(inspeed*2 < readBufferSize())return;

    lastSize = readBufferSize();
    setReadBufferSize(inspeed*2);

}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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();
}
Ejemplo n.º 6
0
int KBufferedIO::bytesAvailable() const
{
  return readBufferSize();
}
Ejemplo n.º 7
0
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);
}