File tree Expand file tree Collapse file tree 4 files changed +66
-1
lines changed Expand file tree Collapse file tree 4 files changed +66
-1
lines changed Original file line number Diff line number Diff line change 2020#include < sstream>
2121#include < vector>
2222
23+ #include < bson.h>
24+
2325#include < bsoncxx/document/view.hpp>
2426#include < bsoncxx/stdx/make_unique.hpp>
2527#include < bsoncxx/stdx/string_view.hpp>
@@ -33,6 +35,10 @@ BSONCXX_INLINE_NAMESPACE_BEGIN
3335
3436namespace {
3537
38+ void bson_free_deleter (std::uint8_t * ptr) {
39+ bson_free (ptr);
40+ }
41+
3642class json_visitor {
3743 public:
3844 json_visitor (std::ostream& out, bool is_array, std::size_t padding)
@@ -275,5 +281,19 @@ std::string to_json(types::value value) {
275281 return ss.str ();
276282}
277283
284+ stdx::optional<document::value> from_json (stdx::string_view json) {
285+ bson_error_t error;
286+ bson_t * result = bson_new_from_json (
287+ reinterpret_cast <const uint8_t *>(json.data ()), json.size (), &error);
288+
289+ if (!result)
290+ return stdx::nullopt ;
291+
292+ std::uint32_t length;
293+ std::uint8_t * buf = bson_destroy_with_steal (result, true , &length);
294+
295+ return document::value{buf, length, bson_free_deleter};
296+ }
297+
278298BSONCXX_INLINE_NAMESPACE_END
279299} // namespace bsoncxx
Original file line number Diff line number Diff line change 1818
1919#include < string>
2020
21+ #include < bsoncxx/document/value.hpp>
2122#include < bsoncxx/document/view.hpp>
23+ #include < bsoncxx/stdx/optional.hpp>
2224
2325namespace bsoncxx {
2426BSONCXX_INLINE_NAMESPACE_BEGIN
@@ -55,6 +57,16 @@ BSONCXX_API std::string to_json(document::element element);
5557// /
5658BSONCXX_API std::string to_json (types::value value);
5759
60+ // /
61+ // / Constructs a new document::value from the provided JSON text
62+ // /
63+ // / @param 'json'
64+ // / A string_view into a JSON document
65+ // /
66+ // / @returns An engaged optional containing a document::value if conversion worked.
67+ // /
68+ BSONCXX_API stdx::optional<document::value> from_json (stdx::string_view json);
69+
5870BSONCXX_INLINE_NAMESPACE_END
5971} // namespace bsoncxx
6072
Original file line number Diff line number Diff line change @@ -3,10 +3,11 @@ include_directories(
33)
44
55add_executable (test_bson
6+ bson_builder.cpp
67 bson_util_itoa.cpp
78 bson_validate.cpp
9+ json.cpp
810 new_tests.cpp
9- bson_builder.cpp
1011)
1112
1213target_link_libraries (test_bson bsoncxx_static)
Original file line number Diff line number Diff line change 1+ #include " catch.hpp"
2+
3+ #include < bsoncxx/builder/stream/document.hpp>
4+ #include < bsoncxx/json.hpp>
5+
6+ namespace {
7+ constexpr auto k_invalid_json = R"( {])" ;
8+ constexpr auto k_valid_json = R"( { "a" : 1, "b" : 2.0 })" ;
9+ }
10+
11+ TEST_CASE (" invalid json returns disengaged optional" ) {
12+ using namespace bsoncxx ;
13+ REQUIRE (!from_json (k_invalid_json));
14+ }
15+
16+ TEST_CASE (" valid json returns an engaged optional" ) {
17+ using namespace bsoncxx ;
18+ REQUIRE (from_json (k_valid_json));
19+ }
20+
21+ TEST_CASE (" valid json is converted to equivalent BSON" ) {
22+ using namespace bsoncxx ;
23+
24+ const auto expected = builder::stream::document{} << " a" << 1 << " b" << 2.0 << builder::stream::finalize;
25+ const auto expected_view = expected.view ();
26+
27+ const auto actual = from_json (k_valid_json);
28+ const auto actual_view = actual->view ();
29+
30+ REQUIRE (expected_view.length () == actual_view.length ());
31+ REQUIRE (0 == memcmp (expected_view.data (), actual_view.data (), expected_view.length ()));
32+ }
You can’t perform that action at this time.
0 commit comments