Чтение буфера из json с помощью boost

#c #json #boost #grpc #asio

Вопрос:

У меня есть следующая строка json:

 {"message":
{"type":"Buffer",
"data":[0,0,0,193,0,41,10,190,1,34,128,0,0,1,38,0,0,1,232,41,40,202,35,104,81,66,0,162,194,173,0,254,67,116,38,60,235,70,250,195,139,141,184,47,167,240,210,207,118,184,140,225,82,52,30,35,111,80,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,33,2,155,92,51,188,68,15,123,37,47,245,59,120,114,102,60,233,15,212,39,112,165,190,210,14,188,25,156,234,124,154,181,101,118,71,48,69,2,33,0,242,181,45,125,208,73,206,26,86,183,220,28,159,36,149,124,208,72,187,118,116,44,224,252,192,173,242,248,112,181,63,49,2,32,84,83,33,39,113,80,183,50,225,212,133,84,226,26,173,185,65,216,237,234,90,20,215,136,184,246,229,230,13,227,69,42]},
"validator_key":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVcn"}
 

Мне нужно прочитать поле message.data, представляющее собой буфер, поступающий из node.js процесс через gRPC. Я попробовал что-то вроде этого:

         std::stringstream ss;
        boost::property_tree::ptree pt;
        ss << gossip.message();

        boost::property_tree::read_json(ss, pt);
        auto message_received = pt.get<std::string>("message.data");

        std::cout << "Message received pure: " << gossip.message() << std::endl;
        std::cout << "Message received, json: " << message_received << std::endl;
 

gossip.message () — это моя строка json, полученная через gRPC. В результате получается следующее:

 Message received pure: {"message":{"type":"Buffer","data":[0,0,0,193,0,41,10,190,1,34,128,0,0,1,38,0,0,1,232,41,40,202,35,104,81,66,0,162,194,173,0,254,67,116,38,60,235,70,250,195,139,141,184,47,167,240,210,207,118,184,140,225,82,52,30,35,111,80,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,33,2,155,92,51,188,68,15,123,37,47,245,59,120,114,102,60,233,15,212,39,112,165,190,210,14,188,25,156,234,124,154,181,101,118,71,48,69,2,33,0,242,181,45,125,208,73,206,26,86,183,220,28,159,36,149,124,208,72,187,118,116,44,224,252,192,173,242,248,112,181,63,49,2,32,84,83,33,39,113,80,183,50,225,212,133,84,226,26,173,185,65,216,237,234,90,20,215,136,184,246,229,230,13,227,69,42]},"validator_key":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVcn"}
Message received, json: 
 

Как я могу прочитать это поле и поместить его в строку std::или буфер asio?

Ответ №1:

Две проблемы:

  • Сообщение.данные-это не строка. Это массив целых чисел.
  • Дерево свойств Boost не является библиотекой JSON.

Предполагая, что вы ожидаете, что «строка» будет состоять из байтов, которые представлены в виде их целых значений без знака в массиве.

Одно исправление, один обходной путь:

Исправление

Используйте библиотеку JSON, например Boost JSON:

Жить В Проводнике Компилятора

 #include <boost/json.hpp>
#include <boost/json/src.hpp>
#include <iostream>

struct Gossip { std::string message(); } gossip;

int main()
{
    namespace json = boost::json;
    auto doc = json::parse(gossip.message()).as_object();

    autoamp; arr   = doc["message"].as_object()["data"];
    auto  bytes = json::value_to<std::vector<uint8_t>>(arr);
    std::string text(bytes.begin(), bytes.end());

    //std::cout << "message(): " << gossip.message() << "n";
    std::cout << "doc:       " << doc              << "n";
    std::cout << "arr:       " << arr              << "n";
    std::cout << "bytes:     ";

    for (int val : bytes)
        std::cout << " " << val;

    std::cout << "ntext: " << std::quoted(text) << "n";
}

std::string Gossip::message() {
    return R"({
    "message": {
        "type": "Buffer",
        "data": [0, 0, 0, 193, 0, 41, 10, 190, 1, 34, 128, 0, 0, 1, 38, 0, 0, 1, 232, 41, 40, 202, 35, 104, 81, 66, 0, 162, 194, 173, 0, 254, 67, 116, 38, 60, 235, 70, 250, 195, 139, 141, 184, 47, 167, 240, 210, 207, 118, 184, 140, 225, 82, 52, 30, 35, 111, 80, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 33, 2, 155, 92, 51, 188, 68, 15, 123, 37, 47, 245, 59, 120, 114, 102, 60, 233, 15, 212, 39, 112, 165, 190, 210, 14, 188, 25, 156, 234, 124, 154, 181, 101, 118, 71, 48, 69, 2, 33, 0, 242, 181, 45, 125, 208, 73, 206, 26, 86, 183, 220, 28, 159, 36, 149, 124, 208, 72, 187, 118, 116, 44, 224, 252, 192, 173, 242, 248, 112, 181, 63, 49, 2, 32, 84, 83, 33, 39, 113, 80, 183, 50, 225, 212, 133, 84, 226, 26, 173, 185, 65, 216, 237, 234, 90, 20, 215, 136, 184, 246, 229, 230, 13, 227, 69, 42]
    },
    "validator_key": "n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVcn"
})";
}
 

Обходной Путь С Деревом Свойств Boost

 std::string message_received;

for (autoamp; [k, v] : pt.get_child("message.data")) {
    message_received  = static_cast<char>(v.get_value<unsigned short>());
}
 

Полученные данные не похожи ни на одну (известную мне) текстовую кодировку, но это, вероятно, не относится к делу.

Жить В Проводнике Компилятора

 #include <boost/property_tree/json_parser.hpp>
#include <iostream>

struct Gossip { std::string message(); } gossip;

int main()
{
    boost::property_tree::ptree pt;

    {
        std::stringstream ss(gossip.message());
        boost::property_tree::read_json(ss, pt);
    }

    std::string message_received;
    for (autoamp; [k, v] : pt.get_child("message.data")) {
        message_received  = static_cast<char>(v.get_value<unsigned short>());
    }

    std::cout << "Message received pure: " << gossip.message() << std::endl;
    std::cout << "Message received, json: " << message_received << std::endl;
}

std::string Gossip::message() {
    return R"({
    "message": {
        "type": "Buffer",
        "data": [0, 0, 0, 193, 0, 41, 10, 190, 1, 34, 128, 0, 0, 1, 38, 0, 0, 1, 232, 41, 40, 202, 35, 104, 81, 66, 0, 162, 194, 173, 0, 254, 67, 116, 38, 60, 235, 70, 250, 195, 139, 141, 184, 47, 167, 240, 210, 207, 118, 184, 140, 225, 82, 52, 30, 35, 111, 80, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 33, 2, 155, 92, 51, 188, 68, 15, 123, 37, 47, 245, 59, 120, 114, 102, 60, 233, 15, 212, 39, 112, 165, 190, 210, 14, 188, 25, 156, 234, 124, 154, 181, 101, 118, 71, 48, 69, 2, 33, 0, 242, 181, 45, 125, 208, 73, 206, 26, 86, 183, 220, 28, 159, 36, 149, 124, 208, 72, 187, 118, 116, 44, 224, 252, 192, 173, 242, 248, 112, 181, 63, 49, 2, 32, 84, 83, 33, 39, 113, 80, 183, 50, 225, 212, 133, 84, 226, 26, 173, 185, 65, 216, 237, 234, 90, 20, 215, 136, 184, 246, 229, 230, 13, 227, 69, 42]
    },
    "validator_key": "n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVcn"
})";
}