BSON

BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type.

!!! abstract “References”

- [BSON Website](http://bsonspec.org) - the main source on BSON
- [BSON Specification](http://bsonspec.org/spec.html) - the specification

Serialization

The library uses the following mapping from JSON values types to BSON types:

JSON value typevalue/rangeBSON typemarker
nullnullnull0x0A
booleantrue, falseboolean0x08
number_integer-9223372036854775808..-2147483649int640x12
number_integer-2147483648..2147483647int320x10
number_integer2147483648..9223372036854775807int640x12
number_unsigned0..2147483647int320x10
number_unsigned2147483648..9223372036854775807int640x12
number_unsigned9223372036854775808..18446744073709551615uint640x11
number_floatany valuedouble0x01
stringany valuestring0x02
arrayany valuedocument0x04
objectany valuedocument0x03
binaryany valuebinary0x05

!!! warning “Incomplete mapping”

The mapping is **incomplete**, since only JSON-objects (and things contained therein) can be serialized to BSON.
Also, keys may not contain U+0000, since they are serialized a zero-terminated c-strings.

!!! warning “BSON type 0x11 interoperability”

The BSON specification defines type `0x11` as a Timestamp. This library uses marker `0x11` when serializing
`number_unsigned` values in the range `9223372036854775808..18446744073709551615`. Other BSON implementations may
therefore interpret these values as Timestamps instead of unsigned integers.

!!! info “Binary values without a subtype”

BSON requires every binary value to have a subtype. If a binary value has no subtype, this library serializes it
with the generic subtype `0x00`. After deserialization, `has_subtype()` returns `true` and `subtype()` returns `0`.
As a result, serializing and deserializing a JSON object containing such a value produces a different JSON object,
even though the binary data is unchanged.

??? example

```cpp
--8<-- "examples/to_bson.cpp"
```

Output:

```c
--8<-- "examples/to_bson.output"
```

Deserialization

The library maps BSON record types to JSON value types as follows:

BSON typeBSON marker byteJSON value type
double0x01number_float
string0x02string
document0x03object
array0x04array
binary0x05binary
undefined0x06unsupported
ObjectId0x07unsupported
boolean0x08boolean
UTC Date-Time0x09unsupported
null0x0Anull
Regular Expr.0x0Bunsupported
DB Pointer0x0Cunsupported
JavaScript Code0x0Dunsupported
Symbol0x0Eunsupported
JavaScript Code w/ scope0x0Funsupported
int320x10number_integer
uint64(Timestamp)0x11number_unsigned
int640x12number_integer
128-bit decimal float0x13unsupported
Max Key0x7Funsupported
Min Key0xFFunsupported

!!! warning “Incomplete mapping”

The mapping is **incomplete**. The unsupported mappings are indicated in the table above.

!!! note “Handling of BSON type 0x11”

This library deserializes BSON type `0x11` (Timestamp) as a `number_unsigned` value. The 64-bit value is preserved,
but the Timestamp type information is not.

!!! warning “Lenient BSON input handling”

The BSON reader is lenient in a few areas where the BSON specification is more restrictive:

- array element keys are not checked against the required decimal sequence (`0`, `1`, `2`, ...),
- any non-zero byte is accepted as `true` for the boolean type, and
- the payload for binary subtype `0x02` is returned as-is, including its inner length prefix.

If BSON input must be validated for strict specification compliance, validate it separately before passing it to
`from_bson()`.

??? example

```cpp
--8<-- "examples/from_bson.cpp"
```

Output:

```json
--8<-- "examples/from_bson.output"
```