使用 boost 从 json 读取缓冲区
Reading a buffer from a json using boost
我有以下 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":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"}
我需要读取字段 message.data,这是一个通过 gRPC 来自 node.js 进程的缓冲区。我试过这样的事情:
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":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"}
Message received, json:
如何读取该字段并将其放入 std::string 或 asio 缓冲区?
两个问题:
message.data 不是字符串。这是一个整数数组。
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();
auto& 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": "n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"
})";
}
使用 Boost 属性 树
的解决方法
std::string message_received;
for (auto& [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 (auto& [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": "n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"
})";
}
我有以下 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":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"}
我需要读取字段 message.data,这是一个通过 gRPC 来自 node.js 进程的缓冲区。我试过这样的事情:
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":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"}
Message received, json:
如何读取该字段并将其放入 std::string 或 asio 缓冲区?
两个问题:
message.data 不是字符串。这是一个整数数组。
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();
auto& 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": "n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"
})";
}
使用 Boost 属性 树
的解决方法std::string message_received;
for (auto& [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 (auto& [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": "n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"
})";
}