Skip to content

Commit d94c821

Browse files
committed
Support BSON uint64 de/serialization
Signed-off-by: Michael Valladolid <[email protected]>
1 parent 48e7b4c commit d94c821

File tree

6 files changed

+30
-16
lines changed

6 files changed

+30
-16
lines changed

docs/mkdocs/docs/features/binary_formats/bson.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ The library uses the following mapping from JSON values types to BSON types:
2323
| number_integer | 2147483648..9223372036854775807 | int64 | 0x12 |
2424
| number_unsigned | 0..2147483647 | int32 | 0x10 |
2525
| number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 |
26-
| number_unsigned | 9223372036854775808..18446744073709551615 | -- | -- |
26+
| number_unsigned | 9223372036854775808..18446744073709551615 | int64 | 0x11 |
2727
| number_float | *any value* | double | 0x01 |
2828
| string | *any value* | string | 0x02 |
2929
| array | *any value* | document | 0x04 |
@@ -73,7 +73,7 @@ The library maps BSON record types to JSON value types as follows:
7373
| Symbol | 0x0E | *unsupported* |
7474
| JavaScript Code | 0x0F | *unsupported* |
7575
| int32 | 0x10 | number_integer |
76-
| Timestamp | 0x11 | *unsupported* |
76+
| Timestamp | 0x11 | number_unsigned |
7777
| 128-bit decimal float | 0x13 | *unsupported* |
7878
| Max Key | 0x7F | *unsupported* |
7979
| Min Key | 0xFF | *unsupported* |

docs/mkdocs/docs/home/exceptions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ A parsed number could not be stored as without changing it to NaN or INF.
839839

840840
### json.exception.out_of_range.407
841841

842-
UBJSON and BSON only support integer numbers up to 9223372036854775807.
842+
UBJSON only support integer numbers up to 9223372036854775807.
843843

844844
!!! failure "Example message"
845845

include/nlohmann/detail/input/binary_reader.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ class binary_reader
328328
return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
329329
}
330330

331+
case 0x11: // uint64
332+
{
333+
std::uint64_t value{};
334+
return get_number<std::uint64_t, true>(input_format_t::bson, value) && sax->number_unsigned(value);
335+
}
336+
331337
default: // anything else not supported (yet)
332338
{
333339
std::array<char, 3> cr{{}};

include/nlohmann/detail/output/binary_writer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,7 +1097,8 @@ class binary_writer
10971097
}
10981098
else
10991099
{
1100-
JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
1100+
write_bson_entry_header(name, 0x11 /* int64 */);
1101+
write_number<std::uint64_t>(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned), true);
11011102
}
11021103
}
11031104

single_include/nlohmann/json.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10006,6 +10006,12 @@ class binary_reader
1000610006
return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
1000710007
}
1000810008

10009+
case 0x11: // uint64
10010+
{
10011+
std::uint64_t value{};
10012+
return get_number<std::uint64_t, true>(input_format_t::bson, value) && sax->number_unsigned(value);
10013+
}
10014+
1000910015
default: // anything else not supported (yet)
1001010016
{
1001110017
std::array<char, 3> cr{{}};
@@ -16733,7 +16739,8 @@ class binary_writer
1673316739
}
1673416740
else
1673516741
{
16736-
JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16742+
write_bson_entry_header(name, 0x11 /* int64 */);
16743+
write_number<std::uint64_t>(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned), true);
1673716744
}
1673816745
}
1673916746

tests/src/unit-bson.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,10 +1164,7 @@ TEST_CASE("BSON numerical data")
11641164
std::vector<std::uint64_t> const numbers
11651165
{
11661166
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()) + 1ULL,
1167-
10000000000000000000ULL,
1168-
18000000000000000000ULL,
1169-
(std::numeric_limits<std::uint64_t>::max)() - 1ULL,
1170-
(std::numeric_limits<std::uint64_t>::max)(),
1167+
0xffffffffffffffff,
11711168
};
11721169

11731170
for (const auto i : numbers)
@@ -1184,7 +1181,7 @@ TEST_CASE("BSON numerical data")
11841181
std::vector<std::uint8_t> const expected_bson =
11851182
{
11861183
0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)
1187-
0x12u, /// entry: int64
1184+
0x11u, /// entry: uint64
11881185
'e', 'n', 't', 'r', 'y', '\x00',
11891186
static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
11901187
static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
@@ -1197,12 +1194,15 @@ TEST_CASE("BSON numerical data")
11971194
0x00u // end marker
11981195
};
11991196

1200-
CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);
1201-
#if JSON_DIAGNOSTICS
1202-
CHECK_THROWS_WITH_STD_STR(json::to_bson(j), "[json.exception.out_of_range.407] (/entry) integer number " + std::to_string(i) + " cannot be represented by BSON as it does not fit int64");
1203-
#else
1204-
CHECK_THROWS_WITH_STD_STR(json::to_bson(j), "[json.exception.out_of_range.407] integer number " + std::to_string(i) + " cannot be represented by BSON as it does not fit int64");
1205-
#endif
1197+
const auto bson = json::to_bson(j);
1198+
CHECK(bson == expected_bson);
1199+
1200+
auto j_roundtrip = json::from_bson(bson);
1201+
1202+
CHECK(j.at("entry").is_number_unsigned());
1203+
CHECK(j_roundtrip.at("entry").is_number_unsigned());
1204+
CHECK(j_roundtrip == j);
1205+
CHECK(json::from_bson(bson, true, false) == j);
12061206
}
12071207
}
12081208

0 commit comments

Comments
 (0)