diff --git a/include/array.h b/include/array.h index 7e59406..4eb5c30 100644 --- a/include/array.h +++ b/include/array.h @@ -83,8 +83,20 @@ public: */ Array set(uint8_t index, const Field &value) { - // copy to a new pointer and store it - _fields[index] = std::shared_ptr(value.clone()); + // construct a shared pointer + auto ptr = std::shared_ptr(value.clone()); + + // should we overwrite an existing record? + if (index >= _fields.size()) + { + // append index + _fields.push_back(ptr); + } + else + { + // overwrite pointer + _fields[index] = ptr; + } // allow chaining return *this; @@ -108,14 +120,14 @@ public: uint32_t count() const; /** - * Remove last element from array + * Remove last element from array */ void pop_back(); /** - * Add field to end of array + * Add field to end of array * - * @param value + * @param value */ void push_back(const Field &value); @@ -145,6 +157,35 @@ public: { return 'A'; } + + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const + { + // prefix + stream << "array("; + + // is this the first iteration + bool first = true; + + // loop through all members + for (auto iter : _fields) + { + // split with comma + if (!first) stream << ","; + + // show output + stream << *iter; + + // no longer first iter + first = false; + } + + // postfix + stream << ")"; + } }; /** diff --git a/include/booleanset.h b/include/booleanset.h index 577fe47..f165643 100644 --- a/include/booleanset.h +++ b/include/booleanset.h @@ -83,6 +83,22 @@ public: return new BooleanSet(*this); } + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const override + { + // prefix + stream << "booleanset("; + + // the members + for (int i=0; i<8; i++) stream << (i == 0 ? "" : ",") << (get(i) ? 1 : 0); + + // postfix + stream << ")"; + } + /** * Get one of the booleans * @param index from 0 to 7, where 0 is rightmost bit diff --git a/include/connectionhandler.h b/include/connectionhandler.h index f5c1d0c..84210f2 100644 --- a/include/connectionhandler.h +++ b/include/connectionhandler.h @@ -25,8 +25,8 @@ public: * Set a function to be executed after a given timeout. * * This function is not strictly necessary to implement. If you - * do not implement it, certain channel methods that fail - * immediately will not be reported. + * do not implement it, certain methods that fail immediately + * will not be reported. * * @param timeout number of seconds to wait * @param callback function to execute once time runs out diff --git a/include/decimalfield.h b/include/decimalfield.h index c9d3cfc..3164286 100644 --- a/include/decimalfield.h +++ b/include/decimalfield.h @@ -88,6 +88,16 @@ public: return new DecimalField(_places, _number); } + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const override + { + // output floating point value + stream << "decimal(" << _number / pow(10, _places) << ")"; + } + /** * Assign a new value * diff --git a/include/field.h b/include/field.h index 079c741..76f89ba 100644 --- a/include/field.h +++ b/include/field.h @@ -59,9 +59,25 @@ public: */ virtual char typeID() const = 0; - + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const = 0; }; +/** + * Custom output stream operator + * @param stream + * @param field + * @return ostream + */ +inline std::ostream &operator<<(std::ostream &stream, const Field &field) +{ + field.output(stream); + return stream; +} + /** * end namespace */ diff --git a/include/fieldproxy.h b/include/fieldproxy.h index ad8c445..5cafcdc 100644 --- a/include/fieldproxy.h +++ b/include/fieldproxy.h @@ -196,21 +196,14 @@ public: // cast to a string return operator=(std::string(value)); } - + /** - * Get boolean value - * @return BooleanSet + * Get the underlying field + * @return Field */ - operator BooleanSet () + const Field &get() const { - // the value - BooleanSet value; - - // retrieve the value - _source->get(_index, value); - - // return the result - return value; + return _source->get(_index); } /** @@ -219,14 +212,8 @@ public: */ operator bool () { - // the value - BooleanSet value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -235,14 +222,8 @@ public: */ operator int8_t () { - // the value - Octet value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -251,14 +232,8 @@ public: */ operator uint8_t () { - // the value - UOctet value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -267,14 +242,8 @@ public: */ operator int16_t () { - // the value - Short value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -283,14 +252,8 @@ public: */ operator uint16_t () { - // the value - UShort value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -299,14 +262,8 @@ public: */ operator int32_t () { - // the value - Long value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -315,14 +272,8 @@ public: */ operator uint32_t () { - // the value - ULong value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -331,14 +282,8 @@ public: */ operator int64_t () { - // the value - Long value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -347,30 +292,8 @@ public: */ operator uint64_t () { - // the value - ULong value; - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); - } - - /** - * Get decimal value - * @return DecimalField - */ - operator DecimalField () - { - // the value - DecimalField value; - - // retrieve the value - _source->get(_index, value); - - // return the result - return value.value(); + return _source->get(_index); } /** @@ -379,16 +302,8 @@ public: */ operator std::string () { - // it has to be either a short or a long string - ShortString shortValue; - LongString longValue; - - // try to retrieve the value - if (_source->get(_index, shortValue)) return shortValue.value(); - if (_source->get(_index, longValue)) return longValue.value(); - - // no valid string found - return std::string(""); + // retrieve the value + return _source->get(_index); } }; @@ -396,6 +311,30 @@ public: typedef FieldProxy AssociativeFieldProxy; typedef FieldProxy ArrayFieldProxy; +/** + * Custom output stream operator + * @param stream + * @param field + * @return ostream + */ +inline std::ostream &operator<<(std::ostream &stream, const AssociativeFieldProxy &field) +{ + // get underlying field, and output that + return stream << field.get(); +} + +/** + * Custom output stream operator + * @param stream + * @param field + * @return ostream + */ +inline std::ostream &operator<<(std::ostream &stream, const ArrayFieldProxy &field) +{ + // get underlying field, and output that + return stream << field.get(); +} + /** * end namespace */ diff --git a/include/numericfield.h b/include/numericfield.h index 82edf99..9a60e4d 100644 --- a/include/numericfield.h +++ b/include/numericfield.h @@ -157,6 +157,16 @@ public: { return F; } + + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const override + { + // show + stream << "numeric(" << value() << ")"; + } }; /** diff --git a/include/stringfield.h b/include/stringfield.h index 724b495..3def910 100644 --- a/include/stringfield.h +++ b/include/stringfield.h @@ -145,6 +145,16 @@ public: { return F; } + + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const override + { + // show + stream << "string(" << value() << ")"; + } }; /** diff --git a/include/table.h b/include/table.h index 3435f13..f7682e5 100644 --- a/include/table.h +++ b/include/table.h @@ -136,6 +136,35 @@ public: { return 'F'; } + + /** + * Output the object to a stream + * @param std::ostream + */ + virtual void output(std::ostream &stream) const + { + // prefix + stream << "table("; + + // is this the first iteration + bool first = true; + + // loop through all members + for (auto iter : _fields) + { + // split with comma + if (!first) stream << ","; + + // show output + stream << iter.first << ":" << *iter.second; + + // no longer first iter + first = false; + } + + // postfix + stream << ")"; + } }; /** diff --git a/src/array.cpp b/src/array.cpp index 706572d..175c168 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -70,16 +70,27 @@ const Field &Array::get(uint8_t index) return *_fields[index]; } +/** + * Number of entries in the array + * @return uint32_t + */ uint32_t Array::count() const { return _fields.size(); } +/** + * Remove a field from the array + */ void Array::pop_back() { _fields.pop_back(); } +/** + * Add a field to the array + * @param value + */ void Array::push_back(const Field& value) { _fields.push_back(std::shared_ptr(value.clone())); @@ -88,6 +99,7 @@ void Array::push_back(const Field& value) /** * Get the size this field will take when * encoded in the AMQP wire-frame format + * @return size_t */ size_t Array::size() const { @@ -95,11 +107,11 @@ size_t Array::size() const size_t size = 4; // iterate over all elements - for (auto iter(_fields.begin()); iter != _fields.end(); ++iter) + for (auto item : _fields) { // add the size of the field type and size of element - size += sizeof((*iter)->typeID()); - size += (*iter)->size(); + size += sizeof(item->typeID()); + size += item->size(); } // return the result @@ -108,15 +120,19 @@ size_t Array::size() const /** * Write encoded payload to the given buffer. + * @param buffer */ void Array::fill(OutBuffer& buffer) const { + // store total size for all elements + buffer.add(static_cast(size()-4)); + // iterate over all elements - for (auto iter(_fields.begin()); iter != _fields.end(); ++iter) + for (auto item : _fields) { // encode the element type and element - buffer.add((*iter)->typeID()); - (*iter)->fill(buffer); + buffer.add((uint8_t)item->typeID()); + item->fill(buffer); } } diff --git a/src/table.cpp b/src/table.cpp index 4be9b11..d0fb853 100644 --- a/src/table.cpp +++ b/src/table.cpp @@ -145,7 +145,7 @@ size_t Table::size() const void Table::fill(OutBuffer& buffer) const { // add size - buffer.add((uint32_t) size()-4); + buffer.add(static_cast(size()-4)); // loop through the fields for (auto iter(_fields.begin()); iter != _fields.end(); ++iter)