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,
232 std::is_same<Begin, End>,
236 BufferType>>::value>;
238template <
class T,
class BufferType,
class =
void>
241template <
class T,
class BufferType>
243 T, BufferType, std::void_t<buffer_sequence_requirements<T, BufferType>>>
263template <
class T,
class =
void>
274template <
class T,
class U = std::remove_const_t<T>>
277 -> std::enable_if_t<std::conjunction<
279 std::is_copy_constructible<U>,
285 std::is_same<
decltype(__const_x->size()),
size_t>,
287 std::is_same<
decltype(__const_x->max_size()),
size_t>,
289 std::is_same<
decltype(__const_x->capacity()),
size_t>,
291 std::is_same<
decltype(__const_x->data(__n, __n)),
292 typename T::const_buffers_type>,
294 std::is_same<
decltype(__x->data(__n, __n)),
295 typename T::mutable_buffers_type>,
297 std::is_void<
decltype(__x->grow(__n))>,
299 std::is_void<
decltype(__x->shrink(__n))>,
301 std::is_void<
decltype(__x->consume(__n))>>::value>;
313template <
class ConstBufferSequence>
314inline size_t buffer_size(
const ConstBufferSequence &buffers)
noexcept {
315 size_t total_size{0};
321 total_size += b.
size();
349template <
class MutableBufferSequence,
class ConstBufferSequence>
351 const ConstBufferSequence &src,
352 const size_t max_size)
noexcept {
353 size_t transfered{0};
362 while (transfered < max_size) {
364 if (src_buf.
size() == 0) {
365 if (src_cur == src_end)
break;
368 if (dest_buf.
size() == 0) {
369 if (dest_cur == dest_end)
break;
373 size_t to_copy = std::min(dest_buf.
size(), src_buf.
size());
374 to_copy = std::min(to_copy, max_size - transfered);
378 std::copy(
static_cast<const char *
>(src_buf.
data()),
379 std::next(
static_cast<const char *
>(src_buf.
data()), to_copy),
380 static_cast<char *
>(dest_buf.
data()));
385 transfered += to_copy;
391template <
class MutableBufferSequence,
class ConstBufferSequence>
393 const ConstBufferSequence &src)
noexcept {
394 return buffer_copy(dest, src, std::numeric_limits<size_t>::max());
400 const size_t inc_size = std::min(
n, b.size());
402 return {
static_cast<char *
>(b.data()) + inc_size, b.size() - inc_size};
409 const size_t inc_size = std::min(
n, b.size());
410 return {
static_cast<const char *
>(b.data()) + inc_size, b.size() - inc_size};
424 return {b.
data(), std::min(b.size(),
n)};
429 return {b.
data(), std::min(b.size(),
n)};
435 return {
n ? data :
nullptr,
sizeof(*data) *
n};
440 return {
n ? data :
nullptr,
sizeof(*data) *
n};
444template <
class T,
size_t N>
449template <
class T,
size_t N>
454template <
class T,
size_t N>
459template <
class T,
size_t N>
464template <
class T,
size_t N>
465inline const_buffer
buffer(
const std::array<T, N> &data)
noexcept {
469template <
class T,
class Allocator>
474template <
class T,
class Allocator>
479template <
class CharT,
class Traits,
class Allocator>
481 std::basic_string<CharT, Traits, Allocator> &data)
noexcept {
486template <
class CharT,
class Traits,
class Allocator>
488 const std::basic_string<CharT, Traits, Allocator> &data)
noexcept {
493template <
class CharT,
class Traits>
495 const std::basic_string_view<CharT, Traits> &data)
noexcept {
500template <
class T, std::
size_t E>
506template <
class T,
size_t N>
511template <
class T,
size_t N>
516template <
class T,
size_t N>
521template <
class T,
size_t N>
526template <
class T,
size_t N>
527inline const_buffer
buffer(
const std::array<T, N> &data,
size_t n)
noexcept {
531template <
class T,
class Allocator>
537template <
class T,
class Allocator>
543template <
class CharT,
class Traits,
class Allocator>
549template <
class CharT,
class Traits,
class Allocator>
551 const std::basic_string<CharT, Traits, Allocator> &data,
556template <
class T, std::
size_t E>
605 throw std::length_error(
"overflow");
607 v_.resize(
v_.size() +
n);
624 size_t m = std::min(
n,
size());
628 v_.erase(
v_.begin(), std::next(
v_.begin(), m));
641template <
class T,
class Allocator>
651template <
class CharT,
class Traits,
class Allocator>
653 std::basic_string<CharT, Traits, Allocator>> {
661template <
class T,
class Allocator>
663 std::vector<T, Allocator> &vec)
noexcept {
667template <
class T,
class Allocator>
669 std::vector<T, Allocator> &vec,
size_t n)
noexcept {
673template <
class CharT,
class Traits,
class Allocator>
675 std::basic_string<CharT, Traits, Allocator> &
str)
noexcept {
679template <
class CharT,
class Traits,
class Allocator>
681 std::basic_string<CharT, Traits, Allocator> &
str,
size_t n)
noexcept {
689 size_t operator()(
const std::error_code &ec,
size_t )
const {
690 if (!ec)
return std::numeric_limits<size_t>::max();
702 if (!ec &&
n <
minimum_)
return std::numeric_limits<size_t>::max();
722 constexpr size_t N = std::numeric_limits<size_t>::max();
734template <
class BufferType>
753 throw std::length_error(
"size() MUST be less than max_size().");
776template <
class BufferSequence,
class BufferType>
798 for (; (from_cur != from_end) && to_bufs.
size() < to_bufs.
max_size() &&
801 if (from_cur->size() > to_skip) {
802 const size_t avail = from_cur->size() - to_skip;
803 const size_t to_use = std::min(avail, max_size);
809 to_skip -= from_cur->size();
834template <
class SyncReadStream,
class MutableBufferSequence>
835std::enable_if_t<is_mutable_buffer_sequence<MutableBufferSequence>::value,
837read(SyncReadStream &stream,
const MutableBufferSequence &buffers) {
843template <
class SyncReadStream,
class MutableBufferSequence,
844 class CompletionCondition>
845std::enable_if_t<is_mutable_buffer_sequence<MutableBufferSequence>::value,
847read(SyncReadStream &stream,
const MutableBufferSequence &buffers,
848 CompletionCondition cond) {
852 std::error_code ec{};
859 while (0 != (to_transfer = cond(ec, consumable.
total_consumed())) &&
861 auto res = stream.read_some(consumable.
prepare(to_transfer));
862 if (!res)
return res;
870template <
class SyncReadStream,
class DynamicBuffer>
871std::enable_if_t<is_dynamic_buffer<std::decay_t<DynamicBuffer>>::value,
873read(SyncReadStream &stream, DynamicBuffer &&b) {
877template <
class SyncReadStream,
class DynamicBuffer,
class CompletionCondition>
878std::enable_if_t<is_dynamic_buffer<std::decay_t<DynamicBuffer>>::value,
880read(SyncReadStream &stream, DynamicBuffer &&b, CompletionCondition cond) {
881 std::error_code ec{};
883 size_t transferred{};
886 while (0 != (to_transfer = cond(ec, transferred)) &&
887 b.size() != b.max_size()) {
888 auto orig_size = b.size();
890 auto avail = b.capacity() - orig_size;
891 size_t grow_size = avail ? avail : 4 * 1024;
892 size_t space_left = b.max_size() - b.size();
894 grow_size = std::min(grow_size, space_left);
896 grow_size = std::min(grow_size, to_transfer);
899 auto res = stream.read_some(b.data(orig_size, grow_size));
905 const auto ec = res.error();
907 std::errc::resource_unavailable_try_again) ||
918 b.shrink(grow_size - *res);
921 return {transferred};
925template <
class AsyncReadStream,
class DynamicBuffer,
class CompletionCondition,
926 class CompletionToken>
927std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_read(
928 AsyncReadStream &stream, DynamicBuffer &&b,
929 CompletionCondition completion_condition, CompletionToken &&token) {
932 using compl_handler_type =
typename decltype(
init)::completion_handler_type;
936 Completor(AsyncReadStream &stream, DynamicBuffer &&b,
937 CompletionCondition compl_cond,
938 compl_handler_type &&compl_handler)
940 b_{std::forward<DynamicBuffer>(b)},
941 compl_cond_{compl_cond},
942 compl_handler_(std::forward<compl_handler_type>(compl_handler)) {}
944 Completor(
const Completor &) =
delete;
945 Completor(Completor &&) =
default;
947 void operator()(std::error_code ec) {
949 compl_handler_(ec, 0);
953 const auto res =
net::read(stream_, b_, compl_cond_);
956 compl_handler_(res.error(), 0);
958 compl_handler_({}, res.value());
965 AsyncReadStream &stream_;
967 CompletionCondition compl_cond_;
968 compl_handler_type compl_handler_;
973 Completor(stream, std::forward<DynamicBuffer>(b), completion_condition,
974 std::move(
init.completion_handler)));
976 return init.result.get();
979template <
class AsyncReadStream,
class DynamicBuffer,
class CompletionToken>
980std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_read(
981 AsyncReadStream &stream, DynamicBuffer &&b, CompletionToken &&token) {
983 std::forward<CompletionToken>(token));
988template <
class SyncWriteStream,
class ConstBufferSequence>
989std::enable_if_t<is_const_buffer_sequence<ConstBufferSequence>::value,
991write(SyncWriteStream &stream,
const ConstBufferSequence &buffers) {
995template <
class SyncWriteStream,
class ConstBufferSequence,
996 class CompletionCondition>
997std::enable_if_t<is_const_buffer_sequence<ConstBufferSequence>::value,
999write(SyncWriteStream &stream,
const ConstBufferSequence &buffers,
1000 CompletionCondition cond) {
1001 std::error_code ec{};
1008 while (0 != (to_transfer = cond(ec, consumable.
total_consumed())) &&
1010 auto res = stream.write_some(consumable.
prepare(to_transfer));
1030template <
class SyncWriteStream,
class DynamicBuffer>
1031std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
1033write(SyncWriteStream &stream, DynamicBuffer &&b) {
1037template <
class SyncWriteStream,
class DynamicBuffer,
class CompletionCondition>
1038std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
1040write(SyncWriteStream &stream, DynamicBuffer &&b, CompletionCondition cond) {
1041 std::error_code ec{};
1044 size_t transferred{};
1046 while (0 != (to_transfer = cond(ec, transferred)) && (b.size() != 0)) {
1047 auto res = stream.write_some(b.data(0, std::min(b.size(), to_transfer)));
1051 transferred += *res;
1062 transferred == 0)) {
1071template <
class AsyncWriteStream,
class DynamicBuffer,
1072 class CompletionCondition,
class CompletionToken>
1073std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_write(
1074 AsyncWriteStream &stream, DynamicBuffer &&b, CompletionCondition cond,
1075 CompletionToken &&token) {
1078 using compl_handler_type =
typename decltype(
init)::completion_handler_type;
1082 Completor(AsyncWriteStream &stream, DynamicBuffer &&b,
1083 CompletionCondition cond, compl_handler_type &&compl_handler)
1085 b_{std::forward<DynamicBuffer>(b)},
1087 compl_handler_(std::forward<compl_handler_type>(compl_handler)) {}
1089 Completor(
const Completor &) =
delete;
1090 Completor(Completor &&) =
default;
1092 void operator()(std::error_code ec) {
1094 compl_handler_(ec, 0);
1099 net::write(stream_, std::forward<DynamicBuffer>(b_), cond_);
1102 compl_handler_(res.error(), 0);
1104 compl_handler_({}, res.value());
1111 AsyncWriteStream &stream_;
1113 CompletionCondition cond_;
1114 compl_handler_type compl_handler_;
1118 Completor(stream, std::forward<DynamicBuffer>(b), cond,
1119 std::move(
init.completion_handler)));
1121 return init.result.get();
1123template <
class AsyncWriteStream,
class DynamicBuffer,
class CompletionToken>
1124std::enable_if_t<is_dynamic_buffer<DynamicBuffer>::value,
void>
async_write(
1125 AsyncWriteStream &stream, DynamicBuffer &&b, CompletionToken &&token) {
1126 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:825
void consume(size_t n)
mark bytes as consumed from the beginning of the unconsumed sequence.
Definition: buffer.h:822
const BufferSequence & buffers_
Definition: buffer.h:828
consuming_buffers(const BufferSequence &buffers)
Definition: buffer.h:781
prepared_buffer_type prepare(size_t max_size)
prepare a buffer sequence, skipping the already consumed bytes.
Definition: buffer.h:790
size_t total_consumed_
Definition: buffer.h:829
T & v_
Definition: buffer.h:633
const_buffers_type data(size_t pos, size_t n) const noexcept
Definition: buffer.h:592
size_t max_size() const noexcept
max number of bytes.
Definition: buffer.h:583
void grow(size_t n)
append bytes at the end.
Definition: buffer.h:603
dynamic_buffer_base(T &v) noexcept
Definition: buffer.h:570
void consume(size_t n)
remove bytes at the start.
Definition: buffer.h:623
dynamic_buffer_base(T &v, size_t max_size) noexcept
Definition: buffer.h:572
void shrink(size_t n)
remove bytes at the end.
Definition: buffer.h:613
mutable_buffers_type data(size_t pos, size_t n)
Definition: buffer.h:596
const size_t max_size_
Definition: buffer.h:634
size_t size() const noexcept
number of bytes.
Definition: buffer.h:578
size_t capacity() const noexcept
max number of bytes without requiring reallocation.
Definition: buffer.h:588
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:748
typename storage_type::iterator iterator
Definition: buffer.h:746
BufferType value_type
Definition: buffer.h:737
constexpr size_t max_size() const noexcept
Definition: buffer.h:761
size_t used_
Definition: buffer.h:765
typename storage_type::const_iterator const_iterator
Definition: buffer.h:745
void push_back(value_type &&v)
Definition: buffer.h:751
size_t size() const noexcept
Definition: buffer.h:759
std::array< BufferType, 16 > storage_type
Definition: buffer.h:744
const_iterator end() const
Definition: buffer.h:749
storage_type bufs_
Definition: buffer.h:764
size_t operator()(const std::error_code &ec, size_t) const
Definition: buffer.h:689
size_t minimum_
Definition: buffer.h:708
size_t operator()(const std::error_code &ec, size_t n) const
Definition: buffer.h:701
transfer_at_least(size_t m)
Definition: buffer.h:699
transfer_exactly(size_t m)
Definition: buffer.h:715
size_t exact_
Definition: buffer.h:730
size_t operator()(const std::error_code &ec, size_t n) const
Definition: buffer.h:720
const char * p
Definition: ctype-mb.cc:1236
bool equivalent(const MDL_ticket *a, const MDL_ticket *b, enum_mdl_duration target_duration)
Definition: mdl.cc:2612
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:1054
Definition: authentication.cc:35
mutable_buffer to_mutable_buffer(T *data, size_t n)
Definition: buffer.h:434
std::integral_constant< bool, std::conjunction< std::is_same< Begin, End >, std::is_convertible< typename std::iterator_traits< Begin >::value_type, BufferType > >::value > buffer_sequence_requirements
Definition: buffer.h:236
const_buffer to_const_buffer(const T *data, size_t n)
Definition: buffer.h:439
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 >
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:333
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:662
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:991
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:419
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:927
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:350
size_t buffer_size(const ConstBufferSequence &buffers) noexcept
Definition: buffer.h:314
size_t buffer_size< const_buffer >(const const_buffer &b) noexcept
Definition: buffer.h:328
mutable_buffer operator+(const mutable_buffer &b, size_t n) noexcept
Definition: buffer.h:399
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:837
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:1073
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:191
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