/** * CopiedBuffer.h * * If an output buffer (frame) cannot immediately be sent, we copy it to * memory using this CopiedBuffer class * * @copyright 2017 Copernica BV */ /** * Include guard */ #pragma once /** * Dependencies */ #include #include #include "endian.h" #include "frame.h" /** * Set up namespace */ namespace AMQP { /** * Class definition */ class CopiedBuffer : public OutBuffer { private: /** * The total capacity of the out buffer * @var size_t */ size_t _capacity; /** * Pointer to the beginning of the buffer * @var const char * */ char *_buffer; /** * Current size of the buffer * @var size_t */ size_t _size = 0; /** * Whether the frame is synchronous * @var bool */ bool _synchronous = false; protected: /** * The method that adds the actual data * @param data * @param size */ virtual void append(const void *data, size_t size) override { // copy into the buffer memcpy(_buffer + _size, data, size); // update the size _size += size; } public: /** * Constructor * @param frame */ CopiedBuffer(const Frame &frame) : _capacity(frame.totalSize()), _buffer((char *)malloc(_capacity)), _synchronous(frame.synchronous()) { // tell the frame to fill this buffer frame.fill(*this); // append an end of frame byte (but not when still negotiating the protocol) if (frame.needsSeparator()) add((uint8_t)206); } /** * Disabled copy constructor to prevent expensive copy operations * @param that */ CopiedBuffer(const CopiedBuffer &that) = delete; /** * Move constructor * @param that */ CopiedBuffer(CopiedBuffer &&that) : _capacity(that._capacity), _buffer(that._buffer), _size(that._size), _synchronous(that._synchronous) { // reset the other object that._buffer = nullptr; that._size = 0; that._capacity = 0; } /** * Destructor */ virtual ~CopiedBuffer() { // deallocate the buffer free(_buffer); } /** * Get access to the internal buffer * @return const char* */ const char *data() const { // expose member return _buffer; } /** * Current size of the output buffer * @return size_t */ size_t size() const { // expose member return _size; } /** * Whether the frame is to be sent synchronously * @return bool */ bool synchronous() const noexcept { // expose member return _synchronous; } }; /** * End of namespace */ }