JSON中主要包括四种数据类型:object、value、array和string;要使用JSON功能,需要:
#include <boost/json.hpp>
using namespace boost::json;
从JSON字符串中获取键值(通过if_contains获取key对应value的指针,然后通过as_XXX获取实际值):
#include <boost/json.hpp>
auto obj = boost::json::parse(recvContent).as_object();
auto opType = obj.at("TYPE").as_string();
auto pValue = obj.if_contains("OP_STR");
if (pValue)
{
if (pValue->as_string().empty())
{
// ...
}
else
{
auto pStr = std::make_shared<std::string>(pValue->as_string().c_str());
// ...
}
}
object是JSON键值对的容器,定义在<boost/json/object.hpp>
,其主要的成员函数:
Name | Description |
---|---|
at(key) | 获取指定Key对应的元素的引用(不存在时会抛出out_of_range异常) |
begin/end | 获取iterator |
capacity | 容量 |
cbegin/cend | 获取const iterator |
clear | Erase all elements. |
contains(key) | 判断Key是否存在 |
count(key) | 返回Key的数量 |
emplace | Construct an element in-place. |
empty | 是否为空 |
erase(it/key) | 根据key或iterator移除元素 |
find(key) | 返回指定key的iterator或end()。 |
if_contains(key) | 返回key对应value的指针,或null(不存在时)。 |
insert | 插入元素 |
insert_or_assign | 插入或赋值(若key已存在) |
operator= | Copy assignment.Move assignment.Assignment. |
operator[] | 存在返回对应引用,若不存在则插入null value,并返回 |
reserve | 增加容量(若指定值小于现有容量,则什么也不做) |
size | 大小 |
swap | Swap two objects. |
max_size | 静态成员,返回object能保存元素的最大数量。 |
表示JSON值的类型,主要的成员函数:
Name | Description |
---|---|
as_array | 若为数组,则返回对应的引用(array),否则抛出异常 |
as_bool as_double as_int64 as_object as_string as_uint64 | 类型匹配时,则返回对应的引用,否则抛出异常 |
at(key) at(pos) | 数组类型根据索引(从0开始),获取值引用;其他根据值返回引用;不存在时抛出异常 |
emplace_array emplace_bool emplace_double emplace_int64 emplace_object emplace_string emplace_uint64 | 返回对应的引用,并修改value为对应类型(且赋为对应的默认值) |
emplace_null | Change the kind to null, discarding the previous contents. |
get_array get_bool get_double get_int64 get_object get_string get_uint64 | 获取对应类型的引用(不做任何检查,速度快) |
if_array if_bool if_double if_int64 if_object if_string if_uint64 | 类型匹配,返回对应的指针;否则返回nullptr |
is_array is_bool is_double is_int64 is_object is_string is_uint64 | 类型匹配,返回true |
is_null | Returns true if this is a null. |
is_primitive | Returns true if this is not an array or object. |
is_structured | Returns true if this is an array or object. |
kind | 返回值对应的底层类型 |
swap | Swap the given values. |
to_number | Return the stored number cast to an arithmetic type. |
JSON值为数组的类型,主要成员函数:
Name | Description |
---|---|
at(pos) | 获取指定索引(从0开始)处值的引用,出错抛出out_of_range异常 |
back | 获取最后一个元素 |
begin/end rbegin/rend | 获取iterator |
capacity | 获取容量 |
clear | 清空 |
data | 获取底层数组的指针 |
emplace(pos, Arg&&) | 在指定位置插入元素(构造) |
emplace_back | 在尾部插入元素 |
empty | Check if the array has no elements. |
earse | 删除元素 |
front | 返回第一个元素 |
if_contains | Return a pointer to an element, or nullptr if the index is invalid. |
insert | Insert elements before the specified location. |
operator= | Copy assignment.Move assignment.Assignment. |
operator[] | Access an element. |
pop_back | 删除最后一个元素 |
push_back | 在尾部添加元素 |
reserve | 增加容量(若指定值小于现有容量,则什么也不做) |
resize | 修改元素数量(若比原来大则填充null value,否则删除多余元素) |
shrink_to_fit | Request the removal of unused capacity. |
size | Return the number of elements in the array. |
字符串值类型,主要成员函数:
Name | Description |
---|---|
append | 追加字符(串) |
assign | 赋值 |
at | 返回指定位置字符引用 |
back | 返回最后一个字符引用 |
begin/end | 返回iterator |
c_str | Return the underlying character array directly. |
clear | Clear the contents. |
compare | Compare a string with the string. |
copy | Copy a substring to another string. |
data | Return the underlying character array directly. |
empty | Check if the string has no characters. |
ends_with | Return whether the string end with a string.Return whether the string ends with a character. |
erase | Erase characters from the string.Erase a character from the string.Erase a range from the string. |
find | Find the first occurrence of a string within the string.Find the first occurrence of a character within the string. |
find_first_not_of | Find the first occurrence of any of the characters not within the string.Find the first occurrence of a character not equal to ch . |
find_first_of | Find the first occurrence of any of the characters within the string. |
find_last_not_of | Find the last occurrence of a character not within the string.Find the last occurrence of a character not equal to ch . |
find_last_of | Find the last occurrence of any of the characters within the string. |
front | Return the first character. |
grow | Increase size without changing capacity. |
insert | 插入 |
operator string_view | Convert to a string_view referring to the string. |
operator+= | Append characters from a string.Append a character. |
operator= | Copy assignment.Move assignment.Assign a value to the string. |
operator[] | Return a character without bounds checking. |
pop_back | Remove the last character. |
push_back | Append a character. |
replace | 替换 |
reserve | Increase the capacity to at least a certain amount. |
resize | Change the size of the string. |
rfind | Find the last occurrence of a string within the string.Find the last occurrence of a character within the string. |
shrink_to_fit | Request the removal of unused capacity. |
size | Return the number of characters in the string. |
starts_with | Return whether the string begins with a string.Return whether the string begins with a character. |
subview | Return a substring. |
构造的JSON示例格式如下:
{
"a_string": "test_string",
"a_number": 123,
"a_null": null,
"a_array": [
1,
"2",
{
"123": "123"
}
],
"a_object": {
"a_name": "a_data"
},
"a_bool": true
}
构造一个JSON很简单:定义一个object,然后设定各个value即可:
boost::json::object val;
val["a_string"] = "test_string";
val["a_number"] = 123;
val["a_null"] = nullptr;
val["a_array"] = {
1, "2", boost::json::object({{"123", "123"}})
};
val["a_object"].emplace_object()["a_name"] = "a_data";
val["a_bool"] = true;
Boost.JSON支持使用std::initializer_list来构造,所以也可以这样使用:
boost::json::value val = {
{"a_string", "test_string"},
{"a_number", 123},
{"a_null", nullptr},
{"a_array", {1, "2", {{"123", "123"}}}},
{"a_object", {{"a_name", "a_data"}}},
{"a_bool", true}
};
使用initializer_list构造时,有时很难区分是数组还是对象,这是可以明确指定:
// 构造[["data", "value"]]
boost::json::value jsonAry = {boost::json::array({"data", "value"})};
// 构造{"data": "value"}
boost::json::value jsonObj = boost::json::object({{"data", "value"}});
JSON对象可以使用serialize序列化:
std::cout << boost::json::serialize(val) << std::endl;
serializer还支持部分流输出(在数据量较大时,可以有效降低内存占用):
boost::json::serializer ser;
ser.reset(&val);
char temp_buff[10];
while (!ser.done()) {
std::memset(temp_buff, 0, sizeof(char) * 10);
ser.read(temp_buff, 9);
std::cout << temp_buff << std::endl;
}
对象转换为JSON,Boost.JSON提供了一个非常简单的方法:只需要在需要序列化的类的命名空间中,定义一个重载函数tag_invoke(注意,是类所在的命名空间),然后通过value_from即可方便地序列化对象了:
namespace NSJsonTest {
class MyClass {
public:
int a;
int b;
MyClass (int a = 0, int b = 1):
a(a), b(b) {}
};
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, MyClass const &c) {
auto & jo = jv.emplace_object();
jo["a"] = c.a;
jo["b"] = c.b;
}
MyClass myObj;
auto jv = boost::json::value_from(myObj)
}
通过boost::json::parse可方便地把字符串反序列化为JSON结构。
auto decode_val = boost::json::parse("{\"123\": [1, 2, 3]}");
在非严格模式下,Boost.JSON可以选择性的对一些不那么严重的错误进行忽略:
unsigned char buf[4096];
boost::json::static_resource mr(buf);
boost::json::parse_options opt;
opt.allow_comments = true; // 允许注释
opt.allow_trailing_commas = true; // 允许尾部逗号
boost::json::parse("[1, 2, 3, ] // comment test", ec, &mr, opt);
std::cout << ec.message() << std::endl;
与对象序列化对应的是对象反序列化;也是在命名空间中定义个tag_invoke函数,然后即可通过value_to把JSON对象反序列化为类对象了:
MyClass tag_invoke(boost::json::value_to_tag<MyClass>, boost::json::value const &jv) {
auto &jo = jv.as_object();
return MyClass(jo.at("a").as_int64(), jo.at("b").as_int64());
}
// jv为前面序列化时的对象
auto myObj = boost::json::value_to<MyClass>(jv);
通过stream_parser可以流的方式读入要解析的字符串:
boost::json::stream_parser p;
p.reset();
p.write("[1, 2,");
p.write("3]");
p.finish();
std::cout << boost::json::serialize(p.release()) << std::endl;