Line data Source code
1 : // 2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 3 : // 4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 : // 7 : // Official repository: https://github.com/CPPAlliance/http_proto 8 : // 9 : 10 : #ifndef BOOST_HTTP_PROTO_DETAIL_IMPL_CIRCULAR_BUFFER_IPP 11 : #define BOOST_HTTP_PROTO_DETAIL_IMPL_CIRCULAR_BUFFER_IPP 12 : 13 : #include <boost/http_proto/detail/circular_buffer.hpp> 14 : #include <boost/http_proto/detail/except.hpp> 15 : #include <boost/assert.hpp> 16 : 17 : namespace boost { 18 : namespace http_proto { 19 : namespace detail { 20 : 21 8 : circular_buffer:: 22 : circular_buffer( 23 : void* base, 24 8 : std::size_t capacity) noexcept 25 : : base_(reinterpret_cast< 26 : unsigned char*>(base)) 27 8 : , cap_(capacity) 28 : { 29 8 : } 30 : 31 : bool 32 4 : circular_buffer:: 33 : empty() const noexcept 34 : { 35 4 : return in_len_ == 0; 36 : } 37 : 38 : std::size_t 39 5 : circular_buffer:: 40 : size() const noexcept 41 : { 42 5 : return in_len_; 43 : } 44 : 45 : std::size_t 46 5 : circular_buffer:: 47 : capacity() const noexcept 48 : { 49 5 : return cap_; 50 : } 51 : 52 : auto 53 5 : circular_buffer:: 54 : data() const noexcept -> 55 : const_buffers_pair 56 : { 57 5 : if(in_pos_ + in_len_ <= cap_) 58 : return { 59 : const_buffer{ 60 5 : base_ + in_pos_, in_len_ }, 61 5 : const_buffer{ base_, 0} }; 62 : return { 63 : const_buffer{ 64 0 : base_ + in_pos_, cap_ - in_pos_}, 65 : const_buffer{ 66 0 : base_, in_len_- (cap_ - in_pos_)}}; 67 : } 68 : 69 : auto 70 10 : circular_buffer:: 71 : prepare(std::size_t n) -> 72 : mutable_buffers_pair 73 : { 74 : // Precondition violation 75 10 : if(n > cap_ - in_len_) 76 0 : detail::throw_length_error(); 77 10 : out_size_ = n; 78 10 : auto const pos = ( 79 10 : in_pos_ + in_len_) % cap_; 80 10 : if(pos + n <= cap_) 81 : return { 82 : mutable_buffer{ 83 10 : base_ + pos, n}, 84 10 : mutable_buffer{base_, 0}}; 85 : return { 86 : mutable_buffer{ 87 0 : base_ + pos, cap_ - pos}, 88 : mutable_buffer{ 89 0 : base_, n - (cap_ - pos)}}; 90 : } 91 : 92 : void 93 9 : circular_buffer:: 94 : commit(std::size_t n) 95 : { 96 : // Precondition violation 97 9 : if(n > out_size_) 98 0 : detail::throw_length_error(); 99 : 100 9 : in_len_ += n; 101 9 : out_size_ = 0; 102 9 : } 103 : 104 : void 105 0 : circular_buffer:: 106 : uncommit( 107 : std::size_t n) 108 : { 109 : // Precondition violation 110 0 : if( n > in_len_ || 111 0 : out_size_ > 0) 112 0 : detail::throw_length_error(); 113 : 114 0 : in_len_ -= n; 115 0 : } 116 : 117 : void 118 4 : circular_buffer:: 119 : consume(std::size_t n) noexcept 120 : { 121 4 : if(n < in_len_) 122 : { 123 0 : in_pos_ = (in_pos_ + n) % cap_; 124 0 : in_len_ -= n; 125 : } 126 : else 127 : { 128 : // make prepare return a 129 : // bigger single buffer 130 4 : in_pos_ = 0; 131 4 : in_len_ = 0; 132 : } 133 4 : } 134 : 135 : } // detail 136 : } // http_proto 137 : } // boost 138 : 139 : #endif