5
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11
#ifndef ASIO_BASIC_STREAMBUF_HPP
12
#define ASIO_BASIC_STREAMBUF_HPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/detail/push_options.hpp"
27
#include "asio/detail/pop_options.hpp"
29
#include "asio/buffer.hpp"
30
#include "asio/detail/noncopyable.hpp"
34
/// Automatically resizable buffer class based on std::streambuf.
35
template <typename Allocator = std::allocator<char> >
37
: public std::streambuf,
41
#if defined(GENERATING_DOCUMENTATION)
42
/// The type used to represent the get area as a list of buffers.
43
typedef implementation_defined const_buffers_type;
45
/// The type used to represent the put area as a list of buffers.
46
typedef implementation_defined mutable_buffers_type;
48
typedef asio::const_buffers_1 const_buffers_type;
49
typedef asio::mutable_buffers_1 mutable_buffers_type;
52
/// Construct a buffer with a specified maximum size.
53
explicit basic_streambuf(
54
std::size_t max_size = (std::numeric_limits<std::size_t>::max)(),
55
const Allocator& allocator = Allocator())
56
: max_size_(max_size),
59
std::size_t pend = (std::min<std::size_t>)(max_size_, buffer_delta);
60
buffer_.resize((std::max<std::size_t>)(pend, 1));
61
setg(&buffer_[0], &buffer_[0], &buffer_[0]);
62
setp(&buffer_[0], &buffer_[0] + pend);
65
/// Return the size of the get area in characters.
66
std::size_t size() const
68
return pptr() - gptr();
71
/// Return the maximum size of the buffer.
72
std::size_t max_size() const
77
/// Get a list of buffers that represents the get area.
78
const_buffers_type data() const
80
return asio::buffer(asio::const_buffer(gptr(),
81
(pptr() - gptr()) * sizeof(char_type)));
84
/// Get a list of buffers that represents the put area, with the given size.
85
mutable_buffers_type prepare(std::size_t size)
88
return asio::buffer(asio::mutable_buffer(
89
pptr(), size * sizeof(char_type)));
92
/// Move the start of the put area by the specified number of characters.
93
void commit(std::size_t n)
95
if (pptr() + n > epptr())
97
pbump(static_cast<int>(n));
100
/// Move the start of the get area by the specified number of characters.
101
void consume(std::size_t n)
103
if (gptr() + n > pptr())
105
gbump(static_cast<int>(n));
109
enum { buffer_delta = 128 };
115
setg(&buffer_[0], gptr(), pptr());
116
return traits_type::to_int_type(*gptr());
120
return traits_type::eof();
124
int_type overflow(int_type c)
126
if (!traits_type::eq_int_type(c, traits_type::eof()))
128
if (pptr() == epptr())
130
std::size_t buffer_size = pptr() - gptr();
131
if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta)
133
reserve(max_size_ - buffer_size);
137
reserve(buffer_delta);
141
*pptr() = traits_type::to_char_type(c);
146
return traits_type::not_eof(c);
149
void reserve(std::size_t n)
151
// Get current stream positions as offsets.
152
std::size_t gnext = gptr() - &buffer_[0];
153
std::size_t gend = egptr() - &buffer_[0];
154
std::size_t pnext = pptr() - &buffer_[0];
155
std::size_t pend = epptr() - &buffer_[0];
157
// Check if there is already enough space in the put area.
158
if (n <= pend - pnext)
163
// Shift existing contents of get area to start of buffer.
166
std::rotate(&buffer_[0], &buffer_[0] + gnext, &buffer_[0] + pend);
171
// Ensure buffer is large enough to hold at least the specified size.
172
if (n > pend - pnext)
174
if (n <= max_size_ && pnext <= max_size_ - n)
176
buffer_.resize((std::max<std::size_t>)(pnext + n, 1));
180
throw std::length_error("asio::streambuf too long");
184
// Update stream positions.
185
setg(&buffer_[0], &buffer_[0], &buffer_[0] + gend);
186
setp(&buffer_[0] + pnext, &buffer_[0] + pnext + n);
190
std::size_t max_size_;
191
std::vector<char_type, Allocator> buffer_;
196
#include "asio/detail/pop_options.hpp"
198
#endif // ASIO_BASIC_STREAMBUF_HPP