Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_BASIC_STREAMBUF_HPP
00012 #define ASIO_BASIC_STREAMBUF_HPP
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017
00018 #include "asio/detail/push_options.hpp"
00019
00020 #include "asio/detail/push_options.hpp"
00021 #include <algorithm>
00022 #include <limits>
00023 #include <memory>
00024 #include <stdexcept>
00025 #include <streambuf>
00026 #include <vector>
00027 #include "asio/detail/pop_options.hpp"
00028
00029 #include "asio/buffer.hpp"
00030 #include "asio/detail/noncopyable.hpp"
00031
00032 namespace asio {
00033
00035 template <typename Allocator = std::allocator<char> >
00036 class basic_streambuf
00037 : public std::streambuf,
00038 private noncopyable
00039 {
00040 public:
00041 #if defined(GENERATING_DOCUMENTATION)
00042
00043 typedef implementation_defined const_buffers_type;
00044
00046 typedef implementation_defined mutable_buffers_type;
00047 #else
00048 typedef asio::const_buffers_1 const_buffers_type;
00049 typedef asio::mutable_buffers_1 mutable_buffers_type;
00050 #endif
00051
00053 explicit basic_streambuf(
00054 std::size_t max_size = (std::numeric_limits<std::size_t>::max)(),
00055 const Allocator& allocator = Allocator())
00056 : max_size_(max_size),
00057 buffer_(allocator)
00058 {
00059 std::size_t pend = (std::min<std::size_t>)(max_size_, buffer_delta);
00060 buffer_.resize((std::max<std::size_t>)(pend, 1));
00061 setg(&buffer_[0], &buffer_[0], &buffer_[0]);
00062 setp(&buffer_[0], &buffer_[0] + pend);
00063 }
00064
00066 std::size_t size() const
00067 {
00068 return pptr() - gptr();
00069 }
00070
00072 std::size_t max_size() const
00073 {
00074 return max_size_;
00075 }
00076
00078 const_buffers_type data() const
00079 {
00080 return asio::buffer(asio::const_buffer(gptr(),
00081 (pptr() - gptr()) * sizeof(char_type)));
00082 }
00083
00085 mutable_buffers_type prepare(std::size_t size)
00086 {
00087 reserve(size);
00088 return asio::buffer(asio::mutable_buffer(
00089 pptr(), size * sizeof(char_type)));
00090 }
00091
00093 void commit(std::size_t n)
00094 {
00095 if (pptr() + n > epptr())
00096 n = epptr() - pptr();
00097 pbump(static_cast<int>(n));
00098 }
00099
00101 void consume(std::size_t n)
00102 {
00103 if (gptr() + n > pptr())
00104 n = pptr() - gptr();
00105 gbump(static_cast<int>(n));
00106 }
00107
00108 protected:
00109 enum { buffer_delta = 128 };
00110
00111 int_type underflow()
00112 {
00113 if (gptr() < pptr())
00114 {
00115 setg(&buffer_[0], gptr(), pptr());
00116 return traits_type::to_int_type(*gptr());
00117 }
00118 else
00119 {
00120 return traits_type::eof();
00121 }
00122 }
00123
00124 int_type overflow(int_type c)
00125 {
00126 if (!traits_type::eq_int_type(c, traits_type::eof()))
00127 {
00128 if (pptr() == epptr())
00129 {
00130 std::size_t buffer_size = pptr() - gptr();
00131 if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta)
00132 {
00133 reserve(max_size_ - buffer_size);
00134 }
00135 else
00136 {
00137 reserve(buffer_delta);
00138 }
00139 }
00140
00141 *pptr() = traits_type::to_char_type(c);
00142 pbump(1);
00143 return c;
00144 }
00145
00146 return traits_type::not_eof(c);
00147 }
00148
00149 void reserve(std::size_t n)
00150 {
00151
00152 std::size_t gnext = gptr() - &buffer_[0];
00153 std::size_t gend = egptr() - &buffer_[0];
00154 std::size_t pnext = pptr() - &buffer_[0];
00155 std::size_t pend = epptr() - &buffer_[0];
00156
00157
00158 if (n <= pend - pnext)
00159 {
00160 return;
00161 }
00162
00163
00164 if (gnext > 0)
00165 {
00166 std::rotate(&buffer_[0], &buffer_[0] + gnext, &buffer_[0] + pend);
00167 gend -= gnext;
00168 pnext -= gnext;
00169 }
00170
00171
00172 if (n > pend - pnext)
00173 {
00174 if (n <= max_size_ && pnext <= max_size_ - n)
00175 {
00176 buffer_.resize((std::max<std::size_t>)(pnext + n, 1));
00177 }
00178 else
00179 {
00180 throw std::length_error("asio::streambuf too long");
00181 }
00182 }
00183
00184
00185 setg(&buffer_[0], &buffer_[0], &buffer_[0] + gend);
00186 setp(&buffer_[0] + pnext, &buffer_[0] + pnext + n);
00187 }
00188
00189 private:
00190 std::size_t max_size_;
00191 std::vector<char_type, Allocator> buffer_;
00192 };
00193
00194 }
00195
00196 #include "asio/detail/pop_options.hpp"
00197
00198 #endif // ASIO_BASIC_STREAMBUF_HPP