0

我正在使用 nlohmann::json 库在 C++ 中序列化 JSON 对象,我的用例涉及读取 c# 中的 cbor 字节字符串输出。我注意到,当使用 nlohmann::json 库将 json 对象转储到 C++ 中的字符串时,json 字符串值(即 case value_t::string)被转义(调用了 escape_string),没有这样的调用当 json 值是 CBOR 方法中的字符串值时生成。

我正在阅读 CBOR CRF 7049,似乎在序列化为 CBOR 时不需要转义字符串。nlohmann::json 库中的行为是一致的:字符串在序列化时不转义,反序列化时也不例外。但似乎 Newtonsoft.Json(C# 库)期望这一点。这是一个有效的期望吗?或者我在这个过程中做错了什么?

C++ 方面:

nlohmann::json json_doc;
json_doc["characters"] = nlohmann::json::array();

for (int i = 0; i < characters.size(); i++) {
    json_doc["characters"][i]["name"] = (characters[i] != nullptr) ? characters[i]->name() : "";
}

std::vector<uint8_t> cbor = nlohmann::json::to_cbor(json_doc);
output->assign((char*)&cbor[0], cbor.size());

C# 方面。cbor_bytes 是 cbor 字节字符串(C++ 输出向量)

CBORObject cbor = CBORObject.DecodeFromBytes(cbor_bytes);
output = cbor.ToString();

到那时,这样的输出字符串格式错误:

{"characters": [{"name": "Clara Oswald"}, {"name": "Kensi Blye"}, {"name": "Temperance "Bones" Brennan"}]}

并且显然不能被解析:

JObject output_obj = JObject.Parse(output);
4

1 回答 1

2

CBOR(简明二进制对象表示)不是JSON(JavaScript 对象表示法)。虽然 CBOR 可能借鉴了 JSON 的一些概念,但它显然是一种不同的格式,具有不同的规则和目标。CBOR 是二进制格式;JSON 是文本。在 CBOR 中,字符串具有长度前缀,而在 JSON 中则没有。此外,CBOR 不允许元素之间有任意空格(对于二进制格式没有意义),而 JSON 允许(对于人类可读性)。最终,CBOR 不需要转义字符串的机制,因为它不需要分隔符来判断字符串的开始和结束位置。另一方面,JSON 需要双引号来标记每个字符串的开头和结尾。因此,字符串中的引号和控制字符必须在 JSON 中使用反斜杠以及文字反斜杠本身进行转义。如果您想确保 JSON 可解析,则无法绕过此规则。

在上面的代码中,您正在使用该CBORObject.ToString()方法将对象转换为字符串。如果这CBORObject是来自第三方库,文档是否说明ToString()会生成有效的 JSON?如果是这样,那么它肯定有一个错误;它应该按照 JSON 规范的要求进行正确的转义。如果没有这样的有效 JSON 承诺,那么你就不能指望 Json.Net 能够解析字符串,即使它看起来有点像 JSON。(您可能会检查是否CBORObject有其他专门的方法ToJson()来执行此转换。)如果CBORObject是您自己的代码,那么在从 CBOR 转换为 JSON 时正确转义字符串是您的责任。

于 2017-06-28T21:41:12.973 回答