I would like to parse a boost::beast::flat_buffer with msgpack data using nlohmann:json
Asked Answered
T

1

3

So I am using boost::beast as a WebSocket server. I would like to receive a binary message and parse it using nlohmann::json. However I get an error message:

none of the 3 overloads can convert parameter "nlohmann::detail::input_adapter"

Here is some code:

        boost::beast::flat_buffer buffer;
        ws.read(buffer);
        if (!ws.got_text()) {
            ws.text(false);
            json request = json::from_msgpack(msgpack);
            ws.write( json::to_msgpack(request) ); // echo request back
        }

If I try to static cast into a std::vector I get: E0312 / no suitable user-defined conversion

        boost::beast::flat_buffer buffer;
        ws.read(buffer);
        if (!ws.got_text()) {
            ws.text(false);
            boost::asio::mutable_buffer req = buffer.data();
            //unsigned char* req2 = static_cast<unsigned char*>(req);                     // does not work
            //std::vector<std::uint8_t> req2 = static_cast<std::vector<std::uint8_t>>(req); // does not work
            json request = json::from_msgpack(buffer.data());
            ws.write(boost::asio::buffer(json::to_msgpack(request)));
        }

How can I get the binary data out of the buffer so that nkohman::json can parse it?

Trenton answered 19/8, 2021 at 13:46 Comment(2)
Did you try json::parse((char*)req.data(), (chjar*)req.data+req.size()) ?Selfpossession
Thanks for the idea, but this gives E0413 No conversion functionTrenton
A
5

You can use the iterators-based overload:

Live On Compiler Explorer

#include <boost/asio/buffers_iterator.hpp>
#include <boost/beast.hpp>
#include <boost/beast/websocket.hpp>
#include <nlohmann/json.hpp>

int main() {
    using nlohmann::json;
    using boost::asio::ip::tcp;
    boost::asio::io_context io;
    boost::beast::websocket::stream<tcp::socket> ws(io);

    boost::beast::flat_buffer buffer;
    ws.read(buffer);
    if (!ws.got_text()) {
        ws.text(false);

        auto req     = buffer.data();
        auto request = json::from_msgpack(buffers_begin(req), buffers_end(req));

        ws.write(boost::asio::buffer(json::to_msgpack(request)));
    }
}

ADL will find the suitable overloads (boost::asio::buffers_begin e.g. in this case)

Ascocarp answered 19/8, 2021 at 15:7 Comment(1)
It compiles, you are my hero! I am testing details now!Trenton

© 2022 - 2024 — McMap. All rights reserved.