/** * Numeric field types for AMQP * * @copyright 2014 Copernica BV */ /** * Set up namespace */ namespace AMQP { /** * Template for numeric field types */ template< typename T, char F, typename = typename std::enable_if::value, T>, typename = typename std::enable_if::value, T> > class NumericField : public Field { private: /** * Field value */ T _value; public: /** * 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(ReceivedFrame &frame) { // copy the data from the buffer into the field if (!std::is_floating_point::value) { // convert value based on internal storage size switch (sizeof(T)) { case 1: _value = frame.nextUint8(); break; case 2: _value = frame.nextUint16(); break; case 4: _value = frame.nextUint32(); break; case 8: _value = frame.nextUint64(); break; } } else { switch (sizeof(T)) { case 4: _value = frame.nextFloat(); break; case 8: _value = frame.nextDouble(); break; } } } /** * Destructor */ virtual ~NumericField() {} /** * Create a new instance of this object * @return Field* */ virtual Field *clone() const override { // create a new copy of ourselves and return it return new NumericField(_value); } /** * Assign a new value * * @param value new value for field * @return NumericField */ NumericField& operator=(T value) { _value = value; return *this; }; /** * Get the value * @return mixed */ operator T () const { return _value; } /** * Get the value * @return mixed */ T value() const { // return internal value return _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); } /** * Get the maximum allowed value for this field * @return mixed */ constexpr static T max() { return std::numeric_limits::max(); } /** * 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; } }; /** * 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 */ }