1 // 2 // detail/buffered_stream_storage.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP 12 #define BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 #include <boost/asio/buffer.hpp> 20 #include <boost/asio/detail/assert.hpp> 21 #include <cstddef> 22 #include <cstring> 23 #include <vector> 24 25 #include <boost/asio/detail/push_options.hpp> 26 27 namespace boost { 28 namespace asio { 29 namespace detail { 30 31 class buffered_stream_storage 32 { 33 public: 34 // The type of the bytes stored in the buffer. 35 typedef unsigned char byte_type; 36 37 // The type used for offsets into the buffer. 38 typedef std::size_t size_type; 39 40 // Constructor. buffered_stream_storage(std::size_t buffer_capacity)41 explicit buffered_stream_storage(std::size_t buffer_capacity) 42 : begin_offset_(0), 43 end_offset_(0), 44 buffer_(buffer_capacity) 45 { 46 } 47 48 /// Clear the buffer. clear()49 void clear() 50 { 51 begin_offset_ = 0; 52 end_offset_ = 0; 53 } 54 55 // Return a pointer to the beginning of the unread data. data()56 mutable_buffer data() 57 { 58 return boost::asio::buffer(buffer_) + begin_offset_; 59 } 60 61 // Return a pointer to the beginning of the unread data. data() const62 const_buffer data() const 63 { 64 return boost::asio::buffer(buffer_) + begin_offset_; 65 } 66 67 // Is there no unread data in the buffer. empty() const68 bool empty() const 69 { 70 return begin_offset_ == end_offset_; 71 } 72 73 // Return the amount of unread data the is in the buffer. size() const74 size_type size() const 75 { 76 return end_offset_ - begin_offset_; 77 } 78 79 // Resize the buffer to the specified length. resize(size_type length)80 void resize(size_type length) 81 { 82 BOOST_ASIO_ASSERT(length <= capacity()); 83 if (begin_offset_ + length <= capacity()) 84 { 85 end_offset_ = begin_offset_ + length; 86 } 87 else 88 { 89 using namespace std; // For memmove. 90 memmove(&buffer_[0], &buffer_[0] + begin_offset_, size()); 91 end_offset_ = length; 92 begin_offset_ = 0; 93 } 94 } 95 96 // Return the maximum size for data in the buffer. capacity() const97 size_type capacity() const 98 { 99 return buffer_.size(); 100 } 101 102 // Consume multiple bytes from the beginning of the buffer. consume(size_type count)103 void consume(size_type count) 104 { 105 BOOST_ASIO_ASSERT(begin_offset_ + count <= end_offset_); 106 begin_offset_ += count; 107 if (empty()) 108 clear(); 109 } 110 111 private: 112 // The offset to the beginning of the unread data. 113 size_type begin_offset_; 114 115 // The offset to the end of the unread data. 116 size_type end_offset_; 117 118 // The data in the buffer. 119 std::vector<byte_type> buffer_; 120 }; 121 122 } // namespace detail 123 } // namespace asio 124 } // namespace boost 125 126 #include <boost/asio/detail/pop_options.hpp> 127 128 #endif // BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP 129