the ReceivedFrame class has been split into a InBuffer base class to make it easier to store messages without having to construct a full frame, this commit adds the newly introduced classes
This commit is contained in:
parent
b03cc6ff1c
commit
92d21c5ddd
|
|
@ -0,0 +1,143 @@
|
||||||
|
/**
|
||||||
|
* InBuffer.h
|
||||||
|
*
|
||||||
|
* The InBuffer class is a wrapper around a data buffer and that adds
|
||||||
|
* some safety checks so that the rest of the library can safely read
|
||||||
|
* from it.
|
||||||
|
*
|
||||||
|
* This is a class that is used internally by the AMQP library. As a user
|
||||||
|
* of this library, you normally do not have to instantiate it. However,
|
||||||
|
* if you do want to store or safe messages yourself, it sometimes can
|
||||||
|
* be useful to implement it.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class InBuffer
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The buffer we are reading from
|
||||||
|
* @var Buffer
|
||||||
|
*/
|
||||||
|
const Buffer &_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes already processed
|
||||||
|
* @var uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t _skip = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param buffer Binary buffer
|
||||||
|
*/
|
||||||
|
InBuffer(const Buffer &buffer) : _buffer(buffer) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~InBuffer() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint8_t from the buffer
|
||||||
|
* @return uint8_t value read
|
||||||
|
*/
|
||||||
|
uint8_t nextUint8();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int8_t from the buffer
|
||||||
|
* @return int8_t value read
|
||||||
|
*/
|
||||||
|
int8_t nextInt8();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint16_t from the buffer
|
||||||
|
* @return uint16_t value read
|
||||||
|
*/
|
||||||
|
uint16_t nextUint16();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int16_t from the buffer
|
||||||
|
* @return int16_t value read
|
||||||
|
*/
|
||||||
|
int16_t nextInt16();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint32_t from the buffer
|
||||||
|
* @return uint32_t value read
|
||||||
|
*/
|
||||||
|
uint32_t nextUint32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int32_t from the buffer
|
||||||
|
* @return int32_t value read
|
||||||
|
*/
|
||||||
|
int32_t nextInt32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint64_t from the buffer
|
||||||
|
* @return uint64_t value read
|
||||||
|
*/
|
||||||
|
uint64_t nextUint64();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int64_t from the buffer
|
||||||
|
* @return int64_t value read
|
||||||
|
*/
|
||||||
|
int64_t nextInt64();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a float from the buffer
|
||||||
|
* @return float float read from buffer.
|
||||||
|
*/
|
||||||
|
float nextFloat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a double from the buffer
|
||||||
|
* @return double double read from buffer
|
||||||
|
*/
|
||||||
|
double nextDouble();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a pointer to the next binary buffer of a certain size
|
||||||
|
* @param size
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
const char *nextData(uint32_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The checker may access private data
|
||||||
|
*/
|
||||||
|
friend class BufferCheck;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* BufferCheck.h
|
||||||
|
*
|
||||||
|
* Class that checks incoming frames for their size
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal helper class that checks if there is enough room left in the buffer
|
||||||
|
*/
|
||||||
|
class BufferCheck
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The frame
|
||||||
|
* @var InBuffer
|
||||||
|
*/
|
||||||
|
InBuffer *_frame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size that is checked
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param frame
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
BufferCheck(InBuffer *frame, size_t size) : _frame(frame), _size(size)
|
||||||
|
{
|
||||||
|
// no problem is there are still enough bytes left
|
||||||
|
if (frame->_buffer.size() - frame->_skip >= size) return;
|
||||||
|
|
||||||
|
// frame buffer is too small
|
||||||
|
throw ProtocolException("frame out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BufferCheck()
|
||||||
|
{
|
||||||
|
// update the number of bytes to skip
|
||||||
|
_frame->_skip += (uint32_t)_size;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
/**
|
||||||
|
* InBuffer.cpp
|
||||||
|
*
|
||||||
|
* Implementation of the InBuffer class
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
#include "includes.h"
|
||||||
|
#include "buffercheck.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint8 from the buffer
|
||||||
|
* @param char* buffer buffer to read from
|
||||||
|
* @return uint8_t value read
|
||||||
|
*/
|
||||||
|
uint8_t InBuffer::nextUint8()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, 1);
|
||||||
|
|
||||||
|
// get a byte
|
||||||
|
return _buffer.byte(_skip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int8 from the buffer
|
||||||
|
* @param char* buffer buffer to read from
|
||||||
|
* @return int8_t value read
|
||||||
|
*/
|
||||||
|
int8_t InBuffer::nextInt8()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, 1);
|
||||||
|
|
||||||
|
// get a byte
|
||||||
|
return (int8_t)_buffer.byte(_skip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint16_t from the buffer
|
||||||
|
* @return uint16_t value read
|
||||||
|
*/
|
||||||
|
uint16_t InBuffer::nextUint16()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(uint16_t));
|
||||||
|
|
||||||
|
// get two bytes, and convert to host-byte-order
|
||||||
|
uint16_t value;
|
||||||
|
_buffer.copy(_skip, sizeof(uint16_t), &value);
|
||||||
|
return be16toh(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int16_t from the buffer
|
||||||
|
* @return int16_t value read
|
||||||
|
*/
|
||||||
|
int16_t InBuffer::nextInt16()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(int16_t));
|
||||||
|
|
||||||
|
// get two bytes, and convert to host-byte-order
|
||||||
|
int16_t value;
|
||||||
|
_buffer.copy(_skip, sizeof(int16_t), &value);
|
||||||
|
return be16toh(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint32_t from the buffer
|
||||||
|
* @return uint32_t value read
|
||||||
|
*/
|
||||||
|
uint32_t InBuffer::nextUint32()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(uint32_t));
|
||||||
|
|
||||||
|
// get four bytes, and convert to host-byte-order
|
||||||
|
uint32_t value;
|
||||||
|
_buffer.copy(_skip, sizeof(uint32_t), &value);
|
||||||
|
return be32toh(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int32_t from the buffer
|
||||||
|
* @return uint32_t value read
|
||||||
|
*/
|
||||||
|
int32_t InBuffer::nextInt32()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(int32_t));
|
||||||
|
|
||||||
|
// get four bytes, and convert to host-byte-order
|
||||||
|
int32_t value;
|
||||||
|
_buffer.copy(_skip, sizeof(int32_t), &value);
|
||||||
|
return be32toh(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint64_t from the buffer
|
||||||
|
* @return uint64_t value read
|
||||||
|
*/
|
||||||
|
uint64_t InBuffer::nextUint64()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(uint64_t));
|
||||||
|
|
||||||
|
// get eight bytes, and convert to host-byte-order
|
||||||
|
uint64_t value;
|
||||||
|
_buffer.copy(_skip, sizeof(uint64_t), &value);
|
||||||
|
return be64toh(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint64_t from the buffer
|
||||||
|
* @return uint64_t value read
|
||||||
|
*/
|
||||||
|
int64_t InBuffer::nextInt64()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(int64_t));
|
||||||
|
|
||||||
|
// get eight bytes, and convert to host-byte-order
|
||||||
|
int64_t value;
|
||||||
|
_buffer.copy(_skip, sizeof(int64_t), &value);
|
||||||
|
return be64toh(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a float from the buffer
|
||||||
|
* @return float float read from buffer.
|
||||||
|
*/
|
||||||
|
float InBuffer::nextFloat()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(float));
|
||||||
|
|
||||||
|
// get four bytes
|
||||||
|
float value;
|
||||||
|
_buffer.copy(_skip, sizeof(float), &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a double from the buffer
|
||||||
|
* @return double double read from buffer
|
||||||
|
*/
|
||||||
|
double InBuffer::nextDouble()
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, sizeof(double));
|
||||||
|
|
||||||
|
// get eight bytes, and convert to host-byte-order
|
||||||
|
double value;
|
||||||
|
_buffer.copy(_skip, sizeof(double), &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a pointer to the next binary buffer of a certain size
|
||||||
|
* @param size
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
const char *InBuffer::nextData(uint32_t size)
|
||||||
|
{
|
||||||
|
// check if there is enough size
|
||||||
|
BufferCheck check(this, size);
|
||||||
|
|
||||||
|
// get the data
|
||||||
|
return _buffer.data(_skip, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue