uint32_t TBufferedTransport::readSlow(uint8_t* buf, uint32_t len) {
  uint32_t have = rBound_ - rBase_;

  // We should only take the slow path if we can't satisfy the read
  // with the data already in the buffer.
  assert(have < len);

  // If we have some date in the buffer, copy it out and return it.
  // We have to return it without attempting to read more, since we aren't
  // guaranteed that the underlying transport actually has more data, so
  // attempting to read from it could block.
  if (have > 0) {
    memcpy(buf, rBase_, have);
    setReadBuffer(rBuf_.get(), 0);
    return have;
  }

  // No data is available in our buffer.
  // Get more from underlying transport up to buffer size.
  // Note that this makes a lot of sense if len < rBufSize_
  // and almost no sense otherwise.  TODO(dreiss): Fix that
  // case (possibly including some readv hotness).
  setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));

  // Hand over whatever we have.
  uint32_t give = std::min(len, static_cast<uint32_t>(rBound_ - rBase_));
  memcpy(buf, rBase_, give);
  rBase_ += give;

  return give;
}
uint32_t TFramedTransport::readSlow(uint8_t* buf, uint32_t len) {
  uint32_t want = len;
  uint32_t have = rBound_ - rBase_;

  // We should only take the slow path if we can't satisfy the read
  // with the data already in the buffer.
  assert(have < want);

  // If we have some data in the buffer, copy it out and return it.
  // We have to return it without attempting to read more, since we aren't
  // guaranteed that the underlying transport actually has more data, so
  // attempting to read from it could block.
  if (have > 0) {
    memcpy(buf, rBase_, have);
    setReadBuffer(rBuf_.get(), 0);
    return have;
  }

  // Read another frame.
  if (!readFrame()) {
    // EOF.  No frame available.
    return 0;
  }

  // TODO(dreiss): Should we warn when reads cross frames?

  // Hand over whatever we have.
  uint32_t give = std::min(want, static_cast<uint32_t>(rBound_ - rBase_));
  memcpy(buf, rBase_, give);
  rBase_ += give;
  want -= give;

  return (len - want);
}
Example #3
0
size_t TCPPipeSlave::readData(IO::File::Byte* buffer,size_t bufferSize)
	{
	/* Receive a data packet from the master: */
	Packet* newPacket=multiplexer->receivePacket(pipeId);
	
	/* Check for error conditions: */
	if(newPacket->packetSize!=0)
		{
		/* Install the new packet as the pipe's read buffer: */
		if(packet!=0)
			multiplexer->deletePacket(packet);
		packet=newPacket;
		setReadBuffer(Packet::maxPacketSize,reinterpret_cast<Byte*>(packet->packet),false);
		
		return packet->packetSize;
		}
	else
		{
		/* Read the status packet: */
		multiplexer->deletePacket(newPacket);
		newPacket=multiplexer->receivePacket(pipeId);
		Packet::Reader reader(newPacket);
		int errorCode=reader.read<int>();
		multiplexer->deletePacket(newPacket);
		
		/* Throw an exception: */
		handleReadError(errorCode);
		}
	
	/* Never reached; just to make compiler happy: */
	return 0;
	}
Example #4
0
uint32_t TBufferedTransport::readSlow(uint8_t* buf, uint32_t len) {
  uint32_t want = len;
  uint32_t have = rBound_ - rBase_;

  // We should only take the slow path if we can't satisfy the read
  // with the data already in the buffer.
  assert(have < want);

  // Copy out whatever we have.
  if (have > 0) {
    memcpy(buf, rBase_, have);
    want -= have;
    buf += have;
  }
  // Get more from underlying transport up to buffer size.
  // Note that this makes a lot of sense if len < rBufSize_
  // and almost no sense otherwise.  TODO(dreiss): Fix that
  // case (possibly including some readv hotness).
  setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));

  // Hand over whatever we have.
  uint32_t give = std::min(want, static_cast<uint32_t>(rBound_ - rBase_));
  memcpy(buf, rBase_, give);
  rBase_ += give;
  want -= give;

  return (len - want);
}
Example #5
0
void Framebuffer::blit(GLenum readBuffer, const std::array<GLint, 4> & srcRect, Framebuffer * destFbo, const std::vector<GLenum> & drawBuffers, const std::array<GLint, 4> & destRect, ClearBufferMask mask, GLenum filter) const
{
    setReadBuffer(readBuffer);
    destFbo->setDrawBuffers(drawBuffers);

    implementation().blit(this, destFbo, srcRect[0], srcRect[1], srcRect[2], srcRect[3], destRect[0], destRect[1], destRect[2], destRect[3], mask, filter);
}
Example #6
0
TCPPipeSlave::~TCPPipeSlave(void)
	{
	/* Delete the current multicast packet: */
	if(packet!=0)
		{
		multiplexer->deletePacket(packet);
		setReadBuffer(0,0,false);
		}
	}
