mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
Add byte_stream for zero-copy serialization, and add support in ZMQ-JSON.
This commit is contained in:
parent
8185054db7
commit
c26c93019a
14 changed files with 806 additions and 171 deletions
|
@ -26,8 +26,9 @@
|
|||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
add_library(epee STATIC byte_slice.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp
|
||||
levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
|
||||
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
int-util.cpp)
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -163,6 +170,14 @@ namespace epee
|
|||
: byte_slice(adapt_buffer{}, std::move(buffer))
|
||||
{}
|
||||
|
||||
byte_slice::byte_slice(byte_stream&& stream) noexcept
|
||||
: storage_(nullptr), portion_(stream.data(), 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));
|
||||
}
|
||||
|
||||
byte_slice::byte_slice(byte_slice&& source) noexcept
|
||||
: storage_(std::move(source.storage_)), portion_(source.portion_)
|
||||
{
|
||||
|
@ -217,4 +232,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
|
||||
|
|
93
contrib/epee/src/byte_stream.cpp
Normal file
93
contrib/epee/src/byte_stream.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "byte_stream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
void byte_stream::overflow(const std::size_t requested)
|
||||
{
|
||||
// Recalculating `need` bytes removes at least one instruction from every
|
||||
// inlined `put` call in header
|
||||
|
||||
assert(available() < requested);
|
||||
const std::size_t need = requested - available();
|
||||
|
||||
const std::size_t len = size();
|
||||
const std::size_t cap = capacity();
|
||||
const std::size_t increase = std::max(need, increase_size());
|
||||
|
||||
next_write_ = nullptr;
|
||||
end_ = nullptr;
|
||||
|
||||
buffer_ = byte_buffer_increase(std::move(buffer_), cap, increase);
|
||||
if (!buffer_)
|
||||
throw std::bad_alloc{};
|
||||
|
||||
next_write_ = buffer_.get() + len;
|
||||
end_ = buffer_.get() + cap + increase;
|
||||
}
|
||||
|
||||
byte_stream::byte_stream(byte_stream&& rhs) noexcept
|
||||
: buffer_(std::move(rhs.buffer_)),
|
||||
next_write_(rhs.next_write_),
|
||||
end_(rhs.end_),
|
||||
increase_size_(rhs.increase_size_)
|
||||
{
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
}
|
||||
|
||||
byte_stream& byte_stream::operator=(byte_stream&& rhs) noexcept
|
||||
{
|
||||
if (this != std::addressof(rhs))
|
||||
{
|
||||
buffer_ = std::move(rhs.buffer_);
|
||||
next_write_ = rhs.next_write_;
|
||||
end_ = rhs.end_;
|
||||
increase_size_ = rhs.increase_size_;
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
byte_buffer byte_stream::take_buffer() noexcept
|
||||
{
|
||||
byte_buffer out{std::move(buffer_)};
|
||||
next_write_ = nullptr;
|
||||
end_ = nullptr;
|
||||
return out;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue