3

I have found many examples showing how to copy the contents of a boost::beast::multi_buffer to a string, but how do I assign the contents of a string to a multi_buffer that has previously been created in a class instance?

If I have the example declarations in my class:

private:
    boost::beast::websocket::stream<boost::asio::ip::tcp::socket> ws_;
    boost::asio::strand<boost::asio::io_context::executor_type> strand_;
    boost::beast::multi_buffer buffer_;

how do I assign a string to buffer_ before using it in a call to:

ws_.async_write(buffer_.data(), boost::asio::bind_executor(strand_,
    std::bind(&CNXG_session::on_write,
            shared_from_this(),
            std::placeholders::_1,
            std::placeholders::_2)));
user1139053
  • 131
  • 3
  • 10

2 Answers2

14

You can also use the boost::beast::ostream function to turn a DynamicBuffer into a std::ostream you can write to:

boost::beast::multi_buffer b;
boost::beast::ostream(b) << "Hello, world!\n";
Vinnie Falco
  • 5,173
  • 28
  • 43
4

You can use boost::asio::buffer_copy after prepare:

size_t n = buffer_copy(b.prepare(contents.size()), boost::asio::buffer(contents));

Demo

Live On Coliru

#include <iostream>
#include <boost/asio/buffers_iterator.hpp>
#include <boost/beast.hpp>

using boost::beast::multi_buffer;

void dump_buffer(std::ostream& os, multi_buffer const& mb) {
    os << mb.size() << " (" << mb.capacity() << ") "
       << "'" << boost::beast::buffers(mb.data()) << "'\n";
}

int main() {
    boost::beast::multi_buffer b;
    dump_buffer(std::cout << "before: ", b);

    std::string const contents = "Hello world";

    size_t n = buffer_copy(b.prepare(contents.size()), boost::asio::buffer(contents));
    b.commit(n);

    dump_buffer(std::cout << "after: ", b);
}

Prints

before: 0 (0) ''
after: 11 (512) 'Hello world'

Note: perhaps you'll be interested in a new buffer facility in Boost asio 1.66.0: dynamic_buffer (Dynamically sized boost::asio::buffer)

sehe
  • 374,641
  • 47
  • 450
  • 633