/** * Numeric field types for AMQP * * @copyright 2014 - 2023 Copernica BV */ /** * Include guard */ #pragma once /** * Dependencies */ #include #include #include "inbuffer.h" #include "outbuffer.h" #include "field.h" #include /** * Set up namespace */ namespace AMQP { /** * Template for numeric field types */ template< typename T, char F, typename = typename std::enable_if::value, T> > class NumericField : public Field { private: /** * Field value */ T _value; public: using Type = T; /** * Default constructor, assign 0 */ NumericField() : _value(0) {} /** * Construct numeric field from * one of numeric types * * @param value field value */ NumericField(T value) : _value(value) {} /** * Parse based on incoming buffer * @param 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 #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4244) #endif if (std::is_same::type>::value) _value = frame.nextInt8(); else if (std::is_same::type>::value) _value = frame.nextInt16(); else if (std::is_same::type>::value) _value = frame.nextInt32(); else if (std::is_same::type>::value) _value = frame.nextInt64(); else if (std::is_same::type>::value) _value = frame.nextUint8(); else if (std::is_same::type>::value) _value = frame.nextUint16(); else if (std::is_same::type>::value) _value = frame.nextUint32(); else if (std::is_same::type>::value) _value = frame.nextUint64(); else if (std::is_same::type>::value) _value = frame.nextFloat(); else if (std::is_same::type>::value) _value = frame.nextDouble(); // re-enable the warning #if defined(_MSC_VER) #pragma warning( pop ) #endif } /** * Destructor */ virtual ~NumericField() {} /** * Create a new instance of this object * @return unique_ptr */ virtual std::unique_ptr clone() const override { // create a new copy of ourselves and return it return std::unique_ptr(new NumericField(_value)); } /** * Assign a new value * * @param value new value for field * @return NumericField */ NumericField& operator=(T value) { _value = value; return *this; }; /** * Clear the field * @return NumericField */ NumericField& clear() { _value = 0; return *this; } /** * Get the value * @return mixed */ operator uint8_t () const override { return (uint8_t)_value; } operator uint16_t() const override { return (uint16_t)_value; } operator uint32_t() const override { return (uint32_t)_value; } operator uint64_t() const override { return (uint64_t)_value; } operator int8_t () const override { return (int8_t)_value; } operator int16_t () const override { return (int16_t)_value; } operator int32_t () const override { return (int32_t)_value; } operator int64_t () const override { return (int64_t)_value; } operator float () const override { return (float)_value; } operator double () const override { return (double)_value; } /** * Get the value * @return mixed */ T value() const { // return internal value return _value; } /** * We are an integer field * * @return true, because we are an integer */ bool isInteger() const override { return std::is_integral::value; } /** * Get the size this field will take when * encoded in the AMQP wire-frame format * @return size_t */ virtual size_t size() const override { // numeric types have no extra storage requirements return sizeof(_value); } /** * Write encoded payload to the given buffer. * @param buffer OutBuffer to write to */ virtual void fill(OutBuffer& buffer) const override { // store converted value T value = _value; // write to buffer // adding a value takes care of host to network byte order buffer.add(value); } /** * Get the type ID that is used to identify this type of * field in a field table */ virtual char typeID() const override { return F; } /** * Output the object to a stream * @param std::ostream */ virtual void output(std::ostream &stream) const override { // show stream << "numeric(" << value() << ")"; } }; /** * Concrete numeric types for AMQP */ typedef NumericField Octet; typedef NumericField UOctet; typedef NumericField Short; typedef NumericField UShort; typedef NumericField Long; typedef NumericField ULong; typedef NumericField LongLong; typedef NumericField ULongLong; typedef NumericField Timestamp; /** * Concrete floating-point types for AMQP */ typedef NumericField Float; typedef NumericField Double; /** * end namespace */ }