Skip to content

Commit 54f58f4

Browse files
authored
CXX-3233 add bsoncxx v1 implementations and tests (#1430)
1 parent 939c336 commit 54f58f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+6460
-7
lines changed

src/bsoncxx/include/bsoncxx/v1/oid.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class oid {
5656
/// [`bson_oid_init`](https://mongoc.org/libbson/current/bson_oid_init.html) function with the default
5757
/// [`bson_context_t`](https://mongoc.org/libbson/current/bson_context_t.html).
5858
///
59+
/// @important On Windows only, the first call to this function initializes a static local variable which loads the
60+
/// Winsock DLL by calling `WSAStartup()`. The Winsock DLL is unloaded by calling `WSACleanup()` when the static
61+
/// local variable is destroyed.
62+
///
5963
/// @throws bsoncxx::v1::exception (on Windows only) with a `std::system_category()` error code
6064
/// (as returned by
6165
/// [`WSAGetLastError()`](https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsagetlasterror))

src/bsoncxx/include/bsoncxx/v1/types/id.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,14 @@ enum class binary_subtype : std::uint8_t {
8484
k_column = 0x07, ///< Compressed BSON column.
8585
k_sensitive = 0x08, ///< Sensitive.
8686
k_vector = 0x09, ///< Vector.
87-
k_user = 0x80, ///< User defined.
87+
k_user = 0x80, ///< User defined (up to 0xFF, inclusive).
8888
};
8989

9090
///
9191
/// Return the name of the enumerator (e.g. `"binary"` given `k_binary`).
9292
///
93+
/// @note Values in the range [0x80, 0xFF] are all equivalent to "k_user".
94+
///
9395
/// @attention This feature is experimental! It is not ready for use!
9496
///
9597
BSONCXX_ABI_EXPORT_CDECL(std::string) to_string(binary_subtype rhs);

src/bsoncxx/lib/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,8 @@ set_dist_list(src_bsoncxx_lib_DIST
115115
bsoncxx/v_noabi/bsoncxx/types/bson_value/value.hh
116116
bsoncxx/v1/config/config.hpp.in
117117
bsoncxx/v1/config/version.hpp.in
118+
bsoncxx/v1/document/view.hh
119+
bsoncxx/v1/element/view.hh
120+
bsoncxx/v1/types/value.hh
121+
bsoncxx/v1/types/view.hh
118122
)

src/bsoncxx/lib/bsoncxx/v1/array/view.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,24 @@
1616

1717
//
1818

19+
#include <bsoncxx/v1/exception.hpp>
20+
21+
#include <bsoncxx/v1/document/view.hh>
22+
#include <bsoncxx/v1/element/view.hh>
23+
24+
#include <cstdint>
25+
26+
#include <bsoncxx/private/bson.hh>
27+
#include <bsoncxx/private/immortal.hh>
28+
#include <bsoncxx/private/itoa.hh>
1929
#include <bsoncxx/private/type_traits.hh>
2030

2131
namespace bsoncxx {
2232
namespace v1 {
2333
namespace array {
2434

35+
using code = v1::document::view::errc;
36+
2537
static_assert(is_regular<view>::value, "bsoncxx::v1::array::view must be regular");
2638
static_assert(is_semitrivial<view>::value, "bsoncxx::v1::array::view must be semitrivial");
2739

@@ -30,6 +42,33 @@ static_assert(
3042
is_nothrow_moveable<view::const_iterator>::value,
3143
"bsoncxx::v1::array::view::const_iterator must be nothrow moveable");
3244

45+
view::const_iterator view::find(std::uint32_t i) const {
46+
if (!_view) {
47+
return this->cend();
48+
}
49+
50+
bsoncxx::itoa key{i};
51+
52+
bson_t bson;
53+
54+
if (!bson_init_static(&bson, _view.data(), _view.length())) {
55+
throw v1::exception{code::invalid_data};
56+
}
57+
58+
bson_iter_t iter;
59+
60+
if (bson_iter_init_find_w_len(&iter, &bson, key.c_str(), static_cast<int>(key.length()))) {
61+
return const_iterator::internal::make_const_iterator(
62+
_view.data(), _view.length(), bson_iter_offset(&iter), bson_iter_key_len(&iter));
63+
}
64+
65+
if (iter.err_off != 0) {
66+
throw v1::exception{code::invalid_data};
67+
}
68+
69+
return this->end();
70+
}
71+
3372
} // namespace array
3473
} // namespace v1
3574
} // namespace bsoncxx

src/bsoncxx/lib/bsoncxx/v1/decimal128.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,117 @@
1616

1717
//
1818

19+
#include <bsoncxx/v1/exception.hpp>
20+
21+
#include <climits>
22+
#include <cstddef>
23+
#include <string>
24+
#include <system_error>
25+
26+
#include <bsoncxx/private/bson.hh>
27+
#include <bsoncxx/private/immortal.hh>
1928
#include <bsoncxx/private/type_traits.hh>
2029

2130
namespace bsoncxx {
2231
namespace v1 {
2332

33+
using code = v1::decimal128::errc;
34+
2435
static_assert(is_regular<decimal128>::value, "bsoncxx::v1::decimal128 must be regular");
2536
static_assert(is_semitrivial<decimal128>::value, "bsoncxx::v1::decimal128 must be semitrivial");
2637

38+
decimal128::decimal128(v1::stdx::string_view sv) {
39+
if (sv.empty()) {
40+
throw v1::exception{code::empty_string};
41+
}
42+
43+
if (sv.size() > std::size_t{INT_MAX}) {
44+
throw v1::exception{code::invalid_string_length};
45+
}
46+
47+
bson_decimal128_t d128;
48+
49+
if (!bson_decimal128_from_string_w_len(sv.data(), static_cast<int>(sv.size()), &d128)) {
50+
throw v1::exception{code::invalid_string_data};
51+
}
52+
53+
_high = d128.high;
54+
_low = d128.low;
55+
}
56+
57+
std::string decimal128::to_string() const {
58+
bson_decimal128_t d128;
59+
d128.high = _high;
60+
d128.low = _low;
61+
char str[BSON_DECIMAL128_STRING];
62+
bson_decimal128_to_string(&d128, str);
63+
return {str};
64+
}
65+
66+
std::error_category const& decimal128::error_category() {
67+
class type final : public std::error_category {
68+
char const* name() const noexcept override {
69+
return "bsoncxx::v1::decimal128";
70+
}
71+
72+
std::string message(int v) const noexcept override {
73+
switch (static_cast<code>(v)) {
74+
case code::zero:
75+
return "zero";
76+
case code::empty_string:
77+
return "string must not be empty";
78+
case code::invalid_string_length:
79+
return "length of string is too long (exceeds INT_MAX)";
80+
case code::invalid_string_data:
81+
return "string is not a valid Decimal128 representation";
82+
default:
83+
return std::string(this->name()) + ':' + std::to_string(v);
84+
}
85+
}
86+
87+
bool equivalent(int v, std::error_condition const& ec) const noexcept override {
88+
if (ec.category() == v1::source_error_category()) {
89+
using condition = v1::source_errc;
90+
91+
auto const source = static_cast<condition>(ec.value());
92+
93+
switch (static_cast<code>(v)) {
94+
case code::empty_string:
95+
case code::invalid_string_length:
96+
case code::invalid_string_data:
97+
return source == condition::bsoncxx;
98+
99+
case code::zero:
100+
default:
101+
return false;
102+
}
103+
}
104+
105+
if (ec.category() == v1::type_error_category()) {
106+
using condition = v1::type_errc;
107+
108+
auto const type = static_cast<condition>(ec.value());
109+
110+
switch (static_cast<code>(v)) {
111+
case code::empty_string:
112+
case code::invalid_string_length:
113+
case code::invalid_string_data:
114+
return type == condition::invalid_argument;
115+
116+
case code::zero:
117+
default:
118+
return false;
119+
}
120+
}
121+
122+
return false;
123+
}
124+
};
125+
126+
static bsoncxx::immortal<type> const instance;
127+
128+
return instance.value();
129+
}
130+
27131
} // namespace v1
28132
} // namespace bsoncxx

src/bsoncxx/lib/bsoncxx/v1/document/value.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace document {
2525
static_assert(is_regular<value>::value, "bsoncxx::v1::document::value must be regular");
2626
static_assert(is_nothrow_moveable<value>::value, "bsoncxx::v1::document::value must be nothrow moveable");
2727

28+
void value::noop_deleter(std::uint8_t*) { /* noop */ }
29+
2830
} // namespace document
2931
} // namespace v1
3032
} // namespace bsoncxx

0 commit comments

Comments
 (0)