/* * charybdis5 * Copyright (C) 2016 Jason Volk * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #pragma once #define HAVE_IRCD_BUFS_H #ifdef __cplusplus #include namespace ircd { inline namespace bufs { using boost::asio::buffer_cast; using boost::asio::const_buffer; using boost::asio::const_buffers_1; using boost::asio::mutable_buffer; using boost::asio::mutable_buffers_1; const mutable_buffer null_buffer { nullptr, 0 }; const std::array null_buffers {{ null_buffer }}; size_t size(const mutable_buffer &buf); size_t size(const const_buffer &buf); template size_t size(const mutable_buffers &iov); template size_t size(const const_buffers &iov); template T data(const mutable_buffer &buf); template T begin(const mutable_buffer &buf); template T end(const mutable_buffer &buf); template std::reverse_iterator rbegin(const mutable_buffer &buf); template std::reverse_iterator rend(const mutable_buffer &buf); template T data(const const_buffer &buf); template T begin(const const_buffer &buf); template T end(const const_buffer &buf); template std::reverse_iterator rbegin(const const_buffer &buf); template std::reverse_iterator rend(const const_buffer &buf); size_t copy(const const_buffer &src, const mutable_buffer &dst); template size_t copy(const buffers &iov, const mutable_buffer &buf); template size_t copy(const mutable_buffer &buf, const mutable_buffers &iov); template size_t copy(const const_buffer &buf, const mutable_buffers &iov); void fill(const mutable_buffer &buf, const uint8_t &val = 0); template void fill(const mutable_buffers &buf, const uint8_t &val = 0); std::string string(const mutable_buffer &); std::string string(const const_buffer &); template struct unique_buffer :buffer { template unique_buffer(std::unique_ptr &&, const size_t &size); unique_buffer(const size_t &size); ~unique_buffer() noexcept; }; template template unique_buffer::unique_buffer(std::unique_ptr &&b, const size_t &size) :buffer{b.release(), size} { } template unique_buffer::unique_buffer(const size_t &size) :unique_buffer { std::unique_ptr{new __attribute__((aligned(16))) uint8_t[size]}, size } { } template unique_buffer::~unique_buffer() noexcept { delete[] data(*this); } template std::string string(const unique_buffer &buf) { return string(static_cast(buf)); } inline std::string string(const const_buffer &buf) { return { data(buf), size(buf) }; } inline std::string string(const mutable_buffer &buf) { return { data(buf), size(buf) }; } template void fill(const mutable_buffers &bufs, const uint8_t &val) { for(auto &buf : bufs) fill(buf, val); } inline void fill(const mutable_buffer &buf, const uint8_t &val) { memset(data(buf), val, size(buf)); } template size_t copy(const const_buffer &buf, const mutable_buffers &iov) { size_t ret(0); for(auto &dst : iov) { const auto remain(buffer_size(buf) - ret); const auto cp_sz(std::min(buffer_size(dst), remain)); const auto src(data(buf) + ret); memcpy(data(dst), src, cp_sz); ret += cp_sz; } return ret; } template size_t copy(const mutable_buffer &buf, const mutable_buffers &iov) { size_t ret(0); for(auto &dst : iov) { const auto remain(buffer_size(buf) - ret); const auto cp_sz(std::min(buffer_size(dst), remain)); const auto src(data(buf) + ret); memcpy(data(dst), src, cp_sz); ret += cp_sz; } return ret; } template size_t copy(const buffers &iov, const mutable_buffer &buf) { size_t ret(0); for(const auto &src : iov) { const auto remain(buffer_size(buf) - ret); const auto cp_sz(std::min(buffer_size(src), remain)); const auto dst(data(buf) + ret); memcpy(dst, data(src), cp_sz); ret += cp_sz; } return ret; } inline size_t copy(const const_buffer &src, const mutable_buffer &dst) { const auto cp_sz(std::min(buffer_size(src), buffer_size(dst))); memcpy(data(dst), data(src), cp_sz); return cp_sz; } template std::reverse_iterator rend(const const_buffer &buf) { return begin(buf); } template std::reverse_iterator rbegin(const const_buffer &buf) { return std::reverse_iterator(begin(buf) + size(buf)); } template T end(const const_buffer &buf) { return begin(buf) + size(buf); } template T begin(const const_buffer &buf) { return data(buf); } template T data(const const_buffer &buf) { return buffer_cast(buf); } template std::reverse_iterator rend(const mutable_buffer &buf) { return begin(buf); } template std::reverse_iterator rbegin(const mutable_buffer &buf) { return std::reverse_iterator(begin(buf) + size(buf)); } template T end(const mutable_buffer &buf) { return begin(buf) + size(buf); } template T begin(const mutable_buffer &buf) { return data(buf); } template T data(const mutable_buffer &buf) { return buffer_cast(buf); } template size_t size(const unique_buffer &buf) { return size(static_cast(buf)); } template size_t size(const buffers &iov) { return std::accumulate(begin(iov), end(iov), size_t(0), [] (auto ret, const auto &buffer) { return ret += size(buffer); }); } inline size_t size(const mutable_buffer &buf) { return buffer_size(buf); } inline size_t size(const const_buffer &buf) { return buffer_size(buf); } } // namespace bufs } // namespace ircd #endif // __cplusplus