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 6 : circular_buffer:: 22 : circular_buffer( 23 : void* base, 24 6 : std::size_t capacity) noexcept 25 : : base_(reinterpret_cast< 26 : unsigned char*>(base)) 27 6 : , cap_(capacity) 28 : { 29 6 : } 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 11 : circular_buffer:: 47 : capacity() const noexcept 48 : { 49 11 : return cap_; 50 : } 51 : 52 : auto 53 4 : circular_buffer:: 54 : data() const noexcept -> 55 : const_buffers_pair 56 : { 57 4 : if(in_pos_ + in_len_ <= cap_) 58 : return { 59 : const_buffer{ 60 4 : base_ + in_pos_, in_len_ }, 61 4 : 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 7 : circular_buffer:: 71 : prepare(std::size_t n) -> 72 : mutable_buffers_pair 73 : { 74 : // Buffer is too small for n 75 7 : if(n > cap_ - in_len_) 76 0 : detail::throw_length_error(); 77 : 78 7 : out_size_ = n; 79 7 : auto const pos = ( 80 7 : in_pos_ + in_len_) % cap_; 81 7 : if(pos + n <= cap_) 82 : return { 83 : mutable_buffer{ 84 7 : base_ + pos, n}, 85 7 : mutable_buffer{base_, 0}}; 86 : return { 87 : mutable_buffer{ 88 0 : base_ + pos, cap_ - pos}, 89 : mutable_buffer{ 90 0 : base_, n - (cap_ - pos)}}; 91 : } 92 : 93 : void 94 7 : circular_buffer:: 95 : commit(std::size_t n) 96 : { 97 : // Precondition violation 98 7 : if(n > out_size_) 99 0 : detail::throw_length_error(); 100 : 101 7 : in_len_ += n; 102 7 : out_size_ = 0; 103 7 : } 104 : 105 : void 106 0 : circular_buffer:: 107 : uncommit( 108 : std::size_t n) 109 : { 110 : // Precondition violation 111 0 : if( n > in_len_ || 112 0 : out_size_ > 0) 113 0 : detail::throw_length_error(); 114 : 115 0 : in_len_ -= n; 116 0 : } 117 : 118 : void 119 4 : circular_buffer:: 120 : consume(std::size_t n) noexcept 121 : { 122 4 : if(n < in_len_) 123 : { 124 0 : in_pos_ = (in_pos_ + n) % cap_; 125 0 : in_len_ -= n; 126 : } 127 : else 128 : { 129 : // make prepare return a 130 : // bigger single buffer 131 4 : in_pos_ = 0; 132 4 : in_len_ = 0; 133 : } 134 4 : } 135 : 136 : } // detail 137 : } // http_proto 138 : } // boost 139 : 140 : #endif