7#include <bond/core/config.h>
9#include "container_interface.h"
10#include "detail/checked.h"
12#include <boost/make_shared.hpp>
13#include <boost/shared_array.hpp>
26 typedef int8_t value_type;
27 typedef const char* const_iterator;
40 : _buffer(boost::shared_ptr<const void>(), static_cast<const char*>(
content)),
44 bond::detail::checked_add(_buffer.get(),
length);
48 blob(
const boost::shared_ptr<
const char[]>& buffer, uint32_t
length)
52 bond::detail::checked_add(_buffer.get(),
length);
56 blob(
const boost::shared_ptr<
const char[]>& buffer, uint32_t offset, uint32_t
length)
57 : _buffer(buffer,
bond::detail::checked_add(buffer.get(), offset)),
60 bond::detail::checked_add(_buffer.get(),
length);
64 blob(
const boost::shared_ptr<
char[]>& buffer, uint32_t
length)
68 bond::detail::checked_add(_buffer.get(),
length);
72 blob(
const boost::shared_ptr<
char[]>& buffer, uint32_t offset, uint32_t
length)
73 : _buffer(buffer,
bond::detail::checked_add(buffer.get(), offset)),
76 bond::detail::checked_add(_buffer.get(),
length);
82 template <
typename T,
template <
typename U>
class SmartPtr>
84 : _buffer(wrap_in_shared_ptr(buffer)),
87 bond::detail::checked_add(_buffer.get(),
length);
93 template <
typename T,
template <
typename U>
class SmartPtr>
94 blob(
const SmartPtr<T>& buffer, uint32_t offset, uint32_t
length)
95 : _buffer(wrap_in_shared_ptr(buffer, offset)),
98 bond::detail::checked_add(_buffer.get(),
length);
103 std::is_nothrow_move_constructible<boost::shared_ptr<
const char[]> >::value)
104 : _buffer(
std::move(that._buffer)),
105 _length(
std::move(that._length))
110 blob& operator=(
blob&& that) BOND_NOEXCEPT_IF(
111 std::is_nothrow_move_assignable<boost::shared_ptr<
const char[]> >::value)
113 _buffer = std::move(that._buffer);
114 _length = std::move(that._length);
120 blob& operator=(
const blob& that) =
default;
125 if (bond::detail::checked_add(offset,
length) > from._length)
127 throw std::invalid_argument(
"Total of offset and length too large; must be less than or equal to length of blob");
130 _buffer = boost::shared_ptr<const char[]>(from._buffer, from._buffer.get() + offset);
135 template <
typename T>
144 template <
typename T>
155 if (bond::detail::checked_add(offset,
length) > _length)
157 throw std::invalid_argument(
"Total of offset and length too large; must be less than or equal to length of blob");
167 if (offset > _length)
169 throw std::invalid_argument(
"Offset too large; must be less than or equal to length of blob");
172 return blob(_buffer, offset, _length - offset);
178 std::swap(_length, src._length);
179 _buffer.swap(src._buffer);
194 return _buffer.get();
198 const void*
data() const BOND_NOEXCEPT
200 return _buffer.get();
210 uint32_t
size() const BOND_NOEXCEPT
221 bool operator==(
const blob& src)
const BOND_NOEXCEPT
224 || ((_length == src._length)
225 && (0 == ::memcmp(_buffer.get(), src._buffer.get(), _length)));
229 const_iterator
begin() const BOND_NOEXCEPT
231 return _buffer.get();
235 const_iterator
end() const BOND_NOEXCEPT
237 return _buffer.get() + _length;
241 template <
typename T>
242 friend T blob_cast(
const blob& from);
244 template <
typename A>
248 template <
typename T>
255 void operator()(
void const *)
263 template <
typename T,
template <
typename U>
class SmartPtr>
264 static boost::shared_ptr<const char[]> wrap_in_shared_ptr(
const SmartPtr<T>& p, uint32_t offset = 0)
266 boost::shared_ptr<const char[]> ptr(bond::detail::checked_add(
static_cast<const char*
>(
static_cast<const void*
>(p.get())), offset),
267 deleter<SmartPtr<T> >(p));
271 boost::shared_ptr<const char[]> _buffer;
282inline bool operator != (
const blob& x,
const blob& y) BOND_NOEXCEPT
288inline blob merge(
const A& allocator,
const blob& x,
const blob& y)
290 if (x.empty() || y.empty())
296 return x.
empty() ? y : x;
300 uint32_t length = detail::checked_add(x.length(), y.length());
301 boost::shared_ptr<char[]> buffer = boost::allocate_shared_noinit<char[]>(allocator, length);
303 ::memcpy(buffer.get(), x.content(), x.length());
304 ::memcpy(buffer.get() + x.length(), y.content(), y.length());
306 return blob(buffer, length);
310template <
typename t_It,
typename A>
311inline blob merge(
const A& allocator, t_It begin, t_It end)
317 for (t_It it = begin; it != end; ++it)
319 length = detail::checked_add(length, it->length());
329 else if (length == begin->length())
341 BOOST_ASSERT(length > begin->length());
343 boost::shared_ptr<char[]> buffer = boost::allocate_shared_noinit<char[]>(allocator, length);
346 for (t_It it = begin; it != end; ++it)
348 ::memcpy(buffer.get() + offset, it->content(), it->length());
350 offset += it->length();
353 BOOST_ASSERT(offset == length);
354 return blob(buffer, length);
358inline blob merge(
const blob& x,
const blob& y)
360 return merge(std::allocator<char>(), x, y);
363template <
typename t_It>
364inline blob merge(t_It begin, t_It end)
366 return merge(std::allocator<char>(), begin, end);
370is_list_container<blob>
375inline T blob_cast(
const blob& from)
377 if (from._buffer.use_count() != 0)
379 boost::shared_array<char> ptr(
const_cast<char*
>(
static_cast<const char*
>(
static_cast<const void*
>(from._buffer.get()))),
380 blob::deleter<boost::shared_ptr<
const char[]> >(from._buffer));
382 return T(ptr,
static_cast<uint32_t
>(0), from._length);
386 return T(from._buffer.get(), from._length);
395 if (src._buffer.use_count() != 0)
400 boost::shared_ptr<char[]> buffer = boost::allocate_shared_noinit<char[]>(allocator, src.
length());
407 return blob_prolong(std::move(src), std::allocator<char>());
Memory blob.
Definition: blob.h:24
const void * data() const BOND_NOEXCEPT
Void pointer to the content.
Definition: blob.h:198
blob(const boost::shared_ptr< const char[]> &buffer, uint32_t offset, uint32_t length)
Construct from a boost::shared_ptr to const memory buffer.
Definition: blob.h:56
bool empty() const BOND_NOEXCEPT
Check if the blob is empty (i.e. lenght == 0)
Definition: blob.h:216
blob range(uint32_t offset, uint32_t length) const
Return a blob object for a range of this object.
Definition: blob.h:153
const char * content() const BOND_NOEXCEPT
Pointer to the content.
Definition: blob.h:192
blob(const void *content, uint32_t length)
Construct from a raw pointer to memory buffer.
Definition: blob.h:39
blob(const SmartPtr< T > &buffer, uint32_t length)
Construct from a smart pointer other than boost::shared_ptr.
Definition: blob.h:83
const_iterator begin() const BOND_NOEXCEPT
Iterator for the beginning of the blob.
Definition: blob.h:229
uint32_t size() const BOND_NOEXCEPT
Length of the content.
Definition: blob.h:210
void swap(blob &src) BOND_NOEXCEPT
Swap with another blob.
Definition: blob.h:176
void clear() BOND_NOEXCEPT
Clear reference to the underlying memory buffer and reset the blob to empty.
Definition: blob.h:184
blob() BOND_NOEXCEPT
Default constructor.
Definition: blob.h:30
void assign(const T &buffer, uint32_t length)
Assign a new value from a raw or smart pointer.
Definition: blob.h:136
blob(const SmartPtr< T > &buffer, uint32_t offset, uint32_t length)
Construct from a smart pointer other than boost::shared_ptr.
Definition: blob.h:94
blob(blob &&that) BOND_NOEXCEPT_IF(std
Move constructor.
Definition: blob.h:102
const_iterator end() const BOND_NOEXCEPT
Iterator for the end of the blob.
Definition: blob.h:235
uint32_t length() const BOND_NOEXCEPT
Length of the content.
Definition: blob.h:204
blob(const boost::shared_ptr< const char[]> &buffer, uint32_t length)
Construct from a boost::shared_ptr to const memory buffer.
Definition: blob.h:48
void assign(const blob &from, uint32_t offset, uint32_t length)
Assign a new value from another blob object or its part.
Definition: blob.h:123
blob(const boost::shared_ptr< char[]> &buffer, uint32_t length)
Construct from a boost::shared_ptr to memory buffer.
Definition: blob.h:64
blob range(uint32_t offset) const
Return a blob object for a range from the specified offset to the end of the buffer.
Definition: blob.h:165
void assign(const T &buffer, uint32_t offset, uint32_t length)
Assign a new value from a raw or smart pointer.
Definition: blob.h:145
friend blob blob_prolong(blob src, const A &allocator)
Returns a blob with a copy of the data if the original one does not own the memory (i....
Definition: blob.h:393
blob(const boost::shared_ptr< char[]> &buffer, uint32_t offset, uint32_t length)
Construct from a boost::shared_ptr to memory buffer.
Definition: blob.h:72
namespace bond
Definition: apply.h:17
void swap(blob &src, blob &dst) BOND_NOEXCEPT
Swap two blobs.
Definition: blob.h:277
blob blob_prolong(blob src, const A &allocator)
Returns a blob with a copy of the data if the original one does not own the memory (i....
Definition: blob.h:393