diff --git a/CHANGELOG.md b/CHANGELOG.md index 2adf490f..4e67b170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ different versioning scheme, following the Haskell community's for compile-time schema and an omitted optional field in the payload. ([Issue \#1120](https://github.com/microsoft/bond/issues/1120)) * Fixed missing include directives. +* Removed `bond::blob`'s unnecessary `_content` member, reducing its size + by 1 pointer. ## 9.0.5: 2021-04-14 ## diff --git a/cpp/inc/bond/core/blob.h b/cpp/inc/bond/core/blob.h index 7ffdbb7b..408925bd 100644 --- a/cpp/inc/bond/core/blob.h +++ b/cpp/inc/bond/core/blob.h @@ -29,7 +29,6 @@ public: /// @brief Default constructor blob() : _buffer(), - _content(), _length() { } @@ -38,47 +37,43 @@ public: /// /// Not recommended because of buffer lifetime management. blob(const void* content, uint32_t length) - : _buffer(), - _content(static_cast(content)), + : _buffer(boost::shared_ptr(), static_cast(content)), // Alias to an empty shared_ptr in order to store + // only a content pointer without the control block. _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Construct from a boost::shared_ptr to const memory buffer blob(const boost::shared_ptr& buffer, uint32_t length) : _buffer(buffer), - _content(_buffer.get()), _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Construct from a boost::shared_ptr to const memory buffer blob(const boost::shared_ptr& buffer, uint32_t offset, uint32_t length) - : _buffer(buffer), - _content(bond::detail::checked_add(_buffer.get(), offset)), + : _buffer(buffer, bond::detail::checked_add(buffer.get(), offset)), _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Construct from a boost::shared_ptr to memory buffer blob(const boost::shared_ptr& buffer, uint32_t length) : _buffer(buffer), - _content(_buffer.get()), _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Construct from a boost::shared_ptr to memory buffer blob(const boost::shared_ptr& buffer, uint32_t offset, uint32_t length) - : _buffer(buffer), - _content(bond::detail::checked_add(_buffer.get(), offset)), + : _buffer(buffer, bond::detail::checked_add(buffer.get(), offset)), _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Construct from a smart pointer other than boost::shared_ptr @@ -87,10 +82,9 @@ public: template class SmartPtr> blob(const SmartPtr& buffer, uint32_t length) : _buffer(wrap_in_shared_ptr(buffer)), - _content(_buffer.get()), _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Construct from a smart pointer other than boost::shared_ptr @@ -98,21 +92,18 @@ public: /// Not recommended for performance reasons. Use boost::shared_ptr whenever possible. template class SmartPtr> blob(const SmartPtr& buffer, uint32_t offset, uint32_t length) - : _buffer(wrap_in_shared_ptr(buffer)), - _content(bond::detail::checked_add(_buffer.get(), offset)), + : _buffer(wrap_in_shared_ptr(buffer, offset)), _length(length) { - bond::detail::checked_add(_content, length); + bond::detail::checked_add(_buffer.get(), length); } /// @brief Move constructor blob(blob&& that) BOND_NOEXCEPT_IF( std::is_nothrow_move_constructible >::value) : _buffer(std::move(that._buffer)), - _content(std::move(that._content)), _length(std::move(that._length)) { - that._content = 0; that._length = 0; } @@ -120,9 +111,7 @@ public: std::is_nothrow_move_assignable >::value) { _buffer = std::move(that._buffer); - _content = std::move(that._content); _length = std::move(that._length); - that._content = 0; that._length = 0; return *this; } @@ -138,8 +127,7 @@ public: throw std::invalid_argument("Total of offset and length too large; must be less than or equal to length of blob"); } - _buffer = from._buffer; - _content = from._content + offset; + _buffer = boost::shared_ptr(from._buffer, from._buffer.get() + offset); _length = length; } @@ -169,12 +157,7 @@ public: throw std::invalid_argument("Total of offset and length too large; must be less than or equal to length of blob"); } - blob temp; - temp._buffer = _buffer; - temp._content = _content + offset; - temp._length = length; - - return temp; + return blob(_buffer, offset, length); } /// @brief Return a blob object for a range from the specified offset to @@ -186,17 +169,12 @@ public: throw std::invalid_argument("Offset too large; must be less than or equal to length of blob"); } - blob temp = *this; - temp._content += offset; - temp._length -= offset; - - return temp; + return blob(_buffer, offset, _length - offset); } /// @brief Swap with another blob void swap(blob& src) { - std::swap(_content, src._content); std::swap(_length, src._length); _buffer.swap(src._buffer); } @@ -213,13 +191,13 @@ public: /// @brief Pointer to the content const char* content() const { - return _content; + return _buffer.get(); } /// @brief Void pointer to the content const void* data() const { - return _content; + return _buffer.get(); } /// @brief Length of the content @@ -244,19 +222,19 @@ public: { return this == &src || ((_length == src._length) - && (0 == ::memcmp(_content, src._content, _length))); + && (0 == ::memcmp(_buffer.get(), src._buffer.get(), _length))); } /// @brief Iterator for the beginning of the blob const_iterator begin() const { - return _content; + return _buffer.get(); } /// @brief Iterator for the end of the blob const_iterator end() const { - return _content + _length; + return _buffer.get() + _length; } @@ -283,17 +261,15 @@ private: }; template class SmartPtr> - static boost::shared_ptr wrap_in_shared_ptr(const SmartPtr& p) + static boost::shared_ptr wrap_in_shared_ptr(const SmartPtr& p, uint32_t offset = 0) { - boost::shared_ptr ptr(static_cast(static_cast(p.get())), + boost::shared_ptr ptr(bond::detail::checked_add(static_cast(static_cast(p.get())), offset), deleter >(p)); return ptr; } boost::shared_ptr _buffer; - const char* _content; - uint32_t _length; }; @@ -398,16 +374,16 @@ is_list_container template inline T blob_cast(const blob& from) { - if (from._buffer) + if (from._buffer.use_count() != 0) { boost::shared_array ptr(const_cast(static_cast(static_cast(from._buffer.get()))), blob::deleter >(from._buffer)); - return T(ptr, static_cast(from._content - from._buffer.get()), from._length); + return T(ptr, static_cast(0), from._length); } else { - return T(from._content, from._length); + return T(from._buffer.get(), from._length); } } @@ -416,7 +392,7 @@ inline T blob_cast(const blob& from) template inline blob blob_prolong(blob src, const A& allocator) { - if (src._buffer) + if (src._buffer.use_count() != 0) { return src; }