Reading YAML and JSON Strings¶
Parsing text with Node::parse()¶
Node::parse() parses YAML and JSON strings into a Node tree.
std::string yaml_txt("mykey: 42.0");
Node n;
n.parse(yaml_txt,"yaml");
std::cout << n["mykey"].as_float64() <<std::endl;
n.print_detailed();
42
{
"mykey":
{
"dtype":"float64",
"number_of_elements": 1,
"offset": 0,
"stride": 8,
"element_bytes": 8,
"endianness": "little",
"value": 42.0
}
}
std::string json_txt("{\"mykey\": 42.0}");
Node n;
n.parse(json_txt,"json");
std::cout << n["mykey"].as_float64() <<std::endl;
n.print_detailed();
42
{
"mykey":
{
"dtype":"float64",
"number_of_elements": 1,
"offset": 0,
"stride": 8,
"element_bytes": 8,
"endianness": "little",
"value": 42.0
}
}
The first argument is the string to parse and the second argument selects the protocol to use when parsing.
Valid Protocols: json, conduit_json, conduit_base64_json, yaml.
jsonandyamlprotocols parse pure JSON or YAML strings. For leaf nodes wide types such as int64, uint64, and float64 are inferred.
Homogeneous numeric lists are parsed as Conduit arrays.
std::string yaml_txt("myarray: [0.0, 10.0, 20.0, 30.0]");
Node n;
n.parse(yaml_txt,"yaml");
n["myarray"].print();
n.print_detailed();
[0.0, 10.0, 20.0, 30.0]
{
"myarray":
{
"dtype":"float64",
"number_of_elements": 4,
"offset": 0,
"stride": 8,
"element_bytes": 8,
"endianness": "little",
"value": [0.0, 10.0, 20.0, 30.0]
}
}
conduit_jsonparses JSON with conduit data type information, allowing you to specify bitwidth style types, strides, etc.conduit_base64_jsoncombines the conduit_json protocol with an embedded base64-encoded data block
Generators¶
Using Generator instances¶
Node::parse() is sufficient for most use cases, but you can also use a Generator instance to parse JSON and YAML. Additionally, Generators can parse a conduit JSON schema and bind it to in-core data.
Generator g("{test: {dtype: float64, value: 100.0}}","conduit_json");
Node n;
g.walk(n);
std::cout << n["test"].as_float64() <<std::endl;
n.print();
n.print_detailed();
100
test: 100.0
{
"test":
{
"dtype":"float64",
"number_of_elements": 1,
"offset": 0,
"stride": 8,
"element_bytes": 8,
"endianness": "little",
"value": 100.0
}
}
Like Node::parse(), Generators can also parse pure JSON or YAML. For leaf nodes: wide types such as int64, uint64, and float64 are inferred.
Generator g("{test: 100.0}","json");
Node n;
g.walk(n);
std::cout << n["test"].as_float64() <<std::endl;
n.print_detailed();
n.print();
100
{
"test":
{
"dtype":"float64",
"number_of_elements": 1,
"offset": 0,
"stride": 8,
"element_bytes": 8,
"endianness": "little",
"value": 100.0
}
}
test: 100.0
Generator g("test: 100.0","yaml");
Node n;
g.walk(n);
std::cout << n["test"].as_float64() <<std::endl;
n.print_detailed();
n.print();
100
{
"test":
{
"dtype":"float64",
"number_of_elements": 1,
"offset": 0,
"stride": 8,
"element_bytes": 8,
"endianness": "little",
"value": 100.0
}
}
test: 100.0
Schemas can be bound to in-core data.
float64 vals[2];
Generator g("{a: {dtype: float64, value: 100.0}, b: {dtype: float64, value: 200.0} }",
"conduit_json",
vals);
Node n;
g.walk_external(n);
std::cout << n["a"].as_float64() << " vs " << vals[0] << std::endl;
std::cout << n["b"].as_float64() << " vs " << vals[1] << std::endl;
n.print();
Node ninfo;
n.info(ninfo);
ninfo.print();
100 vs 100
200 vs 200
a: 100.0
b: 200.0
mem_spaces:
0x7ffee7d56140:
path: "a"
type: "external"
total_bytes_allocated: 0
total_bytes_mmaped: 0
total_bytes_compact: 16
total_strided_bytes: 16
Compacting Nodes¶
Nodes can be compacted to transform sparse data.
float64 vals[] = { 100.0,-100.0,
200.0,-200.0,
300.0,-300.0,
400.0,-400.0,
500.0,-500.0};
// stride though the data with two different views.
Generator g1("{dtype: float64, length: 5, stride: 16}",
"conduit_json",
vals);
Generator g2("{dtype: float64, length: 5, stride: 16, offset:8}",
"conduit_json",
vals);
Node n1;
g1.walk_external(n1);
n1.print();
Node n2;
g2.walk_external(n2);
n2.print();
// look at the memory space info for our two views
Node ninfo;
n1.info(ninfo);
ninfo.print();
n2.info(ninfo);
ninfo.print();
// compact data from n1 to a new node
Node n1c;
n1.compact_to(n1c);
// look at the resulting compact data
n1c.print();
n1c.schema().print();
n1c.info(ninfo);
ninfo.print();
// compact data from n2 to a new node
Node n2c;
n2.compact_to(n2c);
// look at the resulting compact data
n2c.print();
n2c.info(ninfo);
ninfo.print();
[100.0, 200.0, 300.0, 400.0, 500.0]
[-100.0, -200.0, -300.0, -400.0, -500.0]
mem_spaces:
0x7ffee7d56100:
path: ""
type: "external"
total_bytes_allocated: 0
total_bytes_mmaped: 0
total_bytes_compact: 40
total_strided_bytes: 72
mem_spaces:
0x7ffee7d56100:
path: ""
type: "external"
total_bytes_allocated: 0
total_bytes_mmaped: 0
total_bytes_compact: 40
total_strided_bytes: 72
[100.0, 200.0, 300.0, 400.0, 500.0]
{"dtype":"float64","number_of_elements": 5,"offset": 0,"stride": 8,"element_bytes": 8,"endianness": "little"}
mem_spaces:
0x7fefae904610:
path: ""
type: "allocated"
bytes: 40
allocator_id: 0
total_bytes_allocated: 40
total_bytes_mmaped: 0
total_bytes_compact: 40
total_strided_bytes: 40
[-100.0, -200.0, -300.0, -400.0, -500.0]
mem_spaces:
0x7fefae904640:
path: ""
type: "allocated"
bytes: 40
allocator_id: 0
total_bytes_allocated: 40
total_bytes_mmaped: 0
total_bytes_compact: 40
total_strided_bytes: 40