123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #ifndef __ASIO2_LINEAR_BUFFER_HPP__
- #define __ASIO2_LINEAR_BUFFER_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif
- #include <limits>
- #include <memory>
- #include <vector>
- #include <asio2/external/asio.hpp>
- namespace asio2
- {
- template<class Container>
- class basic_linear_buffer : protected Container
- {
- public:
-
- using allocator_type = typename Container::allocator_type;
- using size_type = typename Container::size_type;
-
- using const_buffers_type = asio::const_buffer;
-
- using mutable_buffers_type = asio::mutable_buffer;
-
- ~basic_linear_buffer() = default;
- basic_linear_buffer() = default;
- explicit basic_linear_buffer(size_type max) noexcept : Container(), max_(max) {}
- basic_linear_buffer(basic_linear_buffer&& other) = default;
- basic_linear_buffer(basic_linear_buffer const& other) = default;
- basic_linear_buffer& operator=(basic_linear_buffer&& other) = default;
- basic_linear_buffer& operator=(basic_linear_buffer const& other) = default;
-
- inline size_type size() const noexcept
- {
- return (wpos_ - rpos_);
- }
-
- inline size_type max_size() const noexcept
- {
- return max_;
- }
-
- inline size_type capacity() const noexcept
- {
- return Container::capacity();
- }
-
- inline const_buffers_type data() const noexcept
- {
- return { Container::data() + rpos_, wpos_ - rpos_ };
- }
-
- inline mutable_buffers_type prepare(size_type n)
- {
- size_type const cap = Container::capacity();
- if (n <= cap - wpos_)
- {
- Container::resize(wpos_ + n);
-
- return{ Container::data() + wpos_, n };
- }
- size_type const size = this->size();
- if (n <= cap - size)
- {
-
-
- if (size > 0)
- std::memmove(Container::data(), Container::data() + rpos_, size);
- rpos_ = 0;
- wpos_ = size;
- Container::resize(wpos_ + n);
- return { Container::data() + wpos_, n };
- }
-
- if (n > max_ - size)
- asio::detail::throw_exception(std::length_error{ "basic_linear_buffer overflow" });
-
- size_type const new_size = (std::max<size_type>)((std::min<size_type>)(
- max_,
- (std::max<size_type>)(2 * cap, wpos_ + n)), min_size);
- Container::resize(new_size);
- Container::resize(wpos_ + n);
- return { Container::data() + wpos_, n };
- }
-
- inline void commit(size_type n) noexcept
- {
- wpos_ += (std::min<size_type>)(n, Container::size() - wpos_);
- }
-
- inline void consume(size_type n) noexcept
- {
- if (n >= wpos_ - rpos_)
- {
- wpos_ = 0;
- rpos_ = 0;
- Container::resize(0);
- return;
- }
- rpos_ += n;
- }
- inline void shrink_to_fit()
- {
- Container::shrink_to_fit();
- }
- protected:
- size_type rpos_ = 0;
- size_type wpos_ = 0;
- size_type max_ = (std::numeric_limits<size_type>::max)();
- static size_type constexpr min_size = 512;
- };
- using linear_buffer = basic_linear_buffer<std::vector<char>>;
- }
- #endif
|