139 lines
3.1 KiB
C++
139 lines
3.1 KiB
C++
/**
|
|
* TcpInBuffer.h
|
|
*
|
|
* Implementation of byte byte-buffer used for incoming frames
|
|
*
|
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
|
* @copyright 2016 Copernica BV
|
|
*/
|
|
|
|
/**
|
|
* Include guard
|
|
*/
|
|
#pragma once
|
|
|
|
/**
|
|
* Beginnig of namespace
|
|
*/
|
|
namespace AMQP {
|
|
|
|
/**
|
|
* Class definition
|
|
*/
|
|
class TcpInBuffer : public ByteBuffer
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
* Note that we pass 0 to the constructor because the buffer seems to be empty
|
|
* @param size initial size to allocated
|
|
*/
|
|
TcpInBuffer(size_t size) : ByteBuffer((char *)malloc(size), 0) {}
|
|
|
|
/**
|
|
* No copy'ing
|
|
* @param that object to copy
|
|
*/
|
|
TcpInBuffer(const TcpInBuffer &that) = delete;
|
|
|
|
/**
|
|
* Move constructor
|
|
* @param that
|
|
*/
|
|
TcpInBuffer(TcpInBuffer &&that) : ByteBuffer(std::move(that)) {}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~TcpInBuffer()
|
|
{
|
|
// free memory
|
|
if (_data) free((void *)_data);
|
|
}
|
|
|
|
/**
|
|
* Move assignment operator
|
|
* @param that
|
|
*/
|
|
TcpInBuffer &operator=(TcpInBuffer &&that)
|
|
{
|
|
// skip self-assignment
|
|
if (this == &that) return *this;
|
|
|
|
// call base
|
|
ByteBuffer::operator=(std::move(that));
|
|
|
|
// done
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Reallocate date
|
|
* @param size
|
|
*/
|
|
void reallocate(size_t size)
|
|
{
|
|
// update data
|
|
_data = (char *)realloc((void *)_data, size);
|
|
}
|
|
|
|
/**
|
|
* Receive data from a socket
|
|
* @param socket socket to read from
|
|
* @param expected number of bytes that the library expects
|
|
* @return ssize_t
|
|
*/
|
|
ssize_t receivefrom(int socket, uint32_t expected)
|
|
{
|
|
// find out how many bytes are available
|
|
uint32_t available = 0;
|
|
|
|
// check the number of bytes that are available
|
|
if (ioctl(socket, FIONREAD, &available) != 0) return -1;
|
|
|
|
// if no bytes are available, it could mean that the connection was closed
|
|
// by the remote client, so we do have to call read() anyway, assume a default buffer
|
|
if (available == 0) available = 1;
|
|
|
|
// number of bytes to read
|
|
size_t bytes = std::min((uint32_t)(expected - _size), available);
|
|
|
|
// read data into the buffer
|
|
auto result = read(socket, (void *)(_data + _size), bytes);
|
|
|
|
// update total buffer size
|
|
if (result > 0) _size += result;
|
|
|
|
// done
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Receive data from a socket
|
|
* @param ssl ssl wrapped socket to read from
|
|
* @param expected number of bytes that the library expects
|
|
* @return ssize_t
|
|
*/
|
|
ssize_t receivefrom(SSL *ssl, uint32_t expected)
|
|
{
|
|
// @todo implementation
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Shrink the buffer (in practice this is always called with the full buffer size)
|
|
* @param size
|
|
*/
|
|
void shrink(size_t size)
|
|
{
|
|
// update size
|
|
_size -= size;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* End of namespace
|
|
*/
|
|
}
|
|
|