Example #7
0
void Framebuffer::blit(GLenum readBuffer, const std::array<GLint, 4> & srcRect, Framebuffer * destFbo, const std::vector<GLenum> & drawBuffers, const std::array<GLint, 4> & destRect, ClearBufferMask mask, GLenum filter) const
{
    bind(GL_READ_FRAMEBUFFER);
    destFbo->bind(GL_DRAW_FRAMEBUFFER);

    setReadBuffer(readBuffer);
    destFbo->setDrawBuffers(drawBuffers);

    blit(srcRect, destRect, mask, filter);
}
Example #8
0
uint32_t TFramedTransport::readEnd() {
  // include framing bytes
  uint32_t bytes_read = static_cast<uint32_t>(rBound_ - rBuf_.get() + sizeof(uint32_t));

  if (rBufSize_ > bufReclaimThresh_) {
    rBufSize_ = 0;
    rBuf_.reset();
    setReadBuffer(rBuf_.get(), rBufSize_);
  }

  return bytes_read;
}
SeekableFilter::~SeekableFilter(void)
	{
	/* Uninstall the buffered file's read buffer: */
	setReadBuffer(0,0,false);
	
	/* Delete the buffer list: */
	while(head!=0)
		{
		BufferHeader* succ=head->succ;
		delete[] reinterpret_cast<Byte*>(head);
		head=succ;
		}
	}
Example #10
0
bool TFramedTransport::readFrame() {
  // TODO(dreiss): Think about using readv here, even though it would
  // result in (gasp) read-ahead.

  // Read the size of the next frame.
  // We can't use readAll(&sz, sizeof(sz)), since that always throws an
  // exception on EOF.  We want to throw an exception only if EOF occurs after
  // partial size data.
  int32_t sz = -1;
  uint32_t size_bytes_read = 0;
  while (size_bytes_read < sizeof(sz)) {
    uint8_t* szp = reinterpret_cast<uint8_t*>(&sz) + size_bytes_read;
    uint32_t bytes_read
        = transport_->read(szp, static_cast<uint32_t>(sizeof(sz)) - size_bytes_read);
    if (bytes_read == 0) {
      if (size_bytes_read == 0) {
        // EOF before any data was read.
        return false;
      } else {
        // EOF after a partial frame header.  Raise an exception.
        throw TTransportException(TTransportException::END_OF_FILE,
                                  "No more data to read after "
                                  "partial frame header.");
      }
    }
    size_bytes_read += bytes_read;
  }

  sz = ntohl(sz);

  if (sz < 0) {
    throw TTransportException("Frame size has negative value");
  }

  // Check for oversized frame
  if (sz > static_cast<int32_t>(maxFrameSize_))
    throw TTransportException(TTransportException::CORRUPTED_DATA,
                              "Received an oversized frame");

  // Read the frame payload, and reset markers.
  if (sz > static_cast<int32_t>(rBufSize_)) {
    rBuf_.reset(new uint8_t[sz]);
    rBufSize_ = sz;
  }
  transport_->readAll(rBuf_.get(), sz);
  setReadBuffer(rBuf_.get(), sz);
  return true;
}
Example #11
0
HttpFile::~HttpFile(void)
	{
	/* Skip all unread parts of the HTTP reply body: */
	if(chunked)
		{
		if(!haveEof)
			{
			/* Skip all leftover chunks: */
			while(true)
				{
				/* Skip the rest of the current chunk: */
				pipe->skip<char>(unreadSize);
				
				/* Skip the chunk footer: */
				if(pipe->getChar()!='\r'||pipe->getChar()!='\n')
					Misc::throwStdErr("Comm::HttpFile: Malformed HTTP chunk footer");
				
				/* Parse the next chunk header: */
				unreadSize=parseChunkHeader(*pipe);
				if(unreadSize==0)
					break;
				}
			}
		
		/* Skip any optional message trailers: */
		while(pipe->getChar()!='\r')
			{
			/* Skip the line: */
			while(pipe->getChar()!='\r')
				;
			if(pipe->getChar()!='\n')
				Misc::throwStdErr("Comm::HttpFile: Malformed HTTP body trailer");
			}
		if(pipe->getChar()!='\n')
			Misc::throwStdErr("Comm::HttpFile: Malformed HTTP body trailer");
		}
	else if(fixedSize)
		{
		/* Skip the rest of the fixed-size message body: */
		pipe->skip<char>(unreadSize);
		}
	
	/* Release the read buffer: */
	setReadBuffer(0,0,false);
	}
