c++bufferboost-asiostrncpy

Combine multiple boost::asio::const_buffer into a single buffer


My program receives data in the form of std::vector<boost::asio::const_buffer> buf_vect. I need to combine the const_buffer in the vector into a single buffer which will then be converted to a std::string for further processing.

First attempt:

size_t total_size = 0;
for (auto e : buf_vect) {
    total_size += e.size();
}
char* char_buf = new char[total_size];

for (auto e : buf_vect) {
    strncpy(char_buf, static_cast<const char*>(e.data()), e.size());
}
std::string data(char_buf, total_size);
delete char_buf;

// process data string

This attempt yields nonsense in the data string. Is this the correct approach or am I totally misunderstanding the behavior of buffers...?


Solution

  • std::vector<boost::asio::const_buffer> buf_vect

    That satisfies the criteria for a ConstBufferSequence

    [I need to combine the const_buffer in the vector into a single buffer which will then be converted to] a std::string [for further processing]

    Let's skip the middle man?

    std::string const for_further_processing(asio::buffers_begin(buf_vect),
                                             asio::buffers_end(buf_vect));
    

    Live Demo

    #include <boost/asio.hpp>
    #include <iomanip>
    #include <iostream>
    #include <string>
    
    namespace asio = boost::asio;
    
    int main() {
        float f[]{42057036,      1.9603e-19, 1.9348831e-19,
                  1.7440063e+28, 10268.8545, 10.027938,
                  2.7560551e+12, 10265.352,  9.592293e-39};
        int  ints[]{1819043144, 1867980911, 174353522}; // "Hello World\n"
        char arr[]{" aaaaaa bbbbb ccccc ddddd "};
        std::string_view msg{"Earth To Mars Do You Read\n"};
    
        std::vector<asio::const_buffer> buf_vect{
            asio::buffer(ints),
            asio::buffer(arr),
            asio::buffer(msg),
            asio::buffer(f),
        };
    
        std::string const for_further_processing(asio::buffers_begin(buf_vect),
                                                 asio::buffers_end(buf_vect));
    
        std::cout << std::quoted(for_further_processing) << "\n";
    }
    

    Prints

    "Hello World
     aaaaaa bbbbb ccccc ddddd Earth To Mars Do You Read
    So Long And Thanks For All The Fish"