1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/**
* 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 <memory>
#include <cstring>
#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
*/
}
|