Example #12
0
void TFramedTransport::readFrame() {
  // TODO(dreiss): Think about using readv here, even though it would
  // result in (gasp) read-ahead.

  // Read the size of the next frame.
  int32_t sz;
  transport_->readAll((uint8_t*)&sz, sizeof(sz));
  sz = ntohl(sz);

  if (sz < 0) {
    throw TTransportException("Frame size has negative value");
  }

  // Read the frame payload, and reset markers.
  if (sz > static_cast<int32_t>(rBufSize_)) {
    rBuf_.reset(new uint8_t[sz]);
    rBufSize_ = sz;
  }
  transport_->readAll(rBuf_.get(), sz);
  setReadBuffer(rBuf_.get(), sz);
}
Example #13
0
const uint8_t* TBufferedTransport::borrowSlow(uint8_t* buf, uint32_t* len) {
  // If the request is bigger than our buffer, we are hosed.
  if (*len > rBufSize_) {
    return NULL;
  }

  // The number of bytes of data we have already.
  uint32_t have = rBound_ - rBase_;
  // The number of additional bytes we need from the underlying transport.
  int32_t need = *len - have;
  // The space from the start of the buffer to the end of our data.
  uint32_t offset = rBound_ - rBuf_.get();
  assert(need > 0);

  // If we have less than half our buffer space available, shift the data
  // we have down to the start.  If the borrow is big compared to our buffer,
  // this could be kind of a waste, but if the borrow is small, it frees up
  // space at the end of our buffer to do a bigger single read from the
  // underlying transport.  Also, if our needs extend past the end of the
  // buffer, we have to do a copy no matter what.
  if ((offset > rBufSize_/2) || (offset + need > rBufSize_)) {
    memmove(rBuf_.get(), rBase_, have);
    setReadBuffer(rBuf_.get(), have);
  }

  // First try to fill up the buffer.
  uint32_t got = transport_->read(rBound_, rBufSize_ - have);
  rBound_ += got;
  need -= got;

  // If that fails, readAll until we get what we need.
  if (need > 0) {
    rBound_ += transport_->readAll(rBound_, need);
  }

  *len = rBound_ - rBase_;
  return rBase_;
}
Example #14
0
size_t HttpFile::readData(IO::File::Byte* buffer,size_t bufferSize)
	{
	/* Read depending on the reply body's transfer encoding: */
	if(chunked)
		{
		/* Check if the current chunk is finished: */
		if(unreadSize==0)
			{
			/* Bail out if the EOF chunk has already been read: */
			if(haveEof)
				return 0;
			
			/* Skip the chunk footer: */
			if(pipe->getChar()!='\r'||pipe->getChar()!='\n')
				Misc::throwStdErr("Comm::HttpFile: Malformed HTTP chunk footer");
			
			/* Parse the next chunk header: */
			unreadSize=parseChunkHeader(*pipe);
			}
		
		/* Set the EOF flag if this chunk has size zero: */
		if(unreadSize==0)
			{
			haveEof=true;
			return 0;
			}
		
		/* Read more data directly from the pipe's read buffer: */
		void* pipeBuffer;
		size_t pipeSize=pipe->readInBuffer(pipeBuffer,unreadSize);
		setReadBuffer(pipeSize,static_cast<Byte*>(pipeBuffer),false);
		
		/* Reduce the unread data size and return the read size: */
		unreadSize-=pipeSize;
		return pipeSize;
		}
	else if(fixedSize)
		{
		/* Check for end-of-file: */
		if(unreadSize==0)
			return 0;
		
		/* Read more data directly from the pipe's read buffer: */
		void* pipeBuffer;
		size_t pipeSize=pipe->readInBuffer(pipeBuffer,unreadSize);
		setReadBuffer(pipeSize,static_cast<Byte*>(pipeBuffer),false);
		
		/* Reduce the unread data size and return the read size: */
		unreadSize-=pipeSize;
		return pipeSize;
		}
	else
		{
		/* Read more data directly from the pipe's read buffer: */
		void* pipeBuffer;
		size_t pipeSize=pipe->readInBuffer(pipeBuffer);
		setReadBuffer(pipeSize,static_cast<Byte*>(pipeBuffer),false);
		
		/* Return the read size: */
		return pipeSize;
		}
	}
