aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/src/byte_slice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/src/byte_slice.cpp')
-rw-r--r--contrib/epee/src/byte_slice.cpp67
1 files changed, 59 insertions, 8 deletions
diff --git a/contrib/epee/src/byte_slice.cpp b/contrib/epee/src/byte_slice.cpp
index 3ad3b3e7e..faf7689be 100644
--- a/contrib/epee/src/byte_slice.cpp
+++ b/contrib/epee/src/byte_slice.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019, The Monero Project
+// Copyright (c) 2019-2020, The Monero Project
//
// All rights reserved.
//
@@ -34,6 +34,7 @@
#include <utility>
#include "byte_slice.h"
+#include "byte_stream.h"
namespace epee
{
@@ -117,6 +118,12 @@ namespace epee
}
} // anonymous
+ void release_byte_buffer::operator()(std::uint8_t* buf) const noexcept
+ {
+ if (buf)
+ std::free(buf - sizeof(raw_byte_slice));
+ }
+
byte_slice::byte_slice(byte_slice_data* storage, span<const std::uint8_t> portion) noexcept
: storage_(storage), portion_(portion)
{
@@ -126,10 +133,13 @@ namespace epee
template<typename T>
byte_slice::byte_slice(const adapt_buffer, T&& buffer)
- : storage_(nullptr), portion_(to_byte_span(to_span(buffer)))
+ : storage_(nullptr), portion_(nullptr)
{
if (!buffer.empty())
+ {
storage_ = allocate_slice<adapted_byte_slice<T>>(0, std::move(buffer));
+ portion_ = to_byte_span(to_span(static_cast<adapted_byte_slice<T> *>(storage_.get())->buffer));
+ }
}
byte_slice::byte_slice(std::initializer_list<span<const std::uint8_t>> sources)
@@ -163,6 +173,19 @@ namespace epee
: byte_slice(adapt_buffer{}, std::move(buffer))
{}
+ byte_slice::byte_slice(byte_stream&& stream) noexcept
+ : storage_(nullptr), portion_(stream.data(), stream.size())
+ {
+ if (stream.size())
+ {
+ std::uint8_t* const data = stream.take_buffer().release() - sizeof(raw_byte_slice);
+ new (data) raw_byte_slice{};
+ storage_.reset(reinterpret_cast<raw_byte_slice*>(data));
+ }
+ else
+ portion_ = nullptr;
+ }
+
byte_slice::byte_slice(byte_slice&& source) noexcept
: storage_(std::move(source.storage_)), portion_(source.portion_)
{
@@ -190,14 +213,17 @@ namespace epee
byte_slice byte_slice::take_slice(const std::size_t max_bytes) noexcept
{
byte_slice out{};
- std::uint8_t const* const ptr = data();
- out.portion_ = {ptr, portion_.remove_prefix(max_bytes)};
- if (portion_.empty())
- out.storage_ = std::move(storage_); // no atomic inc/dec
- else
- out = {storage_.get(), out.portion_};
+ if (max_bytes)
+ {
+ std::uint8_t const* const ptr = data();
+ out.portion_ = {ptr, portion_.remove_prefix(max_bytes)};
+ if (portion_.empty())
+ out.storage_ = std::move(storage_); // no atomic inc/dec
+ else
+ out = {storage_.get(), out.portion_};
+ }
return out;
}
@@ -217,4 +243,29 @@ namespace epee
portion_ = nullptr;
return out;
}
+
+ byte_buffer byte_buffer_resize(byte_buffer buf, const std::size_t length) noexcept
+ {
+ if (std::numeric_limits<std::size_t>::max() - sizeof(raw_byte_slice) < length)
+ return nullptr;
+
+ std::uint8_t* data = buf.get();
+ if (data != nullptr)
+ data -= sizeof(raw_byte_slice);
+
+ data = static_cast<std::uint8_t*>(std::realloc(data, sizeof(raw_byte_slice) + length));
+ if (data == nullptr)
+ return nullptr;
+
+ buf.release();
+ buf.reset(data + sizeof(raw_byte_slice));
+ return buf;
+ }
+
+ byte_buffer byte_buffer_increase(byte_buffer buf, const std::size_t current, const std::size_t more)
+ {
+ if (std::numeric_limits<std::size_t>::max() - current < more)
+ throw std::range_error{"byte_buffer_increase size_t overflow"};
+ return byte_buffer_resize(std::move(buf), current + more);
+ }
} // epee