Skip to content

Commit f573b11

Browse files
author
Micah Scott
committed
sub_binary builder and integration with core
1 parent 5360c23 commit f573b11

File tree

5 files changed

+190
-3
lines changed

5 files changed

+190
-3
lines changed

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/builder/basic/impl.hpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#pragma once
1616

1717
#include <bsoncxx/builder/basic/sub_array.hpp>
18+
#include <bsoncxx/builder/basic/sub_binary.hpp>
1819
#include <bsoncxx/builder/basic/sub_document.hpp>
1920
#include <bsoncxx/stdx/type_traits.hpp>
2021

@@ -40,10 +41,19 @@ detail::requires_t<void, detail::is_invocable<T, sub_array>> generic_append(core
4041
core->close_array();
4142
}
4243

44+
template <typename T>
45+
detail::requires_t<void, detail::is_invocable<T, sub_binary>> generic_append(core* core, T&& func) {
46+
detail::invoke(std::forward<T>(func), sub_binary(core));
47+
core->close_binary();
48+
}
49+
4350
template <typename T, typename = void, typename = void>
44-
detail::requires_not_t<void, detail::is_invocable<T, sub_document>, detail::is_invocable<T, sub_array>> generic_append(
45-
core* core,
46-
T&& t) {
51+
detail::requires_not_t<
52+
void,
53+
detail::is_invocable<T, sub_document>,
54+
detail::is_invocable<T, sub_array>,
55+
detail::is_invocable<T, sub_binary>>
56+
generic_append(core* core, T&& t) {
4757
core->append(std::forward<T>(t));
4858
}
4959

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
namespace bsoncxx {
18+
namespace v_noabi {
19+
namespace builder {
20+
namespace basic {
21+
22+
class sub_binary;
23+
24+
} // namespace basic
25+
} // namespace builder
26+
} // namespace v_noabi
27+
} // namespace bsoncxx
28+
29+
namespace bsoncxx {
30+
namespace builder {
31+
namespace basic {
32+
33+
using ::bsoncxx::v_noabi::builder::basic::sub_binary;
34+
35+
} // namespace basic
36+
} // namespace builder
37+
} // namespace bsoncxx
38+
39+
///
40+
/// @file
41+
/// Declares @ref bsoncxx::builder::basic::sub_binary, for constructing BSON Binary values in-place.
42+
///
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include <bsoncxx/builder/basic/sub_binary-fwd.hpp>
18+
19+
#include <bsoncxx/builder/core.hpp>
20+
#include <bsoncxx/types.hpp>
21+
#include <bsoncxx/vector/formats.hpp>
22+
#include <bsoncxx/vector/impl.hpp>
23+
#include <bsoncxx/vector/view.hpp>
24+
25+
#include <bsoncxx/config/prelude.hpp>
26+
27+
namespace bsoncxx {
28+
namespace v_noabi {
29+
namespace builder {
30+
namespace basic {
31+
32+
///
33+
/// Represents a BSON Binary element being constructed during an append operation.
34+
///
35+
class sub_binary {
36+
public:
37+
///
38+
/// Default constructor
39+
///
40+
sub_binary(core* core) : _core(core) {}
41+
42+
/// @brief Allocate space for an un-initialized BSON Binary element of any subtype.
43+
/// @param sub_type BSON binary subtype code, identifying the format of the data within.
44+
/// @param length Number of bytes to allocate
45+
/// @return Pointer to uninitialized memory within the bson_t, valid only during this sub_binary builder's lifetime.
46+
/// The caller must overwrite every byte if the resulting BSON document is to be used.
47+
/// @throws bsoncxx::v_noabi::exception if this sub_binary has already allocated.
48+
/// bsoncxx::v_noabi::exception if the binary fails to append due to the BSON size limit.
49+
uint8_t* allocate(binary_sub_type sub_type, uint32_t length) {
50+
return _core->append(sub_type, length);
51+
}
52+
53+
/// @brief Allocate and format space for a BSON Binary Vector with uninitialized elements.
54+
/// @param fmt Instance of a format type from @ref bsoncxx::v_noabi::vector::formats
55+
/// @param element_count Number of elements to allocate space for.
56+
/// @return A vector::view, valid during the lifetime of this sub_binary builder. Every element must be overwritten
57+
/// before that element is read or the resulting document is used.
58+
/// @throws bsoncxx::v_noabi::exception if this sub_binary has already allocated.
59+
/// bsoncxx::v_noabi::exception if the binary fails to append due to the BSON size limit.
60+
/// bsoncxx::v_noabi::exception if a vector of the requested size would be too large to represent.
61+
template <typename Format, typename SFINAE = typename vector::impl::format_traits<Format>::value_type>
62+
vector::view<Format> allocate(Format, std::size_t element_count) {
63+
using format_traits = typename vector::impl::format_traits<Format>;
64+
uint32_t binary_data_length = format_traits::length_for_append(element_count);
65+
uint8_t* binary_data = allocate(binary_sub_type::k_vector, binary_data_length);
66+
return {
67+
{binary_data,
68+
binary_data_length,
69+
format_traits::write_frame(binary_data, binary_data_length, element_count)}};
70+
}
71+
72+
private:
73+
core* _core;
74+
};
75+
76+
} // namespace basic
77+
} // namespace builder
78+
} // namespace v_noabi
79+
} // namespace bsoncxx
80+
81+
#include <bsoncxx/config/postlude.hpp>
82+
83+
///
84+
/// @file
85+
/// Declares @ref bsoncxx::v_noabi::builder::basic::sub_binary, for constructing BSON Binary values in-place.
86+
///

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/builder/core.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ class core {
237237
///
238238
BSONCXX_ABI_EXPORT_CDECL(core&) append(types::b_binary const& value);
239239

240+
///
241+
/// Appends a BSON binary datum by allocating space that the caller must fill with content.
242+
///
243+
/// @return
244+
/// A pointer to the allocated binary data block. The caller must write to every
245+
/// byte or discard the builder.
246+
///
247+
/// @throws
248+
/// bsoncxx::v_noabi::exception if the current BSON datum is a document that is waiting for a
249+
/// key to be appended to start a new key/value pair.
250+
/// bsoncxx::v_noabi::exception if the binary fails to append.
251+
///
252+
BSONCXX_ABI_EXPORT_CDECL(uint8_t*) append(binary_sub_type sub_type, uint32_t length);
253+
240254
///
241255
/// Appends a BSON undefined.
242256
///
@@ -693,6 +707,17 @@ class core {
693707
///
694708
BSONCXX_ABI_EXPORT_CDECL(void) clear();
695709

710+
///
711+
/// Closes the current sub-binary within this BSON datum.
712+
///
713+
/// @return
714+
/// A reference to the object on which this member function is being called. This facilitates
715+
/// method chaining.
716+
///
717+
/// @throws bsoncxx::v_noabi::exception if the binary contents were never allocated.
718+
///
719+
BSONCXX_ABI_EXPORT_CDECL(core&) close_binary();
720+
696721
private:
697722
std::unique_ptr<impl> _impl;
698723
};

src/bsoncxx/lib/bsoncxx/v_noabi/bsoncxx/builder/core.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,23 @@ core& core::append(types::b_binary const& value) {
351351
return *this;
352352
}
353353

354+
uint8_t* core::append(binary_sub_type sub_type, uint32_t length) {
355+
stdx::string_view key = _impl->next_key();
356+
uint8_t* allocated_bytes;
357+
358+
if (!bson_append_binary_uninit(
359+
_impl->back(),
360+
key.data(),
361+
static_cast<std::int32_t>(key.length()),
362+
static_cast<bson_subtype_t>(sub_type),
363+
&allocated_bytes,
364+
length)) {
365+
throw bsoncxx::v_noabi::exception{error_code::k_cannot_append_binary};
366+
}
367+
368+
return allocated_bytes;
369+
}
370+
354371
core& core::append(types::b_undefined const&) {
355372
stdx::string_view key = _impl->next_key();
356373

@@ -685,6 +702,13 @@ core& core::close_array() {
685702
return *this;
686703
}
687704

705+
core& core::close_binary() {
706+
if (!_impl->is_viewable()) {
707+
throw bsoncxx::v_noabi::exception{error_code::k_unmatched_key_in_builder};
708+
}
709+
return *this;
710+
}
711+
688712
bsoncxx::v_noabi::document::view core::view_document() const {
689713
if (!_impl->is_viewable()) {
690714
throw bsoncxx::v_noabi::exception{error_code::k_unmatched_key_in_builder};

0 commit comments

Comments
 (0)