boost streambuf потребляет и фиксирует, что это
Кажется, я не могу найти хорошее объяснение того, что на самом деле означают, что значит require() и commit (), на самом деле я вообще не понимаю streambuf.
Насколько я понимаю, streambuf - это просто массив символов. Но почему это в документации,
basic_streambuf::data
Get a list of buffers that represents the input sequence.
так на самом деле там много буферов? И что такое "входная последовательность" и "выходная последовательность"? Это еще два буфера?
Что на самом деле делает следующий код?
streambuf b;
size_t size;
size = read( socket, b.prepare( 1024 ) );
b.commit( size );
size = write( socket, b.data() );
b.consume( size );
когда я вызываю b.prepare(), выделяет ли он новый буфер для read () для помещения данных? Тогда когда данные передаются из этого буфера в основной буфер streambuf? Я думал, что это было совершить (), но
basic_streambuf::commit
Move characters from the output sequence to the input sequence.
так что кажется, что commit фактически перемещает данные из "выходной последовательности" в "входную последовательность", даже не упоминая базовый буфер, используемый для хранения данных!
1 ответ
Boost ASIO streambuf - это больше, чем просто массив символов. Из документации basic_streambuf:
Класс basic_streambuf является производным от std::streambuf для связи входных и выходных последовательностей streambuf с одним или несколькими символьными массивами. Эти символьные массивы являются внутренними по отношению к объекту basic_streambuf, но прямой доступ к элементам массива предоставляется, чтобы позволить им эффективно использоваться с операциями ввода-вывода. Символы, записанные в выходную последовательность объекта basic_streambuf, добавляются к входной последовательности того же объекта.
Документация продолжает говорить о возможных стратегиях реализации. Объект streambuf может просто использовать один непрерывный массив символов с указателями для управления последовательностями ввода и вывода. Но интерфейс допускает более сложные схемы.
Вы спросили, что на самом деле делает фрагмент кода, но это зависит от базовой реализации. Короче говоря, prepare() гарантирует, что базовый буфер достаточно большой, чтобы вместить то, что вы пытаетесь в него поместить. Это также дает вам доступ к буферу через объект mutuable_buffers. После записи данных в потоковый буфер (предположительно, когда вызывается обработчик чтения), commit() делает эти данные доступными для входной последовательности. Вы можете получить доступ к этим байтам, используя data(). После того, как вы закончили работу с данными в буфере (потому что вы скопировали, обработали или что-то еще), require () удаляет данные из входной последовательности. Последующий вызов data () не будет содержать байты предыдущего вызова.
Вы также утверждали, что основной буфер, используемый для хранения данных, никогда не упоминается, и это правильно. Авторам ASIO решать, как хранить фактические данные.