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 is contained in:
Emiel Bruijntjes 2020-08-14 12:20:22 +02:00
parent ee6ed20430
commit b03cc6ff1c
15 changed files with 27 additions and 356 deletions

View File

@ -1,7 +1,7 @@
/**
* AMQP field array
*
* @copyright 2014, 2015 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -46,7 +46,7 @@ public:
*
* @param frame received frame
*/
Array(ReceivedFrame &frame);
Array(InBuffer &frame);
/**
* Copy constructor

View File

@ -5,7 +5,7 @@
* is a utility class for setting and getting the eight
* booleans
*
* @copyright 2014 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -19,7 +19,7 @@
#include <ostream>
#include "field.h"
#include "outbuffer.h"
#include "receivedframe.h"
#include "inbuffer.h"
/**
* Set up namespace
@ -67,7 +67,7 @@ public:
* Constructor based on incoming data
* @param frame
*/
BooleanSet(ReceivedFrame &frame)
BooleanSet(InBuffer &frame)
{
_byte = frame.nextUint8();
}

View File

@ -1,7 +1,7 @@
/**
* Decimal field type for AMQP
*
* @copyright 2014, 2015 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -16,7 +16,7 @@
#include <ostream>
#include "field.h"
#include "outbuffer.h"
#include "receivedframe.h"
#include "inbuffer.h"
/**
* Set up namespace
@ -81,7 +81,7 @@ public:
* Construct based on incoming data
* @param frame
*/
DecimalField(ReceivedFrame &frame)
DecimalField(InBuffer &frame)
{
_places = frame.nextUint8();
_number = frame.nextUint32();

View File

@ -1,7 +1,7 @@
/**
* Available field types for AMQP
*
* @copyright 2014, 2015 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -22,7 +22,7 @@ namespace AMQP {
/**
* Forward declarations
*/
class ReceivedFrame;
class InBuffer;
class OutBuffer;
class Array;
class Table;
@ -42,7 +42,7 @@ protected:
* @param frame
* @return Field*
*/
static Field *decode(ReceivedFrame &frame);
static Field *decode(InBuffer &frame);
public:
/**

View File

@ -139,7 +139,7 @@ public:
* Read incoming frame
* @param frame
*/
MetaData(ReceivedFrame &frame) :
MetaData(InBuffer &frame) :
_bools1(frame),
_bools2(frame)
{

View File

@ -1,7 +1,7 @@
/**
* Numeric field types for AMQP
*
* @copyright 2014 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -14,7 +14,7 @@
*/
#include <memory>
#include <type_traits>
#include "receivedframe.h"
#include "inbuffer.h"
#include "outbuffer.h"
#include "field.h"
#include <ostream>
@ -60,7 +60,7 @@ public:
* Parse based on incoming buffer
* @param frame
*/
NumericField(ReceivedFrame &frame)
NumericField(InBuffer &frame)
{
// The Microsoft Visual Studio compiler thinks that there is an issue
// with the following code, so we temporarily disable a specific warning

View File

@ -8,7 +8,7 @@
* 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.
*
* @copyright 2014 - 2017 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -35,21 +35,9 @@ class ConnectionImpl;
/**
* Class definition
*/
class ReceivedFrame
class ReceivedFrame : public InBuffer
{
private:
/**
* The buffer we are reading from
* @var Buffer
*/
const Buffer &_buffer;
/**
* Number of bytes already processed
* @var uint32_t
*/
uint32_t _skip = 0;
/**
* Type of frame
* @var uint8_t
@ -187,83 +175,6 @@ public:
return _payloadSize;
}
/**
* 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);
/**
* Process the received frame
*
@ -276,13 +187,6 @@ public:
* @internal
*/
bool process(ConnectionImpl *connection);
/**
* The checker may access private data
*/
friend class FrameCheck;
};
/**

View File

@ -15,7 +15,7 @@
#include "field.h"
#include "outbuffer.h"
#include "numericfield.h"
#include "receivedframe.h"
#include "inbuffer.h"
/**
* Set up namespace
@ -70,7 +70,7 @@ public:
* Construct based on received data
* @param frame
*/
StringField(ReceivedFrame &frame)
StringField(InBuffer &frame)
{
// get the size
T size(frame);

View File

@ -1,7 +1,7 @@
/**
* AMQP field table
*
* @copyright 2014 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -51,7 +51,7 @@ public:
*
* @param frame received frame to decode
*/
Table(ReceivedFrame &frame);
Table(InBuffer &frame);
/**
* Copy constructor

View File

@ -13,7 +13,7 @@ namespace AMQP {
* Constructor based on incoming frame
* @param frame
*/
Array::Array(ReceivedFrame &frame)
Array::Array(InBuffer &frame)
{
// use this to see if we've read too many bytes.
uint32_t charsToRead = frame.nextUint32();

View File

@ -1,7 +1,7 @@
/**
* Field.cpp
*
* @copyright 2014 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
#include "includes.h"
@ -16,7 +16,7 @@ namespace AMQP {
* @param frame
* @return Field*
*/
Field *Field::decode(ReceivedFrame &frame)
Field *Field::decode(InBuffer &frame)
{
// get the type
uint8_t type = frame.nextUint8();

View File

@ -1,61 +0,0 @@
/**
* FrameCheck.h
*
* Class that checks incoming frames for their size
*
* @copyright 2014 Copernica BV
*/
/**
* Set up namespace
*/
namespace AMQP {
/**
* Internal helper class that checks if there is enough room left in the frame
*/
class FrameCheck
{
private:
/**
* The frame
* @var ReceivedFrame
*/
ReceivedFrame *_frame;
/**
* The size that is checked
* @var size_t
*/
size_t _size;
public:
/**
* Constructor
* @param frame
* @param size
*/
FrameCheck(ReceivedFrame *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 ~FrameCheck()
{
// update the number of bytes to skip
_frame->_skip += (uint32_t)_size;
}
};
/**
* End namespace
*/
}

View File

@ -41,6 +41,7 @@
#include "amqpcpp/endian.h"
#include "amqpcpp/buffer.h"
#include "amqpcpp/bytebuffer.h"
#include "amqpcpp/inbuffer.h"
#include "amqpcpp/receivedframe.h"
#include "amqpcpp/outbuffer.h"
#include "amqpcpp/copiedbuffer.h"

View File

@ -70,7 +70,6 @@
#include "consumedmessage.h"
#include "bodyframe.h"
#include "basicheaderframe.h"
#include "framecheck.h"
#define TYPE_INVALID 0
#define END_OF_FRAME 206
@ -85,7 +84,7 @@ namespace AMQP {
* @param buffer Binary buffer
* @param max Max size for a frame
*/
ReceivedFrame::ReceivedFrame(const Buffer &buffer, uint32_t max) : _buffer(buffer)
ReceivedFrame::ReceivedFrame(const Buffer &buffer, uint32_t max) : InBuffer(buffer)
{
// we need enough room for type, channel, the payload size,
// the the end-of-frame byte is not yet necessary
@ -127,178 +126,6 @@ bool ReceivedFrame::complete() const
return _buffer.size() >= _payloadSize + 8;
}
/**
* Read the next uint8 from the buffer
*
* @param char* buffer buffer to read from
* @return uint8_t value read
*/
uint8_t ReceivedFrame::nextUint8()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextInt8()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextUint16()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextInt16()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextUint32()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextInt32()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextUint64()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextInt64()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextFloat()
{
// check if there is enough size
FrameCheck 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 ReceivedFrame::nextDouble()
{
// check if there is enough size
FrameCheck 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 * ReceivedFrame::nextData(uint32_t size)
{
// check if there is enough size
FrameCheck check(this, size);
// get the data
return _buffer.data(_skip, size);
}
/**
* Process the received frame
* @param connection

View File

@ -9,7 +9,7 @@ namespace AMQP {
*
* @param frame received frame to decode
*/
Table::Table(ReceivedFrame &frame)
Table::Table(InBuffer &frame)
{
// table buffer begins with the number of bytes to read
uint32_t bytesToRead = frame.nextUint32();