1// 2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/boostorg/beast 8// 9 10#ifndef BOOST_BEAST_IMPL_STATIC_BUFFER_IPP 11#define BOOST_BEAST_IMPL_STATIC_BUFFER_IPP 12 13#include <boost/beast/core/static_buffer.hpp> 14#include <boost/asio/buffer.hpp> 15#include <boost/throw_exception.hpp> 16#include <stdexcept> 17 18namespace boost { 19namespace beast { 20 21static_buffer_base:: 22static_buffer_base( 23 void* p, std::size_t size) noexcept 24 : begin_(static_cast<char*>(p)) 25 , capacity_(size) 26{ 27} 28 29void 30static_buffer_base:: 31clear() noexcept 32{ 33 in_off_ = 0; 34 in_size_ = 0; 35 out_size_ = 0; 36} 37 38auto 39static_buffer_base:: 40data() const noexcept -> 41 const_buffers_type 42{ 43 if(in_off_ + in_size_ <= capacity_) 44 return { 45 net::const_buffer{ 46 begin_ + in_off_, in_size_}, 47 net::const_buffer{ 48 begin_, 0}}; 49 return { 50 net::const_buffer{ 51 begin_ + in_off_, capacity_ - in_off_}, 52 net::const_buffer{ 53 begin_, in_size_ - (capacity_ - in_off_)}}; 54} 55 56auto 57static_buffer_base:: 58data() noexcept -> 59 mutable_buffers_type 60{ 61 if(in_off_ + in_size_ <= capacity_) 62 return { 63 net::mutable_buffer{ 64 begin_ + in_off_, in_size_}, 65 net::mutable_buffer{ 66 begin_, 0}}; 67 return { 68 net::mutable_buffer{ 69 begin_ + in_off_, capacity_ - in_off_}, 70 net::mutable_buffer{ 71 begin_, in_size_ - (capacity_ - in_off_)}}; 72} 73 74auto 75static_buffer_base:: 76prepare(std::size_t n) -> 77 mutable_buffers_type 78{ 79 using net::mutable_buffer; 80 if(n > capacity_ - in_size_) 81 BOOST_THROW_EXCEPTION(std::length_error{ 82 "static_buffer overflow"}); 83 out_size_ = n; 84 auto const out_off = 85 (in_off_ + in_size_) % capacity_; 86 if(out_off + out_size_ <= capacity_ ) 87 return { 88 net::mutable_buffer{ 89 begin_ + out_off, out_size_}, 90 net::mutable_buffer{ 91 begin_, 0}}; 92 return { 93 net::mutable_buffer{ 94 begin_ + out_off, capacity_ - out_off}, 95 net::mutable_buffer{ 96 begin_, out_size_ - (capacity_ - out_off)}}; 97} 98 99void 100static_buffer_base:: 101commit(std::size_t n) noexcept 102{ 103 in_size_ += (std::min)(n, out_size_); 104 out_size_ = 0; 105} 106 107void 108static_buffer_base:: 109consume(std::size_t n) noexcept 110{ 111 if(n < in_size_) 112 { 113 in_off_ = (in_off_ + n) % capacity_; 114 in_size_ -= n; 115 } 116 else 117 { 118 // rewind the offset, so the next call to prepare 119 // can have a longer contiguous segment. this helps 120 // algorithms optimized for larger buffers. 121 in_off_ = 0; 122 in_size_ = 0; 123 } 124} 125 126} // beast 127} // boost 128 129#endif 130