Add more documentation for asio::streambuf.
diff --git a/asio/include/asio/basic_streambuf.hpp b/asio/include/asio/basic_streambuf.hpp index 17192b0..599cb70 100644 --- a/asio/include/asio/basic_streambuf.hpp +++ b/asio/include/asio/basic_streambuf.hpp
@@ -33,6 +33,73 @@ namespace asio { /// Automatically resizable buffer class based on std::streambuf. +/** + * The @c basic_streambuf class is derived from @c std::streambuf to associate + * the streambuf's input and output sequences with one or more character + * arrays. These character arrays are internal to the @c basic_streambuf + * object, but direct access to the array elements is provided to permit them + * to be used efficiently with I/O operations. Characters written to the output + * sequence of a @c basic_streambuf object are appended to the input sequence + * of the same object. + * + * The @c basic_streambuf class's public interface is intended to permit the + * following implementation strategies: + * + * @li A single contiguous character array, which is reallocated as necessary + * to accommodate changes in the size of the character sequence. This is the + * implementation approach currently used in Asio. + * + * @li A sequence of one or more character arrays, where each array is of the + * same size. Additional character array objects are appended to the sequence + * to accommodate changes in the size of the character sequence. + * + * @li A sequence of one or more character arrays of varying sizes. Additional + * character array objects are appended to the sequence to accommodate changes + * in the size of the character sequence. + * + * The constructor for basic_streambuf accepts a @c size_t argument specifying + * the maximum of the sum of the sizes of the input sequence and output + * sequence. During the lifetime of the @c basic_streambuf object, the following + * invariant holds: + * @code size() <= max_size()@endcode + * Any member function that would, if successful, cause the invariant to be + * violated shall throw an exception of class @c std::length_error. + * + * The constructor for @c basic_streambuf takes an Allocator argument. A copy + * of this argument is used for any memory allocation performed, by the + * constructor and by all member functions, during the lifetime of each @c + * basic_streambuf object. + * + * @par Examples + * Writing directly from an streambuf to a socket: + * @code + * asio::streambuf b; + * std::ostream os(&b); + * os << "Hello, World!\n"; + * + * // try sending some data in input sequence + * size_t n = sock.send(b.data()); + * + * b.consume(n); // sent data is removed from input sequence + * @endcode + * + * Reading from a socket directly into a streambuf: + * @code + * asio::streambuf b; + * + * // reserve 512 bytes in output sequence + * asio::streambuf::const_buffers_type bufs = b.prepare(512); + * + * size_t n = sock.receive(bufs); + * + * // received data is "committed" from output sequence to input sequence + * b.commit(n); + * + * std::istream is(&b); + * std::string s; + * is >> s; + * @endcode + */ template <typename Allocator = std::allocator<char> > class basic_streambuf : public std::streambuf, @@ -40,17 +107,21 @@ { public: #if defined(GENERATING_DOCUMENTATION) - /// The type used to represent the get area as a list of buffers. + /// The type used to represent the input sequence as a list of buffers. typedef implementation_defined const_buffers_type; - /// The type used to represent the put area as a list of buffers. + /// The type used to represent the output sequence as a list of buffers. typedef implementation_defined mutable_buffers_type; #else typedef asio::const_buffers_1 const_buffers_type; typedef asio::mutable_buffers_1 mutable_buffers_type; #endif - /// Construct a buffer with a specified maximum size. + /// Construct a basic_streambuf object. + /** + * Constructs a streambuf with the specified maximum size. The initial size + * of the streambuf's input sequence is 0. + */ explicit basic_streambuf( std::size_t max_size = (std::numeric_limits<std::size_t>::max)(), const Allocator& allocator = Allocator()) @@ -63,34 +134,86 @@ setp(&buffer_[0], &buffer_[0] + pend); } - /// Return the size of the get area in characters. + /// Get the size of the input sequence. + /** + * @returns The size of the input sequence. The value is equal to that + * calculated for @c s in the following code: + * @code + * size_t s = 0; + * const_buffers_type bufs = data(); + * const_buffers_type::const_iterator i = bufs.begin(); + * while (i != bufs.end()) + * { + * const_buffer buf(*i++); + * s += buffer_size(buf); + * } + * @endcode + */ std::size_t size() const { return pptr() - gptr(); } - /// Return the maximum size of the buffer. + /// Get the maximum size of the basic_streambuf. + /** + * @returns The allowed maximum of the sum of the sizes of the input sequence + * and output sequence. + */ std::size_t max_size() const { return max_size_; } - /// Get a list of buffers that represents the get area. + /// Get a list of buffers that represents the input sequence. + /** + * @returns An object of type @c const_buffers_type that satisfies + * ConstBufferSequence requirements, representing all character arrays in the + * input sequence. + * + * @note The returned object is invalidated by any @c basic_streambuf member + * function that modifies the input sequence or output sequence. + */ const_buffers_type data() const { return asio::buffer(asio::const_buffer(gptr(), (pptr() - gptr()) * sizeof(char_type))); } - /// Get a list of buffers that represents the put area, with the given size. - mutable_buffers_type prepare(std::size_t size) + /// Get a list of buffers that represents the output sequence, with the given + /// size. + /** + * Ensures that the output sequence can accommodate @c n characters, + * reallocating character array objects as necessary. + * + * @returns An object of type @c mutable_buffers_type that satisfies + * MutableBufferSequence requirements, representing character array objects + * at the start of the output sequence such that the sum of the buffer sizes + * is @c n. + * + * @throws std::length_error If <tt>size() + n > max_size()</tt>. + * + * @note The returned object is invalidated by any @c basic_streambuf member + * function that modifies the input sequence or output sequence. + */ + mutable_buffers_type prepare(std::size_t n) { - reserve(size); + reserve(n); return asio::buffer(asio::mutable_buffer( - pptr(), size * sizeof(char_type))); + pptr(), n * sizeof(char_type))); } - /// Move the start of the put area by the specified number of characters. + /// Move characters from the output sequence to the input sequence. + /** + * Appends @c n characters from the start of the output sequence to the input + * sequence. The beginning of the output sequence is advanced by @c n + * characters. + * + * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and + * no intervening operations that modify the input or output sequence. + * + * @throws std::length_error If @c n is greater than the size of the output + * sequence. + */ void commit(std::size_t n) { if (pptr() + n > epptr()) @@ -99,7 +222,12 @@ setg(eback(), gptr(), pptr()); } - /// Move the start of the get area by the specified number of characters. + /// Remove characters from the input sequence. + /** + * Removes @c n characters from the beginning of the input sequence. + * + * @throws std::length_error If <tt>n > size()</tt>. + */ void consume(std::size_t n) { if (gptr() + n > pptr()) @@ -110,6 +238,10 @@ protected: enum { buffer_delta = 128 }; + /// Override std::streambuf behaviour. + /** + * Behaves according to the specification of @c std::streambuf::underflow(). + */ int_type underflow() { if (gptr() < pptr()) @@ -123,6 +255,13 @@ } } + /// Override std::streambuf behaviour. + /** + * Behaves according to the specification of @c std::streambuf::overflow(), + * with the specialisation that @c std::length_error is thrown if appending + * the character to the input sequence would require the condition + * <tt>size() > max_size()</tt> to be true. + */ int_type overflow(int_type c) { if (!traits_type::eq_int_type(c, traits_type::eof()))