25#ifndef MYSQL_HARNESS_NET_TS_BUFFER_H_
26#define MYSQL_HARNESS_NET_TS_BUFFER_H_
34#include <system_error>
61 class stream_category_impl :
public std::error_category {
63 const char *
name()
const noexcept override {
return "stream"; }
64 std::string message(
int ev)
const override {
76 const std::error_condition &other)
const noexcept override {
77 if (*
this == other.category() ||
78 std::string_view(
name()) ==
79 std::string_view(other.category().name())) {
80 return mycode == other.value();
87 int mycode)
const noexcept override {
88 if (*
this == other.category() ||
89 std::string_view(
name()) ==
90 std::string_view(other.category().name())) {
91 return mycode == other.value();
98 static stream_category_impl instance;
145 const size_t inc_size = std::min(
n,
size_);
146 data_ =
static_cast<const char *
>(
data_) + inc_size;
181 return std::addressof(b);
185 return std::addressof(b) + 1;
210 return std::addressof(b);
215 return std::addressof(b) + 1;
222template <
class T,
class BufferType,
230 std::is_same<Begin, End>,
236template <
class T,
class BufferType,
class =
void>
239template <
class T,
class BufferType>
241 T, BufferType, std::void_t<buffer_sequence_requirements<T, BufferType>>>
261template <
class T,
class =
void>
272template <
class T,
class U = std::remove_const_t<T>>
275 -> std::enable_if_t<std::conjunction<
277 std::is_copy_constructible<U>,
283 std::is_same<
decltype(__const_x->size()),
size_t>,
285 std::is_same<
decltype(__const_x->max_size()),
size_t>,
287 std::is_same<
decltype(__const_x->capacity()),
size_t>,
289 std::is_same<
decltype(__const_x->data(__n, __n)),
290 typename T::const_buffers_type>,
292 std::is_same<
decltype(__x->data(__n, __n)),
293 typename T::mutable_buffers_type>,
295 std::is_void<
decltype(__x->grow(__n))>,
297 std::is_void<
decltype(__x->shrink(__n))>,
299 std::is_void<
decltype(__x->consume(__n))>>::value>;
311template <
class ConstBufferSequence>
312inline size_t buffer_size(
const ConstBufferSequence &buffers)
noexcept {
313 size_t total_size{0};
319 total_size += b.
size();
347template <
class MutableBufferSequence,
class ConstBufferSequence>
349 const ConstBufferSequence &src,
350 const size_t max_size)
noexcept {
351 size_t transfered{0};
360 while (transfered < max_size) {
362 if (src_buf.
size() == 0) {
363 if (src_cur == src_end)
break;
366 if (dest_buf.
size() == 0) {
367 if (dest_cur == dest_end)
break;
371 size_t to_copy = std::min(dest_buf.
size(), src_buf.
size());
372 to_copy = std::min(to_copy, max_size - transfered);
376 std::copy(
static_cast<const char *
>(src_buf.
data()),
377 std::next(
static_cast<const char *
>(src_buf.
data()), to_copy),
378 static_cast<char *
>(dest_buf.
data()));
383 transfered += to_copy;
389template <
class MutableBufferSequence,
class ConstBufferSequence>
391 const ConstBufferSequence &src)
noexcept {
392 return buffer_copy(dest, src, std::numeric_limits<size_t>::max());
398 const size_t inc_size = std::min(
n, b.size());
400 return {
static_cast<char *
>(b.data()) + inc_size, b.size() - inc_size};
407 const size_t inc_size = std::min(
n, b.size());
408 return {
static_cast<const char *
>(b.data()) + inc_size, b.size() - inc_size};
422 return {b.
data(), std::min(b.size(),
n)};
427 return {b.
data(), std::min(b.size(),
n)};
433 return {
n ? data :
nullptr,
sizeof(*data) *
n};
438 return {
n ? data :
nullptr,
sizeof(*data) *
n};
442template <
class T,
size_t N>
447template <
class T,
size_t N>
452template <
class T,
size_t N>
457template <
class T,
size_t N>
462template <
class T,
size_t N>
463inline const_buffer
buffer(
const std::array<T, N> &data)
noexcept {
467template <
class T,
class Allocator>
472template <
class T,
class Allocator>
477template <
class CharT,
class Traits,
class Allocator>
479 std::basic_string<CharT, Traits, Allocator> &data)
noexcept {
484template <
class CharT,
class Traits,
class Allocator>
486 const std::basic_string<CharT, Traits, Allocator> &data)
noexcept {
491template <
class CharT,
class Traits>
493 const std::basic_string_view<CharT, Traits> &data)
noexcept {
498template <
class T, std::
size_t E>
504template <
class T,
size_t N>
509template <
class T,
size_t N>
514template <
class T,
size_t N>
519template <
class T,
size_t N>
524template <
class T,
size_t N>
525inline const_buffer
buffer(
const std::array<T, N> &data,
size_t n)
noexcept {
529template <
class T,
class Allocator>
535template <
class T,
class Allocator>
541template <
class CharT,
class Traits,
class Allocator>
547template <
class CharT,
class Traits,
class Allocator>
549 const std::basic_string<CharT, Traits, Allocator> &data,
554template <
class T, std::
size_t E>
603 throw std::length_error(
"overflow");
605 v_.resize(
v_.size() +
n);
622 size_t m = std::min(
n,
size());
626 v_.erase(
v_.begin(), std::next(
v_.begin(), m));
639template <
class T,
class Allocator>
649template <
class CharT,
class Traits,
class Allocator>
651 std::basic_string<CharT, Traits, Allocator>> {
659template <
class T,
class Allocator>
661 std::vector<T, Allocator> &vec)
noexcept {
665template <
class T,
class Allocator>
667 std::vector<T, Allocator> &vec,
size_t n)
noexcept {
671template <
class CharT,
class Traits,
class Allocator>
673 std::basic_string<CharT, Traits, Allocator> &
str)
noexcept {
677template <
class CharT,
class Traits,
class Allocator>
679 std::basic_string<CharT, Traits, Allocator> &
str,
size_t n)
noexcept {
687 size_t operator()(
const std::error_code &ec,
size_t )
const {
688 if (!ec)
return std::numeric_limits<size_t>::max();
700 if (!ec &&
n <
minimum_)
return std::numeric_limits<size_t>::max();
720 constexpr size_t N = std::numeric_limits<size_t>::max();
732template <
class BufferType>
751 throw std::length_error(
"size() MUST be less than max_size().");
774template <
class BufferSequence,
class BufferType>
796 for (; (from_cur != from_end) && to_bufs.
size() < to_bufs.
max_size() &&
799 if (from_cur->size() > to_skip) {
800 const size_t avail = from_cur->size() - to_skip;
801 const size_t to_use = std::min(avail, max_size);
807 to_skip -= from_cur->size();
832template <
class SyncReadStream,
class MutableBufferSequence>
833std::enable_if_t<is_mutable_buffer_sequence<MutableBufferSequence>::value,
835read(SyncReadStream &stream,
const MutableBufferSequence &buffers) {
841template <
class SyncReadStream,
class MutableBufferSequence,
842 class CompletionCondition>
843std::enable_if_t<is_mutable_buffer_sequence<MutableBufferSequence>::value,
845read(SyncReadStream &stream,
const MutableBufferSequence &buffers,
846 CompletionCondition cond) {
850 std::error_code ec{};
857 while (0 != (to_transfer = cond(ec, consumable.
total_consumed())) &&
859 auto res = stream.read_some(consumable.
prepare(to_transfer));
860 if (!res)
return res;
868template <
class SyncReadStream,
class DynamicBuffer>
869std::enable_if_t<is_dynamic_buffer<std::decay_t<DynamicBuffer>>::value,
871read(SyncReadStream &stream, DynamicBuffer &&b) {
875template <
class SyncReadStream,
class DynamicBuffer,
class CompletionCondition>
876std::enable_if_t<is_dynamic_buffer<std::decay_t<DynamicBuffer>>::value,
878read(SyncReadStream &stream, DynamicBuffer &&b, CompletionCondition cond) {
879 std::error_code ec{};
881 size_t transferred{};
884 while (0 != (to_transfer = cond(ec, transferred)) &&
885 b.size() != b.max_size()) {
886 auto orig_size = b.size();
888 auto avail = b.capacity() - orig_size;
889 size_t grow_size = avail ? avail : 4 * 1024;
890 size_t space_left = b.max_size() - b.size();
892 grow_size = std::min(grow_size, space_left);
894 grow_size = std::min(grow_size, to_transfer);
897 auto res = stream.read_some(b.data(orig_size, grow_size));
903 const auto ec = res.error();
905 std::errc::resource_unavailable_try_again) ||
916 b.shrink(grow_size - *res);
919 return {transferred};
923template <
class AsyncReadStream,
class DynamicBuffer,
class CompletionCondition,
924 class CompletionToken>
925std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_read(
926 AsyncReadStream &stream, DynamicBuffer &&b,
927 CompletionCondition completion_condition, CompletionToken &&token) {
930 using compl_handler_type =
typename decltype(
init)::completion_handler_type;
934 Completor(AsyncReadStream &stream, DynamicBuffer &&b,
935 CompletionCondition compl_cond,
936 compl_handler_type &&compl_handler)
938 b_{std::forward<DynamicBuffer>(b)},
939 compl_cond_{compl_cond},
940 compl_handler_(std::forward<compl_handler_type>(compl_handler)) {}
942 Completor(
const Completor &) =
delete;
943 Completor(Completor &&) =
default;
945 void operator()(std::error_code ec) {
947 compl_handler_(ec, 0);
951 const auto res =
net::read(stream_, b_, compl_cond_);
954 compl_handler_(res.error(), 0);
956 compl_handler_({}, res.value());
963 AsyncReadStream &stream_;
965 CompletionCondition compl_cond_;
966 compl_handler_type compl_handler_;
971 Completor(stream, std::forward<DynamicBuffer>(b), completion_condition,
972 std::move(
init.completion_handler)));
974 return init.result.get();
977template <
class AsyncReadStream,
class DynamicBuffer,
class CompletionToken>
978std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_read(
979 AsyncReadStream &stream, DynamicBuffer &&b, CompletionToken &&token) {
981 std::forward<CompletionToken>(token));
986template <
class SyncWriteStream,
class ConstBufferSequence>
987std::enable_if_t<is_const_buffer_sequence<ConstBufferSequence>::value,
989write(SyncWriteStream &stream,
const ConstBufferSequence &buffers) {
993template <
class SyncWriteStream,
class ConstBufferSequence,
994 class CompletionCondition>
995std::enable_if_t<is_const_buffer_sequence<ConstBufferSequence>::value,
997write(SyncWriteStream &stream,
const ConstBufferSequence &buffers,
998 CompletionCondition cond) {
999 std::error_code ec{};
1006 while (0 != (to_transfer = cond(ec, consumable.
total_consumed())) &&
1008 auto res = stream.write_some(consumable.
prepare(to_transfer));
1028template <
class SyncWriteStream,
class DynamicBuffer>
1029std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
1031write(SyncWriteStream &stream, DynamicBuffer &&b) {
1035template <
class SyncWriteStream,
class DynamicBuffer,
class CompletionCondition>
1036std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
1038write(SyncWriteStream &stream, DynamicBuffer &&b, CompletionCondition cond) {
1039 std::error_code ec{};
1042 size_t transferred{};
1044 while (0 != (to_transfer = cond(ec, transferred)) && (b.size() != 0)) {
1045 auto res = stream.write_some(b.data(0, std::min(b.size(), to_transfer)));
1049 transferred += *res;
1060 transferred == 0)) {
1069template <
class AsyncWriteStream,
class DynamicBuffer,
1070 class CompletionCondition,
class CompletionToken>
1071std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_write(
1072 AsyncWriteStream &stream, DynamicBuffer &&b, CompletionCondition cond,
1073 CompletionToken &&token) {
1076 using compl_handler_type =
typename decltype(
init)::completion_handler_type;
1080 Completor(AsyncWriteStream &stream, DynamicBuffer &&b,
1081 CompletionCondition cond, compl_handler_type &&compl_handler)
1083 b_{std::forward<DynamicBuffer>(b)},
1085 compl_handler_(std::forward<compl_handler_type>(compl_handler)) {}
1087 Completor(
const Completor &) =
delete;
1088 Completor(Completor &&) =
default;
1090 void operator()(std::error_code ec) {
1092 compl_handler_(ec, 0);
1097 net::write(stream_, std::forward<DynamicBuffer>(b_), cond_);
1100 compl_handler_(res.error(), 0);
1102 compl_handler_({}, res.value());
1109 AsyncWriteStream &stream_;
1111 CompletionCondition cond_;
1112 compl_handler_type compl_handler_;
1116 Completor(stream, std::forward<DynamicBuffer>(b), cond,
1117 std::move(
init.completion_handler)));
1119 return init.result.get();
1121template <
class AsyncWriteStream,
class DynamicBuffer,
class CompletionToken>
1122std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_write(
1123 AsyncWriteStream &stream, DynamicBuffer &&b, CompletionToken &&token) {
1124 return async_write(stream, std::forward<DynamicBuffer>(b),
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
Definition: executor.h:71
const_buffer(const mutable_buffer &b) noexcept
Definition: buffer.h:138
const void * data() const noexcept
Definition: buffer.h:141
const void * data_
Definition: buffer.h:152
size_t size() const noexcept
Definition: buffer.h:142
size_t size_
Definition: buffer.h:153
const_buffer() noexcept
Definition: buffer.h:136
const_buffer(const void *p, size_t n) noexcept
Definition: buffer.h:137
const_buffer & operator+=(size_t n) noexcept
Definition: buffer.h:144
size_t total_consumed() const
Definition: buffer.h:823
void consume(size_t n)
mark bytes as consumed from the beginning of the unconsumed sequence.
Definition: buffer.h:820
const BufferSequence & buffers_
Definition: buffer.h:826
consuming_buffers(const BufferSequence &buffers)
Definition: buffer.h:779
prepared_buffer_type prepare(size_t max_size)
prepare a buffer sequence, skipping the already consumed bytes.
Definition: buffer.h:788
size_t total_consumed_
Definition: buffer.h:827
T & v_
Definition: buffer.h:631
const_buffers_type data(size_t pos, size_t n) const noexcept
Definition: buffer.h:590
size_t max_size() const noexcept
max number of bytes.
Definition: buffer.h:581
void grow(size_t n)
append bytes at the end.
Definition: buffer.h:601
dynamic_buffer_base(T &v) noexcept
Definition: buffer.h:568
void consume(size_t n)
remove bytes at the start.
Definition: buffer.h:621
dynamic_buffer_base(T &v, size_t max_size) noexcept
Definition: buffer.h:570
void shrink(size_t n)
remove bytes at the end.
Definition: buffer.h:611
mutable_buffers_type data(size_t pos, size_t n)
Definition: buffer.h:594
const size_t max_size_
Definition: buffer.h:632
size_t size() const noexcept
number of bytes.
Definition: buffer.h:576
size_t capacity() const noexcept
max number of bytes without requiring reallocation.
Definition: buffer.h:586
mutable_buffer(void *p, size_t n) noexcept
Definition: buffer.h:116
mutable_buffer & operator+=(size_t n) noexcept
Definition: buffer.h:121
size_t size_
Definition: buffer.h:129
void * data() const noexcept
Definition: buffer.h:118
mutable_buffer() noexcept
Definition: buffer.h:114
void * data_
Definition: buffer.h:128
size_t size() const noexcept
Definition: buffer.h:119
const_iterator begin() const
Definition: buffer.h:746
typename storage_type::iterator iterator
Definition: buffer.h:744
BufferType value_type
Definition: buffer.h:735
constexpr size_t max_size() const noexcept
Definition: buffer.h:759
size_t used_
Definition: buffer.h:763
typename storage_type::const_iterator const_iterator
Definition: buffer.h:743
void push_back(value_type &&v)
Definition: buffer.h:749
size_t size() const noexcept
Definition: buffer.h:757
std::array< BufferType, 16 > storage_type
Definition: buffer.h:742
const_iterator end() const
Definition: buffer.h:747
storage_type bufs_
Definition: buffer.h:762
size_t operator()(const std::error_code &ec, size_t) const
Definition: buffer.h:687
size_t minimum_
Definition: buffer.h:706
size_t operator()(const std::error_code &ec, size_t n) const
Definition: buffer.h:699
transfer_at_least(size_t m)
Definition: buffer.h:697
transfer_exactly(size_t m)
Definition: buffer.h:713
size_t exact_
Definition: buffer.h:728
size_t operator()(const std::error_code &ec, size_t n) const
Definition: buffer.h:718
const char * p
Definition: ctype-mb.cc:1234
bool equivalent(const MDL_ticket *a, const MDL_ticket *b, enum_mdl_duration target_duration)
Definition: mdl.cc:2614
std::atomic< Type > N
Definition: ut0counter.h:224
uint16_t value_type
Definition: vt100.h:183
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1085
Definition: authentication.cc:35
mutable_buffer to_mutable_buffer(T *data, size_t n)
Definition: buffer.h:432
const_buffer to_const_buffer(const T *data, size_t n)
Definition: buffer.h:437
auto dynamic_buffer_requirements(U *__x=nullptr, const U *__const_x=nullptr, size_t __n=0) -> std::enable_if_t< std::conjunction< std::is_copy_constructible< U >, is_const_buffer_sequence< typename T::const_buffers_type >, is_mutable_buffer_sequence< typename T::mutable_buffers_type >, std::is_same< decltype(__const_x->size()), size_t >, std::is_same< decltype(__const_x->max_size()), size_t >, std::is_same< decltype(__const_x->capacity()), size_t >, std::is_same< decltype(__const_x->data(__n, __n)), typename T::const_buffers_type >, std::is_same< decltype(__x->data(__n, __n)), typename T::mutable_buffers_type >, std::is_void< decltype(__x->grow(__n))>, std::is_void< decltype(__x->shrink(__n))>, std::is_void< decltype(__x->consume(__n))> >::value >
std::bool_constant< std::conjunction_v< std::is_same< Begin, End >, std::is_convertible< typename std::iterator_traits< Begin >::value_type, BufferType > > > buffer_sequence_requirements
Definition: buffer.h:234
const std::error_category & stream_category() noexcept
Definition: buffer.h:60
size_t buffer_size< mutable_buffer >(const mutable_buffer &b) noexcept
Definition: buffer.h:331
constexpr bool is_const_buffer_sequence_v
Definition: buffer.h:162
constexpr bool is_dynamic_buffer_v
Definition: buffer.h:175
const const_buffer * buffer_sequence_end(const const_buffer &b) noexcept
Definition: buffer.h:184
stream_errc
Definition: buffer.h:48
dynamic_vector_buffer< T, Allocator > dynamic_buffer(std::vector< T, Allocator > &vec) noexcept
Definition: buffer.h:660
std::enable_if_t< is_const_buffer_sequence< ConstBufferSequence >::value, stdx::expected< size_t, std::error_code > > write(SyncWriteStream &stream, const ConstBufferSequence &buffers)
Definition: buffer.h:989
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:417
const const_buffer * buffer_sequence_begin(const const_buffer &b) noexcept
Definition: buffer.h:179
constexpr bool is_mutable_buffer_sequence_v
Definition: buffer.h:168
std::enable_if_t< is_dynamic_buffer< DynamicBuffer >::value, void > async_read(AsyncReadStream &stream, DynamicBuffer &&b, CompletionCondition completion_condition, CompletionToken &&token)
Definition: buffer.h:925
size_t buffer_copy(const MutableBufferSequence &dest, const ConstBufferSequence &src, const size_t max_size) noexcept
copy bytes from a ConstBufferSequence to a MutableBufferSequence.
Definition: buffer.h:348
size_t buffer_size(const ConstBufferSequence &buffers) noexcept
Definition: buffer.h:312
size_t buffer_size< const_buffer >(const const_buffer &b) noexcept
Definition: buffer.h:326
mutable_buffer operator+(const mutable_buffer &b, size_t n) noexcept
Definition: buffer.h:397
std::error_condition make_error_condition(net::stream_errc e) noexcept
Definition: buffer.h:106
std::enable_if_t< is_mutable_buffer_sequence< MutableBufferSequence >::value, stdx::expected< size_t, std::error_code > > read(SyncReadStream &stream, const MutableBufferSequence &buffers)
Definition: buffer.h:835
std::error_code make_error_code(net::stream_errc e) noexcept
Definition: buffer.h:102
std::enable_if_t< is_dynamic_buffer< DynamicBuffer >::value, void > async_write(AsyncWriteStream &stream, DynamicBuffer &&b, CompletionCondition cond, CompletionToken &&token)
Definition: buffer.h:1071
Definition: varlen_sort.h:183
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:124
required string type
Definition: replication_group_member_actions.proto:33
case opt name
Definition: sslopt-case.h:32
int n
Definition: xcom_base.cc:508