Buffer
cppreference std::basic_streambuf
The class basic_streambuf
controls input and output to a character sequence.
NOTE: 有两个**character sequence**:
1) controlled character sequence,buffer
2) associated character sequence,source or sink
It includes and provides access to
1) The controlled character sequence, also called the buffer, which may contain input sequence (also called get area) for buffering the input operations and/or output sequence (also called put area) for buffering the output operations.
2) The associated character sequence, also called source (for input) or sink (for output). This may be an entity that is accessed through OS API (file, TCP socket, serial port, other character device), or it may be an object (std::vector
, array, string literal), that can be interpreted as a character source or sink.
A basic_streambuf
object may support
- input (in which case the buffer described by the beginning, next, and end pointers is called get area),
- output (put area),
- input and output simultaneously.
In latter case, six pointers are tracked, which may all point to elements of the same character array or two individual arrays.
NOTE:
上面这张图基本上已经形象的描述了
basic_streambuf
的原理了。在上一章中,我们已经知道C++ IO library采用了buffering策略,对应的就是**input buffer**、output buffer。
上图展示了两个数据流向:
input/read:
如果input buffer为empty,即无数据可读、即
in_avail()
返回0、即next pointer等于egptr()
,则调用underflow()
来从**associated character sequence**中读取数据,数据的流向如下:associated character sequence ->
codecvt
-> input buffer此时input buffer为full。然后application可以调用
sgetc()
,即“The next pointer can be dereferenced and read from."output/write:
如果output buffer为full,即无空间可写、即next pointer等于
egptr()
,则调用overflow()
来将数据写入到associated character sequence中,数据的流向如下:output buffer ->
codecvt
-> associated character sequence此时output buffer为empty。如何application可以调用
sputc()
,即“The next pointer can be dereferenced and assigned to.”
If the next pointer is less than the end pointer in the put area, a write position is available. The next pointer can be dereferenced and assigned to.
If the next pointer is less than the end pointer in the get area, a read position is available. The next pointer can be dereferenced and read from.
If the next pointer is greater than the beginning pointer in a get area, a putback position is available, and the next pointer may be decremented, dereferenced, and assigned to, in order to put a character back into the get area.
The character representation and encoding in the controlled sequence may be different from the character representations in the associated sequence, in which case a std::codecvt locale facet is typically used to perform the conversion. Common examples are UTF-8 (or other multibyte) files accessed through std::wfstream objects: the controlled sequence consists of wchar_t
characters, but the associated sequence consists of bytes.
Typical implementation of the std::basic_streambuf
base class holds only the six CharT*
pointers and a copy of std::locale as data members. In addition, implementations may keep cached copies of locale facets, which are invalidated whenever imbue()
is called. The concrete buffers such as std::basic_filebuf or std::basic_stringbuf are derived from std::basic_streambuf
.
Get area | Put area | |
---|---|---|
get the pointer to the beginning of the area |
eback() |
pbase() |
get the pointer to the current character in the area |
gptr() |
pptr() |
get the pointer to the end of the area |
egptr() |
epptr() |
advances the next pointer | gbump | pbump |
repositions the pointers | setg | setp |
Get area | Put area | |
---|---|---|
sgetc | sputc | |
sgetn | sputn | |
xsgetn | xsputn |
Get area | Put area |
---|---|
underflow [virtual] | overflow [virtual] |
cppreference std::basic_stringbuf
std::basic_stringbuf
is a std::basic_streambuf whose associated character sequence is a memory-resident sequence of arbitrary characters, which can be initialized from or made available as an instance of std::basic_string.
Typical implementations of std::basic_stringbuf
hold an object of type std::basic_string or equivalent resizeable sequence container directly as a data member and use it as both the controlled character sequence (the array where the six pointers of std::basic_streambuf are pointing to) and as the associated character sequence (the source of characters for all input operations and the target for the output).
cppreference std::basic_filebuf
std::basic_filebuf
is a std::basic_streambuf whose associated character sequence is a file. Both the input sequence and the output sequence are associated with the same file, and a joint file position is maintained for both operations.
The functions underflow()
and overflow()
/sync()
perform the actual I/O between the file and the get and put areas of the buffer. When CharT
is not char, most implementations store multibyte characters in the file and a std::codecvt facet is used to perform wide/multibyte character conversion.