buffers.qbk
来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 163 行
QBK
163 行
[/ / Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) / / Distributed under the Boost Software License, Version 1.0. (See accompanying / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) /][section:buffers Buffers]Fundamentally, I/O involves the transfer of data to and from contiguous regionsof memory, called buffers. These buffers can be simply expressed as a tupleconsisting of a pointer and a size in bytes. However, to allow the developmentof efficient network applications, Boost.Asio includes support for scatter-gatheroperations. These operations involve one or more buffers:* A scatter-read receives data into multiple buffers.* A gather-write transmits multiple buffers.Therefore we require an abstraction to represent a collection of buffers. Theapproach used in Boost.Asio is to define a type (actually two types) torepresent a single buffer. These can be stored in a container, which may bepassed to the scatter-gather operations.In addition to specifying buffers as a pointer and size in bytes, Boost.Asio makes adistinction between modifiable memory (called mutable) and non-modifiablememory (where the latter is created from the storage for a const-qualifiedvariable). These two types could therefore be defined as follows: typedef std::pair<void*, std::size_t> mutable_buffer; typedef std::pair<const void*, std::size_t> const_buffer;Here, a mutable_buffer would be convertible to a const_buffer, but conversionin the opposite direction is not valid.However, Boost.Asio does not use the above definitions as-is, but instead defines twoclasses: `mutable_buffer` and `const_buffer`. The goal of these is to providean opaque representation of contiguous memory, where:* Types behave as std::pair would in conversions. That is, a `mutable_buffer` is convertible to a `const_buffer`, but the opposite conversion is disallowed.* There is protection against buffer overruns. Given a buffer instance, a user can only create another buffer representing the same range of memory or a sub-range of it. To provide further safety, the library also includes mechanisms for automatically determining the size of a buffer from an array, `boost::array` or `std::vector` of POD elements, or from a `std::string`.* Type safety violations must be explicitly requested using the `buffer_cast` function. In general an application should never need to do this, but it is required by the library implementation to pass the raw memory to the underlying operating system functions.Finally, multiple buffers can be passed to scatter-gather operations (such as[link boost_asio.reference.read read()] or [link boost_asio.reference.write write()]) byputting the buffer objects into a container. The `MutableBufferSequence` and`ConstBufferSequence` concepts have been defined so that containers such as`std::vector`, `std::list`, `std::vector` or `boost::array` can be used.[heading Streambuf for Integration with Iostreams]The class `boost::asio::basic_streambuf` is derived from `std::basic_streambuf` toassociate the input sequence and output sequence with one or more objects ofsome character array type, whose elements store arbitrary values. Thesecharacter array objects are internal to the streambuf object, but direct accessto the array elements is provided to permit them to be used with I/Ooperations, such as the send or receive operations of a socket:* The input sequence of the streambuf is accessible via the [link boost_asio.reference.basic_streambuf.data data()] member function. The return type of this function meets the `ConstBufferSequence` requirements.* The output sequence of the streambuf is accessible via the [link boost_asio.reference.basic_streambuf.data prepare()] member function. The return type of this function meets the `MutableBufferSequence` requirements.* Data is transferred from the front of the output sequence to the back of the input sequence by calling the [link boost_asio.reference.basic_streambuf.commit commit()] member function.* Data is removed from the front of the input sequence by calling the [link boost_asio.reference.basic_streambuf.consume consume()] member function.The streambuf constructor accepts a `size_t` argument specifying the maximum ofthe sum of the sizes of the input sequence and output sequence. Any operationthat would, if successful, grow the internal data beyond this limit will throwa `std::length_error` exception.[heading Bytewise Traversal of Buffer Sequences]The `buffers_iterator<>` class template allows buffer sequences (i.e. typesmeeting `MutableBufferSequence` or `ConstBufferSequence` requirements) to betraversed as though they were a contiguous sequence of bytes. Helper functionscalled buffers_begin() and buffers_end() are also provided, where thebuffers_iterator<> template parameter is automatically deduced.As an example, to read a single line from a socket and into a `std::string`,you may write: boost::asio::streambuf sb; ... std::size_t n = boost::asio::read_until(sock, sb, '\n'); boost::asio::streambuf::const_buffers_type bufs = sb.data(); std::string line( boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + n);[heading Buffer Debugging]Some standard library implementations, such as the one that ships withMicrosoft Visual C++ 8.0 and later, provide a feature called iteratordebugging. What this means is that the validity of iterators is checked atruntime. If a program tries to use an iterator that has been invalidated, anassertion will be triggered. For example: std::vector<int> v(1) std::vector<int>::iterator i = v.begin(); v.clear(); // invalidates iterators *i = 0; // assertion!Boost.Asio takes advantage of this feature to add buffer debugging. Consider thefollowing code: void dont_do_this() { std::string msg = "Hello, world!"; boost::asio::async_write(sock, boost::asio::buffer(msg), my_handler); }When you call an asynchronous read or write you need to ensure that the buffersfor the operation are valid until the completion handler is called. In theabove example, the buffer is the `std::string` variable `msg`. This variable ison the stack, and so it goes out of scope before the asynchronous operationcompletes. If you're lucky then the application will crash, but random failuresare more likely.When buffer debugging is enabled, Boost.Asio stores an iterator into the string untilthe asynchronous operation completes, and then dereferences it to check itsvalidity. In the above example you would observe an assertion failure justbefore Boost.Asio tries to call the completion handler.This feature is automatically made available for Microsoft Visual Studio 8.0 orlater and for GCC when `_GLIBCXX_DEBUG` is defined. There is a performance costto this checking, so buffer debugging is only enabled in debug builds. Forother compilers it may be enabled by defining `BOOST_ASIO_ENABLE_BUFFER_DEBUGGING`.It can also be explicitly disabled by defining `BOOST_ASIO_DISABLE_BUFFER_DEBUGGING`.[heading See Also][link boost_asio.reference.buffer buffer],[link boost_asio.reference.buffers_begin buffers_begin],[link boost_asio.reference.buffers_end buffers_end],[link boost_asio.reference.buffers_iterator buffers_iterator],[link boost_asio.reference.const_buffer const_buffer],[link boost_asio.reference.const_buffers_1 const_buffers_1],[link boost_asio.reference.mutable_buffer mutable_buffer],[link boost_asio.reference.mutable_buffers_1 mutable_buffers_1],[link boost_asio.reference.streambuf streambuf],[link boost_asio.reference.ConstBufferSequence ConstBufferSequence],[link boost_asio.reference.MutableBufferSequence MutableBufferSequence],[link boost_asio.examples.buffers buffers example].[endsect]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?