mirror of
https://github.com/nlohmann/json.git
synced 2026-07-12 05:25:09 +00:00
130 lines
5.4 KiB
Markdown
130 lines
5.4 KiB
Markdown
# <small>nlohmann::basic_json::</small>binary_t
|
|
|
|
```cpp
|
|
using binary_t = byte_container_with_subtype<BinaryType>;
|
|
```
|
|
|
|
This type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type
|
|
2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for
|
|
compatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values.
|
|
|
|
Additionally, as an implementation detail, the subtype of the binary data is carried around as a `std::uint64_t`, which
|
|
is compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is
|
|
incompatible with each other, and it is up to the user to translate between them). The subtype is added to `BinaryType`
|
|
via the helper type [byte_container_with_subtype](../byte_container_with_subtype/index.md).
|
|
|
|
[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type as:
|
|
> Major type 2: a byte string. The string's length in bytes is represented following the rules for positive integers
|
|
> (major type 0).
|
|
|
|
[MessagePack's documentation on the bin type
|
|
family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) describes this type as:
|
|
> Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array.
|
|
|
|
[BSON's specifications](http://bsonspec.org/spec.html) describe several binary types; however, this type is intended to
|
|
represent the generic binary type which has the description:
|
|
> Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and
|
|
> tools.
|
|
|
|
None of these impose any limitations on the internal representation other than the basic unit of storage be some type of
|
|
array whose parts are decomposable into bytes.
|
|
|
|
The default representation of this binary format is a `#!cpp std::vector<std::uint8_t>`, which is a very common way to
|
|
represent a byte array in modern C++.
|
|
|
|
## Template parameters
|
|
|
|
`BinaryType`
|
|
: container type to store arrays
|
|
|
|
Although not formally expressed as a C++ concept, `BinaryType` must be default-constructible,
|
|
copy/move-constructible, and support `push_back()`, `.data()`, and `.size()`, because
|
|
[`byte_container_with_subtype`](../byte_container_with_subtype/index.md) derives directly from it. Its
|
|
`value_type` must additionally be exactly one byte wide (e.g., `std::uint8_t`/`char`/`std::byte`): the binary
|
|
serializers (CBOR, MessagePack, BSON, UBJSON) read and write the container's raw bytes via
|
|
`reinterpret_cast`, which is only correct for byte-sized elements -- a container like
|
|
`#!cpp std::vector<std::intptr_t>` will not work as `BinaryType`.
|
|
|
|
## Notes
|
|
|
|
#### Default type
|
|
|
|
The default values for `BinaryType` is `#!cpp std::vector<std::uint8_t>`.
|
|
|
|
#### Custom BinaryType behavior
|
|
|
|
When a custom `BinaryType` is configured (other than the default `#!cpp std::vector<std::uint8_t>`), you can assign
|
|
values of that type directly to a `basic_json` instance, and they will automatically be recognized as binary values
|
|
rather than arrays:
|
|
|
|
```cpp
|
|
using custom_json = nlohmann::basic_json<
|
|
nlohmann::ordered_map, // ObjectType
|
|
std::vector, // ArrayType
|
|
std::string, // StringType
|
|
bool, // BooleanType
|
|
std::int64_t, // NumberIntegerType
|
|
std::uint64_t, // NumberUnsignedType
|
|
double, // NumberFloatType
|
|
std::allocator, // AllocatorType
|
|
nlohmann::adl_serializer,
|
|
std::vector<std::byte> // Custom BinaryType
|
|
>;
|
|
|
|
std::vector<std::byte> data{std::byte{1}, std::byte{2}, std::byte{3}};
|
|
custom_json j = data; // Creates a binary value, not an array
|
|
assert(j.is_binary());
|
|
|
|
// Round-tripping works seamlessly
|
|
auto extracted = j.get<std::vector<std::byte>>();
|
|
assert(extracted == data);
|
|
```
|
|
|
|
This automatic type detection is a convenience feature that only applies to custom (non-default) `BinaryType` configurations.
|
|
The default `nlohmann::json` continues to treat `#!cpp std::vector<std::uint8_t>` as arrays for backward compatibility.
|
|
|
|
#### Storage
|
|
|
|
Binary Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of the
|
|
type `#!cpp binary_t*` must be dereferenced.
|
|
|
|
#### Notes on subtypes
|
|
|
|
- CBOR
|
|
- Binary values are represented as byte strings. Subtypes are written as tags.
|
|
|
|
- MessagePack
|
|
- If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1,
|
|
fixext2, fixext4, fixext8) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is
|
|
then added as a signed 8-bit integer.
|
|
- If no subtype is given, the bin family (bin8, bin16, bin32) is used.
|
|
|
|
- BSON
|
|
- If a subtype is given, it is used and added as an unsigned 8-bit integer.
|
|
- If no subtype is given, the generic binary subtype 0x00 is used.
|
|
|
|
## Examples
|
|
|
|
??? example
|
|
|
|
The following code shows that `binary_t` is by default, a typedef to
|
|
`#!cpp nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>`.
|
|
|
|
```cpp
|
|
--8<-- "examples/binary_t.cpp"
|
|
```
|
|
|
|
Output:
|
|
|
|
```json
|
|
--8<-- "examples/binary_t.output"
|
|
```
|
|
|
|
## See also
|
|
|
|
- [byte_container_with_subtype](../byte_container_with_subtype/index.md)
|
|
|
|
## Version history
|
|
|
|
- Added in version 3.8.0. Changed the type of subtype to `std::uint64_t` in version 3.10.0.
|