4f5fa7bfbf
All of the AddValue methods (AddValue, push_front, push_back) have two overloads: - `(..., T const& data)` - `(..., JsonType type, unsigned cbData = 0, void const* pbData = NULL)` For the second overload, the default values are convenient. They provide a convenient syntax for adding the no-data values like null, array, and object, e.g. `builder.push_back(parent, name, JsonNull)`. However, these defaults are ambiguous and a bit dangerous: - `builder.push_back(parent, name, something)` could be a call to the first overload or it could be a call to the second overload with defaulted `0, NULL` parameters. - `builder.push_back(parent, name, type, 43)` compiles without warning and silently leaves the value uninitialized. The uninitialized case is useful but rare and should only happen with explicit NULL, not by default. Fix is to remove the defaults: - `(..., T const& data)` - `(..., JsonType type, unsigned cbData, void const* pbData)` However, this breaks the `builder.push_back(parent, name, JsonNull)` syntax. Restore that syntax by adding `JsonType` to the list of valid types accepted by the first overload. Now there is no ambiguity between the two overloads, and you can't call the cbData + pbData overload without both size and pointer. This intentionally breaks `builder.push_back(parent, name, type, size)`, which must be fixed by `builder.push_back(parent, name, type, size, NULL)` (assuming it wasn't a bug). |
||
---|---|---|
cmake/modules | ||
external | ||
include/jsonbuilder | ||
src | ||
test | ||
.clang-format | ||
.gitignore | ||
.gitmodules | ||
Android.bp | ||
CMakeLists.txt | ||
CONTRIBUTING.md | ||
LICENSE | ||
README.md | ||
SECURITY.md | ||
azure-pipelines.yml |
README.md
JsonBuilder
JsonBuilder is a small C++ library for building a space-efficient binary representation of structured data and, when ready, rendering it to JSON. The library offers STL-like syntax for adding and finding data as well as STL-like iterators for efficiently tracking location.
Examples
Building structured data
Let's try to build the following JSON up using the JsonBuilder interface:
{
"e": 2.718,
"enabled": true,
"user": "john",
"resolution": {
"x": 1024,
"y": 768
},
"colors": [
"Red",
"Green",
"Blue"
]
}
The code to do so would look like this:
JsonBuilder jb;
jb.push_back(jb.end(), "e", 2.718);
jb.push_back(jb.end(), "enabled", true);
jb.push_back(jb.end(), "user", "john");
JsonIterator resolutionItr = jb.push_back(jb.end(), "resolution", JsonObject);
jb.push_back(resolutionItr, "x", 1024);
jb.push_back(resolutionItr, "y", 768);
JsonIterator colorIterator = jb.push_back(jb.end(), "colors", JsonArray);
jb.push_back(colorIterator, "", "Red");
jb.push_back(colorIterator, "", "Green");
jb.push_back(colorIterator, "", "Blue");
Getting an iterator to existing data
Using the built JsonBuilder object above as a starting point:
// Float
JsonConstIterator eItr = jb.find("e");
float e = eItr->GetUnchecked<float>();
std::cout << e << std::endl;
// Object
JsonConstIterator resolutionItr = jb.find("resolution");
for (JsonConstIterator beginItr = resolutionItr.begin(),
endItr = resolutionItr.end();
beginItr != endItr;
++beginItr)
{
std::string name(beginItr->Name().data(), beginItr->Name().length());
std::cout << name << " " << beginItr->GetUnchecked<int64_t>()
<< std::endl;
}
// Array
JsonConstIterator colorsItr = jb.find("colors");
for (JsonConstIterator beginItr = colorsItr.begin(), endItr = colorsItr.end();
beginItr != endItr;
++beginItr)
{
auto color = beginItr->GetUnchecked<std::string_view>();
std::cout << color << std::endl;
}
Rendering to JSON
Using the built JsonBuilder object above as a starting point:
// Create a renderer and reserve 2048 bytes up front
JsonRenderer renderer;
renderer.Reserve(2048);
// Render a json builder object to a string
std::string_view result = renderer.Render(_jsonBuilder);
std::string stl_string(result.data(), result.size());
std::cout << stl_string.c_str() << std::endl;
Dependencies
The Linux tests for this project depend on the uuid library. To develop with this project, install the development version of the library:
sudo apt-get install uuid-dev
If you checkout with submodules, you will receive a version of Catch2 for testing that can be used automatically. If you do not checkout this submodule, the build system will instead search for an installed version of Catch2 and use that to build the tests.
Integration
JsonBuilder builds as a static library and requires C++17. The project creates a CMake compatible 'jsonbuilder' target which you can use for linking against the library.
- Add this project as a subdirectory in your project, either as a git submodule or copying the code directly.
- Add that directory to your top-level CMakeLists.txt with 'add_subdirectory'. This will make the 'jsonbuilder' target available.
- Add the 'jsonbuilder' target to the target_link_libraries of any target that will use the JsonBuilder library.
Reporting Security Issues
Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) at <secure@microsoft.com>. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the Security TechCenter.
Code of Conduct
This project has adopted the Microsoft Open Source Code of Conduct.
For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Contributing
Want to contribute? The team encourages community feedback and contributions. Please follow our contributing guidelines.
We also welcome issues submitted on GitHub.
Project Status
This project is currently in active development.
Contact
The easiest way to contact us is via the Issues page.