Example #15
0
void Framebuffer::readPixels(const GLenum readBuffer, const std::array<GLint, 4> & rect, const GLenum format, const GLenum type, GLvoid * data) const
{
    setReadBuffer(readBuffer);
    readPixels(rect, format, type, data);
}
Example #16
0
size_t SeekableFilter::readData(File::Byte* buffer,size_t bufferSize)
	{
	/* Check if the file position needs to be moved to the read position: */
	if(filePos!=readPos)
		{
		if(readPos>filePos)
			{
			/* Skip forward in buffer chain from the current position: */
			currentPos+=(readPos-filePos);
			
			/* Skip buffers until the current buffer offset is within the current buffer: */
			while(currentPos>Offset(current->size))
				{
				/* Check if there is a next buffer: */
				if(current->succ!=0)
					{
					/* Go to the next buffer: */
					currentPos-=current->size;
					current=current->succ;
					}
				else
					{
					/* Check for end-of-file: */
					if(source->eof())
						throw SeekError(readPos);
					
					/* Read more data: */
					readFromSource();
					}
				}
			}
		else
			{
			/* Skip from the beginning of the buffer chain: */
			current=head;
			currentPos=readPos;
			
			/* Skip buffers until the current buffer offset is within the current buffer: */
			while(currentPos>Offset(current->size))
				{
				/* Go to the next buffer: */
				currentPos-=current->size;
				current=current->succ;
				}
			}
		
		/* Update the file position: */
		filePos=readPos;
		}
	
	/* Check if the file position is at the end of the read data: */
	if(filePos==totalReadSize)
		{
		/* Check for end-of-file: */
		if(source->eof())
			return 0;
		
		/* Read more data: */
		readFromSource();
		}
	
	/* Read from the current file position: */
	if(currentPos==Offset(current->size))
		{
		/* Go to the next buffer: */
		current=current->succ;
		currentPos=0;
		}
	size_t copySize=current->size-size_t(currentPos);
	setReadBuffer(copySize,reinterpret_cast<Byte*>(current+1)+currentPos,false);
	readPos+=copySize;
	filePos+=copySize;
	currentPos+=copySize;
	
	return copySize;
	}
Example #17
0
std::vector<unsigned char> Framebuffer::readPixelsToByteArray(GLenum readBuffer, const std::array<GLint, 4> & rect, GLenum format, GLenum type) const
{
    setReadBuffer(readBuffer);
    return readPixelsToByteArray(rect, format, type);
}