the AMQP::Message and AMQP::Envelope objects can now longer be copied or moved, and the signatures for creating an envelope and publishing a message have been made much more strict. This could be a API breaking change, to the version number should be upped
This commit is contained in:
parent
c6608cee0a
commit
00b81949d3
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Class storing deferred callbacks of different type.
|
* Class storing deferred callbacks of different type.
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,7 +41,7 @@ using EmptyCallback = std::function<void()>;
|
||||||
using BeginCallback = std::function<void()>;
|
using BeginCallback = std::function<void()>;
|
||||||
using HeaderCallback = std::function<void(const MetaData &metaData)>;
|
using HeaderCallback = std::function<void(const MetaData &metaData)>;
|
||||||
using DataCallback = std::function<void(const char *data, size_t size)>;
|
using DataCallback = std::function<void(const char *data, size_t size)>;
|
||||||
using MessageCallback = std::function<void(Message &&message, uint64_t deliveryTag, bool redelivered)>;
|
using MessageCallback = std::function<void(const Message &message, uint64_t deliveryTag, bool redelivered)>;
|
||||||
using CompleteCallback = std::function<void(uint64_t deliveryTag, bool redelivered)>;
|
using CompleteCallback = std::function<void(uint64_t deliveryTag, bool redelivered)>;
|
||||||
using QueueCallback = std::function<void(const std::string &name, uint32_t messagecount, uint32_t consumercount)>;
|
using QueueCallback = std::function<void(const std::string &name, uint32_t messagecount, uint32_t consumercount)>;
|
||||||
using DeleteCallback = std::function<void(uint32_t deletedmessages)>;
|
using DeleteCallback = std::function<void(uint32_t deletedmessages)>;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Class describing a (mid-level) AMQP channel implementation
|
* Class describing a (mid-level) AMQP channel implementation
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -344,10 +344,7 @@ public:
|
||||||
* @param size size of the message
|
* @param size size of the message
|
||||||
*/
|
*/
|
||||||
bool publish(const std::string &exchange, const std::string &routingKey, const Envelope &envelope) { return _implementation->publish(exchange, routingKey, envelope); }
|
bool publish(const std::string &exchange, const std::string &routingKey, const Envelope &envelope) { return _implementation->publish(exchange, routingKey, envelope); }
|
||||||
bool publish(const std::string &exchange, const std::string &routingKey, const std::string &message) { return _implementation->publish(exchange, routingKey, Envelope(message)); }
|
|
||||||
bool publish(const std::string &exchange, const std::string &routingKey, std::string &&message) { return _implementation->publish(exchange, routingKey, Envelope(std::move(message))); }
|
|
||||||
bool publish(const std::string &exchange, const std::string &routingKey, const char *message, size_t size) { return _implementation->publish(exchange, routingKey, Envelope(message, size)); }
|
bool publish(const std::string &exchange, const std::string &routingKey, const char *message, size_t size) { return _implementation->publish(exchange, routingKey, Envelope(message, size)); }
|
||||||
bool publish(const std::string &exchange, const std::string &routingKey, const char *message) { return _implementation->publish(exchange, routingKey, Envelope(message, strlen(message))); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Quality of Service (QOS) for this channel
|
* Set the Quality of Service (QOS) for this channel
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* that has a private constructor so that it can not be used from outside
|
* that has a private constructor so that it can not be used from outside
|
||||||
* the AMQP library
|
* the AMQP library
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* List of all declared classes
|
* List of all declared classes
|
||||||
*
|
*
|
||||||
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -31,7 +32,6 @@ class ConnectionImpl;
|
||||||
class Exchange;
|
class Exchange;
|
||||||
class Frame;
|
class Frame;
|
||||||
class Login;
|
class Login;
|
||||||
class MessageImpl;
|
|
||||||
class Monitor;
|
class Monitor;
|
||||||
class OutBuffer;
|
class OutBuffer;
|
||||||
class ReceivedFrame;
|
class ReceivedFrame;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Deferred callback for consumers
|
* Deferred callback for consumers
|
||||||
*
|
*
|
||||||
* @copyright 2014 - 2016 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,7 +46,7 @@ private:
|
||||||
* @param deliveryTag The delivery tag (for ack()ing)
|
* @param deliveryTag The delivery tag (for ack()ing)
|
||||||
* @param redelivered Is this a redelivered message
|
* @param redelivered Is this a redelivered message
|
||||||
*/
|
*/
|
||||||
virtual void announce(Message &&message, uint64_t deliveryTag, bool redelivered) const override;
|
virtual void announce(const Message &message, uint64_t deliveryTag, bool redelivered) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The channel implementation may call our
|
* The channel implementation may call our
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* Base class for the deferred consumer and the
|
* Base class for the deferred consumer and the
|
||||||
* deferred get.
|
* deferred get.
|
||||||
*
|
*
|
||||||
* @copyright 2016 Copernica B.V.
|
* @copyright 2016 - 2017 Copernica B.V.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -85,7 +85,7 @@ private:
|
||||||
* @param deliveryTag The delivery tag (for ack()ing)
|
* @param deliveryTag The delivery tag (for ack()ing)
|
||||||
* @param redelivered Is this a redelivered message
|
* @param redelivered Is this a redelivered message
|
||||||
*/
|
*/
|
||||||
virtual void announce(Message &&message, uint64_t deliveryTag, bool redelivered) const = 0;
|
virtual void announce(const Message &message, uint64_t deliveryTag, bool redelivered) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frames may be processed
|
* Frames may be processed
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* DeferredGet.h
|
* DeferredGet.h
|
||||||
*
|
*
|
||||||
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
* @copyright 2014 - 2016 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,7 +62,7 @@ private:
|
||||||
* @param deliveryTag The delivery tag (for ack()ing)
|
* @param deliveryTag The delivery tag (for ack()ing)
|
||||||
* @param redelivered Is this a redelivered message
|
* @param redelivered Is this a redelivered message
|
||||||
*/
|
*/
|
||||||
virtual void announce(Message &&message, uint64_t deliveryTag, bool redelivered) const override;
|
virtual void announce(const Message &message, uint64_t deliveryTag, bool redelivered) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The channel implementation may call our
|
* The channel implementation may call our
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* When you send or receive a message to the rabbitMQ server, it is encapsulated
|
* When you send or receive a message to the rabbitMQ server, it is encapsulated
|
||||||
* in an envelope that contains additional meta information as well.
|
* in an envelope that contains additional meta information as well.
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -29,23 +29,22 @@ class Envelope : public MetaData
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* The body (only used when string object was passed to constructor
|
* Pointer to the body data (the memory is not managed by the AMQP library!)
|
||||||
* @var std::string
|
|
||||||
*/
|
|
||||||
std::string _str;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer to the body data (the memory buffer is not managed by the AMQP
|
|
||||||
* library!)
|
|
||||||
* @var const char *
|
* @var const char *
|
||||||
*/
|
*/
|
||||||
const char *_body;
|
char *_body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of the data
|
* Size of the data
|
||||||
* @var uint64_t
|
* @var uint64_t
|
||||||
*/
|
*/
|
||||||
uint64_t _bodySize;
|
uint64_t _bodySize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was the data allocated by this object?
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _allocated = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,120 +56,22 @@ public:
|
||||||
* @param body
|
* @param body
|
||||||
* @param size
|
* @param size
|
||||||
*/
|
*/
|
||||||
Envelope(const char *body, uint64_t size) : MetaData(), _body(body), _bodySize(size) {}
|
Envelope(const char *body, uint64_t size) : MetaData(), _body((char *)body), _bodySize(size) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor based on a string
|
* Disabled copy constructor
|
||||||
* @param body
|
|
||||||
*/
|
|
||||||
Envelope(const std::string &body) : MetaData(), _str(body), _body(_str.data()), _bodySize(_str.size()) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on a string
|
|
||||||
* @param body
|
|
||||||
*/
|
|
||||||
Envelope(std::string &&body) : MetaData(), _str(std::move(body)), _body(_str.data()), _bodySize(_str.size()) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor
|
|
||||||
*
|
*
|
||||||
* @param envelope the envelope to copy
|
* @param envelope the envelope to copy
|
||||||
*/
|
*/
|
||||||
Envelope(const Envelope &envelope) :
|
Envelope(const Envelope &envelope) = delete;
|
||||||
MetaData(envelope),
|
|
||||||
_str(envelope._body, envelope._bodySize),
|
|
||||||
_body(_str.data()),
|
|
||||||
_bodySize(_str.size())
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move constructor
|
|
||||||
*
|
|
||||||
* @param envelope the envelope to move
|
|
||||||
*/
|
|
||||||
Envelope(Envelope &&envelope) :
|
|
||||||
MetaData(std::move(envelope)),
|
|
||||||
_str(std::move(envelope._str)),
|
|
||||||
_body(_str.data()),
|
|
||||||
_bodySize(_str.size())
|
|
||||||
{
|
|
||||||
// if the envelope we moved did not have allocation by string
|
|
||||||
// we are out of luck, and have to copy it ourselves :(
|
|
||||||
if (_str.empty())
|
|
||||||
{
|
|
||||||
// assign the data from the other envelope
|
|
||||||
_str.assign(envelope._body, envelope._bodySize);
|
|
||||||
|
|
||||||
// and set the correct pointer and size
|
|
||||||
_body = _str.data();
|
|
||||||
_bodySize = _str.size();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we moved the other envelopes string
|
|
||||||
// which means their body pointer is now
|
|
||||||
// garbage (it no longer points to a valid
|
|
||||||
// address), so we need to clear it
|
|
||||||
envelope._body = nullptr;
|
|
||||||
envelope._bodySize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~Envelope() {}
|
virtual ~Envelope()
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator
|
|
||||||
*
|
|
||||||
* @param envelope the envelope to copy
|
|
||||||
* @return same object for chaining
|
|
||||||
*/
|
|
||||||
Envelope &operator=(const Envelope &envelope)
|
|
||||||
{
|
{
|
||||||
// copy the data from the envelope
|
// deallocate the data
|
||||||
_str.assign(envelope._body, envelope._bodySize);
|
if (_allocated) free(_body);
|
||||||
|
|
||||||
// set the data pointer and body size
|
|
||||||
_body = _str.data();
|
|
||||||
_bodySize = _str.size();
|
|
||||||
|
|
||||||
// allow chaining
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move assignment operator
|
|
||||||
*
|
|
||||||
* @param envelope the envelope to move
|
|
||||||
* @return same object for chaining
|
|
||||||
*/
|
|
||||||
Envelope &operator=(Envelope &&envelope)
|
|
||||||
{
|
|
||||||
// was the string in the other envelop empty?
|
|
||||||
if (envelope._str.empty())
|
|
||||||
{
|
|
||||||
// that's a shame, we have to make a full copy
|
|
||||||
_str.assign(envelope._body, envelope._bodySize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not empty, just move it
|
|
||||||
_str = std::move(envelope._str);
|
|
||||||
|
|
||||||
// their string is now garbage so the
|
|
||||||
// pointer is also invalid
|
|
||||||
envelope._body = nullptr;
|
|
||||||
envelope._bodySize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we now have a valid string, set the body and
|
|
||||||
_body = _str.data();
|
|
||||||
_bodySize = _str.size();
|
|
||||||
|
|
||||||
// allow chaining
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
* Message objects can not be constructed by end users, they are only constructed
|
* Message objects can not be constructed by end users, they are only constructed
|
||||||
* by the AMQP library, and passed to user callbacks.
|
* by the AMQP library, and passed to user callbacks.
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,8 +48,15 @@ protected:
|
||||||
* The routing key that was originally used
|
* The routing key that was originally used
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
std::string _routingKey;
|
std::string _routingkey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes already filled
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _filled = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are an open book to the consumer handler
|
* We are an open book to the consumer handler
|
||||||
*/
|
*/
|
||||||
|
|
@ -79,43 +86,41 @@ protected:
|
||||||
*/
|
*/
|
||||||
bool append(const char *buffer, uint64_t size)
|
bool append(const char *buffer, uint64_t size)
|
||||||
{
|
{
|
||||||
// is this the only data, and also direct complete?
|
// is the body already allocated?
|
||||||
if (_str.empty() && size >= _bodySize)
|
if (_allocated)
|
||||||
{
|
{
|
||||||
// we have everything
|
// prevent overflow
|
||||||
_body = buffer;
|
size = std::min(size, _bodySize - _filled);
|
||||||
|
|
||||||
// done
|
// append more data
|
||||||
return true;
|
memcpy(_body + _filled, buffer, size);
|
||||||
|
|
||||||
|
// update filled data
|
||||||
|
_filled += size;
|
||||||
|
}
|
||||||
|
else if (size >= _bodySize)
|
||||||
|
{
|
||||||
|
// we do not have to combine multiple frames, so we can store
|
||||||
|
// the buffer pointer in the message
|
||||||
|
_body = (char *)buffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// it does not fit yet, do we have to allocate
|
// allocate the buffer
|
||||||
if (!_body)
|
_body = (char *)malloc(_bodySize);
|
||||||
{
|
|
||||||
// allocate memory in the string
|
// remember that the buffer was allocated, so that the destructor can get rid of it
|
||||||
_str.reserve(static_cast<size_t>(_bodySize));
|
_allocated = true;
|
||||||
|
|
||||||
// we now use the data buffer inside the string
|
// append more data
|
||||||
_body = _str.data();
|
memcpy(_body, buffer, std::min(size, _bodySize));
|
||||||
}
|
|
||||||
|
// update filled data
|
||||||
// safety-check: if the given size exceeds the given message body size
|
_filled = std::min(size, _bodySize);
|
||||||
// we truncate it, this should never happen because it indicates a bug
|
|
||||||
// in the AMQP server implementation, should we report this?
|
|
||||||
size = std::min(size, _bodySize - _str.size());
|
|
||||||
|
|
||||||
// we can not safely append the data to the string, it
|
|
||||||
// will not exceed the reserved size so it is guaranteed
|
|
||||||
// not to change the data pointer, we can just leave that
|
|
||||||
// @todo this is not always necessary; instead, we can refrain from
|
|
||||||
// allocating this buffer entirely and just insert it into the message
|
|
||||||
// directly.
|
|
||||||
_str.append(buffer, static_cast<size_t>(size));
|
|
||||||
|
|
||||||
// if the string is filled with the given number of characters we are done now
|
|
||||||
return _str.size() >= _bodySize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if we're done
|
||||||
|
return _filled >= _bodySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -125,82 +130,28 @@ public:
|
||||||
* @param exchange
|
* @param exchange
|
||||||
* @param routingKey
|
* @param routingKey
|
||||||
*/
|
*/
|
||||||
Message(const std::string &exchange, const std::string &routingKey) :
|
Message(std::string exchange, std::string routingkey) :
|
||||||
Envelope(nullptr, 0), _exchange(exchange), _routingKey(routingKey)
|
Envelope(nullptr, 0), _exchange(std::move(exchange)), _routingkey(std::move(routingkey))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy constructor
|
* Disabled copy constructor
|
||||||
*
|
|
||||||
* @param message the message to copy
|
* @param message the message to copy
|
||||||
*/
|
*/
|
||||||
Message(const Message &message) :
|
Message(const Message &message) = delete;
|
||||||
Envelope(message),
|
|
||||||
_exchange(message._exchange),
|
|
||||||
_routingKey(message._routingKey)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move constructor
|
|
||||||
*
|
|
||||||
* @param message the message to move
|
|
||||||
*/
|
|
||||||
Message(Message &&message) :
|
|
||||||
Envelope(std::move(message)),
|
|
||||||
_exchange(std::move(message._exchange)),
|
|
||||||
_routingKey(std::move(message._routingKey))
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~Message() = default;
|
virtual ~Message() = default;
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator
|
|
||||||
*
|
|
||||||
* @param message the message to copy
|
|
||||||
* @return same object for chaining
|
|
||||||
*/
|
|
||||||
Message &operator=(const Message &message)
|
|
||||||
{
|
|
||||||
// call the base assignment
|
|
||||||
Envelope::operator=(message);
|
|
||||||
|
|
||||||
// move the exchange and routing key
|
|
||||||
_exchange = message._exchange;
|
|
||||||
_routingKey = message._routingKey;
|
|
||||||
|
|
||||||
// allow chaining
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move assignment operator
|
|
||||||
*
|
|
||||||
* @param message the message to move
|
|
||||||
* @return same object for chaining
|
|
||||||
*/
|
|
||||||
Message &operator=(Message &&message)
|
|
||||||
{
|
|
||||||
// call the base assignment
|
|
||||||
Envelope::operator=(std::move(message));
|
|
||||||
|
|
||||||
// move the exchange and routing key
|
|
||||||
_exchange = std::move(message._exchange);
|
|
||||||
_routingKey = std::move(message._routingKey);
|
|
||||||
|
|
||||||
// allow chaining
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The exchange to which it was originally published
|
* The exchange to which it was originally published
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const std::string &exchange() const
|
const std::string &exchange() const
|
||||||
{
|
{
|
||||||
|
// expose member
|
||||||
return _exchange;
|
return _exchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,9 +159,10 @@ public:
|
||||||
* The routing key that was originally used
|
* The routing key that was originally used
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const std::string &routingKey() const
|
const std::string &routingkey() const
|
||||||
{
|
{
|
||||||
return _routingKey;
|
// expose member
|
||||||
|
return _routingkey;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* With every published message a set of meta data is passed to. This class
|
* With every published message a set of meta data is passed to. This class
|
||||||
* holds all that meta data.
|
* holds all that meta data.
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
* This is a class that is used internally by the AMQP library. As a user
|
* 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.
|
* of this library, you normally do not have to instantiate it.
|
||||||
*
|
*
|
||||||
* @documentation public
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Class describing an AMQP basic header frame
|
* Class describing an AMQP basic header frame
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,12 @@
|
||||||
*
|
*
|
||||||
* Implementation for a channel
|
* Implementation for a channel
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "basicdeliverframe.h"
|
#include "basicdeliverframe.h"
|
||||||
#include "basicgetokframe.h"
|
#include "basicgetokframe.h"
|
||||||
#include "basicreturnframe.h"
|
#include "basicreturnframe.h"
|
||||||
#include "messageimpl.h"
|
|
||||||
#include "consumedmessage.h"
|
#include "consumedmessage.h"
|
||||||
#include "returnedmessage.h"
|
#include "returnedmessage.h"
|
||||||
#include "channelopenframe.h"
|
#include "channelopenframe.h"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Base class for a message implementation
|
* Base class for a message implementation
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -12,7 +12,7 @@ namespace AMQP {
|
||||||
/**
|
/**
|
||||||
* Class definition
|
* Class definition
|
||||||
*/
|
*/
|
||||||
class ConsumedMessage : public MessageImpl
|
class ConsumedMessage : public Message
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
@ -40,7 +40,7 @@ public:
|
||||||
* @param frame
|
* @param frame
|
||||||
*/
|
*/
|
||||||
ConsumedMessage(const BasicDeliverFrame &frame) :
|
ConsumedMessage(const BasicDeliverFrame &frame) :
|
||||||
MessageImpl(frame.exchange(), frame.routingKey()),
|
Message(frame.exchange(), frame.routingKey()),
|
||||||
_consumerTag(frame.consumerTag()), _deliveryTag(frame.deliveryTag()), _redelivered(frame.redelivered())
|
_consumerTag(frame.consumerTag()), _deliveryTag(frame.deliveryTag()), _redelivered(frame.redelivered())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ public:
|
||||||
* @param frame
|
* @param frame
|
||||||
*/
|
*/
|
||||||
ConsumedMessage(const BasicGetOKFrame &frame) :
|
ConsumedMessage(const BasicGetOKFrame &frame) :
|
||||||
MessageImpl(frame.exchange(), frame.routingKey()),
|
Message(frame.exchange(), frame.routingKey()),
|
||||||
_deliveryTag(frame.deliveryTag()), _redelivered(frame.redelivered())
|
_deliveryTag(frame.deliveryTag()), _redelivered(frame.redelivered())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ public:
|
||||||
void report(const MessageCallback &callback)
|
void report(const MessageCallback &callback)
|
||||||
{
|
{
|
||||||
// send ourselves to the consumer
|
// send ourselves to the consumer
|
||||||
if (callback) callback(std::move(*this), _deliveryTag, _redelivered);
|
if (callback) callback(*this, _deliveryTag, _redelivered);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Implementation file for the DeferredConsumer class
|
* Implementation file for the DeferredConsumer class
|
||||||
*
|
*
|
||||||
* @copyright 2014 - 2016 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
|
|
@ -38,10 +38,10 @@ const std::shared_ptr<Deferred> &DeferredConsumer::reportSuccess(const std::stri
|
||||||
* @param deliveryTag The delivery tag (for ack()ing)
|
* @param deliveryTag The delivery tag (for ack()ing)
|
||||||
* @param redelivered Is this a redelivered message
|
* @param redelivered Is this a redelivered message
|
||||||
*/
|
*/
|
||||||
void DeferredConsumer::announce(Message &&message, uint64_t deliveryTag, bool redelivered) const
|
void DeferredConsumer::announce(const Message &message, uint64_t deliveryTag, bool redelivered) const
|
||||||
{
|
{
|
||||||
// simply execute the message callback
|
// simply execute the message callback
|
||||||
_messageCallback(std::move(message), deliveryTag, redelivered);
|
_messageCallback(message, deliveryTag, redelivered);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* Base class for the deferred consumer and the
|
* Base class for the deferred consumer and the
|
||||||
* deferred get.
|
* deferred get.
|
||||||
*
|
*
|
||||||
* @copyright 2016 Copernica B.V.
|
* @copyright 2016 - 2017 Copernica B.V.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -120,7 +120,7 @@ void DeferredConsumerBase::complete()
|
||||||
if (_message)
|
if (_message)
|
||||||
{
|
{
|
||||||
// announce the message
|
// announce the message
|
||||||
announce(std::move(*_message), _deliveryTag, _redelivered);
|
announce(*_message, _deliveryTag, _redelivered);
|
||||||
|
|
||||||
// and destroy it
|
// and destroy it
|
||||||
_message.reset();
|
_message.reset();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* Implementation of the DeferredGet call
|
* Implementation of the DeferredGet call
|
||||||
*
|
*
|
||||||
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
* @copyright 2014 - 2016 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -63,7 +63,7 @@ const std::shared_ptr<Deferred> &DeferredGet::reportSuccess() const
|
||||||
* @param deliveryTag The delivery tag (for ack()ing)
|
* @param deliveryTag The delivery tag (for ack()ing)
|
||||||
* @param redelivered Is this a redelivered message
|
* @param redelivered Is this a redelivered message
|
||||||
*/
|
*/
|
||||||
void DeferredGet::announce(Message &&message, uint64_t deliveryTag, bool redelivered) const
|
void DeferredGet::announce(const Message &message, uint64_t deliveryTag, bool redelivered) const
|
||||||
{
|
{
|
||||||
// monitor the channel
|
// monitor the channel
|
||||||
Monitor monitor{ _channel };
|
Monitor monitor{ _channel };
|
||||||
|
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
/**
|
|
||||||
* Base class for a message implementation
|
|
||||||
*
|
|
||||||
* This is the base class for either the returned message or the consumed
|
|
||||||
* message.
|
|
||||||
*
|
|
||||||
* @copyright 2014 Copernica BV
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Namespace
|
|
||||||
*/
|
|
||||||
namespace AMQP {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class definition
|
|
||||||
*/
|
|
||||||
class MessageImpl : public Message
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
* @param exchange
|
|
||||||
* @param routingKey
|
|
||||||
*/
|
|
||||||
MessageImpl(const std::string &exchange, const std::string &routingKey) :
|
|
||||||
Message(exchange, routingKey)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
virtual ~MessageImpl() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the body size
|
|
||||||
* This field is set when the header is received
|
|
||||||
* @param uint64_t
|
|
||||||
*/
|
|
||||||
void setBodySize(uint64_t size)
|
|
||||||
{
|
|
||||||
// safety-check: on 32-bit platforms size_t is obviously also a 32-bit dword
|
|
||||||
// in which case casting the uint64_t to a size_t could result in truncation
|
|
||||||
// here we check whether the given size fits inside a size_t
|
|
||||||
if (std::numeric_limits<size_t>::max() < size) throw std::runtime_error("message is too big for this system");
|
|
||||||
|
|
||||||
// store the new size
|
|
||||||
_bodySize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append data
|
|
||||||
* @param buffer incoming data
|
|
||||||
* @param size size of the data
|
|
||||||
* @return bool true if the message is now complete
|
|
||||||
*/
|
|
||||||
bool append(const char *buffer, uint64_t size)
|
|
||||||
{
|
|
||||||
// is this the only data, and also direct complete?
|
|
||||||
if (_str.empty() && size >= _bodySize)
|
|
||||||
{
|
|
||||||
// we have everything
|
|
||||||
_body = buffer;
|
|
||||||
|
|
||||||
// done
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// it does not fit yet, do we have to allocate
|
|
||||||
if (!_body)
|
|
||||||
{
|
|
||||||
// allocate memory in the string
|
|
||||||
_str.reserve(static_cast<size_t>(_bodySize));
|
|
||||||
|
|
||||||
// we now use the data buffer inside the string
|
|
||||||
_body = _str.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
// safety-check: if the given size exceeds the given message body size
|
|
||||||
// we truncate it, this should never happen because it indicates a bug
|
|
||||||
// in the AMQP server implementation, should we report this?
|
|
||||||
size = std::min(size, _bodySize - _str.size());
|
|
||||||
|
|
||||||
// we can not safely append the data to the string, it
|
|
||||||
// will not exceed the reserved size so it is guaranteed
|
|
||||||
// not to change the data pointer, we can just leave that
|
|
||||||
// @todo this is not always necessary; instead, we can refrain from
|
|
||||||
// allocating this buffer entirely and just insert it into the message
|
|
||||||
// directly.
|
|
||||||
_str.append(buffer, static_cast<size_t>(size));
|
|
||||||
|
|
||||||
// if the string is filled with the given number of characters we are done now
|
|
||||||
return _str.size() >= _bodySize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End of namespace
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Implementation of the ReceivedFrame class
|
* Implementation of the ReceivedFrame class
|
||||||
*
|
*
|
||||||
* @documentation private
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "heartbeatframe.h"
|
#include "heartbeatframe.h"
|
||||||
|
|
@ -65,7 +65,6 @@
|
||||||
#include "transactioncommitokframe.h"
|
#include "transactioncommitokframe.h"
|
||||||
#include "transactionrollbackframe.h"
|
#include "transactionrollbackframe.h"
|
||||||
#include "transactionrollbackokframe.h"
|
#include "transactionrollbackokframe.h"
|
||||||
#include "messageimpl.h"
|
|
||||||
#include "consumedmessage.h"
|
#include "consumedmessage.h"
|
||||||
#include "bodyframe.h"
|
#include "bodyframe.h"
|
||||||
#include "basicheaderframe.h"
|
#include "basicheaderframe.h"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* was published with the immediate or mandatory flag, and could not be
|
* was published with the immediate or mandatory flag, and could not be
|
||||||
* delivered according to those rules.
|
* delivered according to those rules.
|
||||||
*
|
*
|
||||||
* @copyright 2014 Copernica BV
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,7 +16,7 @@ namespace AMQP {
|
||||||
/**
|
/**
|
||||||
* Class definition
|
* Class definition
|
||||||
*/
|
*/
|
||||||
class ReturnedMessage : public MessageImpl
|
class ReturnedMessage : public Message
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,13 +38,13 @@ public:
|
||||||
* @param frame
|
* @param frame
|
||||||
*/
|
*/
|
||||||
ReturnedMessage(const BasicReturnFrame &frame) :
|
ReturnedMessage(const BasicReturnFrame &frame) :
|
||||||
MessageImpl(frame.exchange(), frame.routingKey()),
|
Message(frame.exchange(), frame.routingKey()),
|
||||||
_replyCode(frame.replyCode()), _replyText(frame.replyText()) {}
|
_replyCode(frame.replyCode()), _replyText(frame.replyText()) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~ReturnedMessage() {}
|
virtual ~ReturnedMessage() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue