44#include < bson/bson.h>
55
66#include < cstddef>
7+ #include < stdexcept>
78#include < string>
89#include < string_view>
910#include < type_traits>
1011#include < variant>
1112#include < vector>
1213
1314#include " ../Box.hpp"
14- #include " ../Bytestring.hpp"
1515#include " ../Ref.hpp"
16- // #include "../Result.hpp"
17- #include " ../Vectorstring.hpp"
1816#include " ../always_false.hpp"
19- #include " ../internal/ptr_cast.hpp"
2017#include " ../common.hpp"
18+ #include " ../concepts.hpp"
19+ #include " ../internal/ptr_cast.hpp"
2120
2221namespace rfl {
2322namespace bson {
@@ -79,43 +78,65 @@ class RFL_API Writer {
7978 }
8079
8180 OutputArrayType add_array_to_array (const size_t _size,
82- OutputArrayType* _parent) const noexcept ;
81+ OutputArrayType* _parent) const ;
8382
8483 OutputArrayType add_array_to_object (const std::string_view& _name,
8584 const size_t _size,
86- OutputObjectType* _parent) const noexcept ;
85+ OutputObjectType* _parent) const ;
8786
8887 OutputObjectType add_object_to_array (const size_t _size,
89- OutputArrayType* _parent) const noexcept ;
88+ OutputArrayType* _parent) const ;
9089
91- OutputObjectType add_object_to_object (
92- const std::string_view& _name, const size_t _size,
93- OutputObjectType* _parent) const noexcept ;
90+ OutputObjectType add_object_to_object (const std::string_view& _name,
91+ const size_t _size,
92+ OutputObjectType* _parent) const ;
9493
9594 template <class T >
9695 OutputVarType add_value_to_array (const T& _var,
97- OutputArrayType* _parent) const noexcept {
96+ OutputArrayType* _parent) const {
9897 if constexpr (std::is_same<std::remove_cvref_t <T>, std::string>()) {
99- bson_array_builder_append_utf8 (_parent->val_ , _var.c_str (),
100- static_cast <int >(_var.size ()));
101- } else if constexpr (std::is_same<std::remove_cvref_t <T>,
102- rfl::Bytestring>() ||
103- std::is_same<std::remove_cvref_t <T>,
104- rfl::Vectorstring>()) {
105- bson_array_builder_append_binary (
98+ const bool ok = bson_array_builder_append_utf8 (
99+ _parent->val_ , _var.c_str (), static_cast <int >(_var.size ()));
100+ if (!ok) {
101+ throw std::runtime_error (" Could not append utf-8 to array." );
102+ }
103+
104+ } else if constexpr (concepts::MutableContiguousByteContainer<
105+ std::remove_cvref_t <T>>) {
106+ const bool ok = bson_array_builder_append_binary (
106107 _parent->val_ , BSON_SUBTYPE_BINARY,
107108 internal::ptr_cast<const uint8_t *>(_var.data ()),
108109 static_cast <uint32_t >(_var.size ()));
110+ if (!ok) {
111+ throw std::runtime_error (" Could not append binary to array." );
112+ }
113+
109114 } else if constexpr (std::is_same<std::remove_cvref_t <T>, bool >()) {
110- bson_array_builder_append_bool (_parent->val_ , _var);
115+ const bool ok = bson_array_builder_append_bool (_parent->val_ , _var);
116+ if (!ok) {
117+ throw std::runtime_error (" Could not append bool to array." );
118+ }
119+
111120 } else if constexpr (std::is_floating_point<std::remove_cvref_t <T>>()) {
112- bson_array_builder_append_double (_parent->val_ ,
113- static_cast <double >(_var));
121+ const bool ok = bson_array_builder_append_double (
122+ _parent->val_ , static_cast <double >(_var));
123+ if (!ok) {
124+ throw std::runtime_error (" Could not append float to array." );
125+ }
126+
114127 } else if constexpr (std::is_integral<std::remove_cvref_t <T>>()) {
115- bson_array_builder_append_int64 (_parent->val_ ,
116- static_cast <std::int64_t >(_var));
128+ const bool ok = bson_array_builder_append_int64 (
129+ _parent->val_ , static_cast <std::int64_t >(_var));
130+ if (!ok) {
131+ throw std::runtime_error (" Could not append integer to array." );
132+ }
133+
117134 } else if constexpr (std::is_same<std::remove_cvref_t <T>, bson_oid_t >()) {
118- bson_array_builder_append_oid (_parent->val_ , &_var);
135+ const bool ok = bson_array_builder_append_oid (_parent->val_ , &_var);
136+ if (!ok) {
137+ throw std::runtime_error (" Could not append OID to array." );
138+ }
139+
119140 } else {
120141 static_assert (rfl::always_false_v<T>, " Unsupported type." );
121142 }
@@ -125,47 +146,75 @@ class RFL_API Writer {
125146 template <class T >
126147 OutputVarType add_value_to_object (const std::string_view& _name,
127148 const T& _var,
128- OutputObjectType* _parent) const noexcept {
149+ OutputObjectType* _parent) const {
129150 if constexpr (std::is_same<std::remove_cvref_t <T>, std::string>()) {
130- bson_append_utf8 (_parent->val_ , _name.data (),
131- static_cast <int >(_name.size ()), _var.c_str (),
132- static_cast <int >(_var.size ()));
133- } else if constexpr (std::is_same<std::remove_cvref_t <T>,
134- rfl::Bytestring>() ||
135- std::is_same<std::remove_cvref_t <T>,
136- rfl::Vectorstring>()) {
137- bson_append_binary (_parent->val_ , _name.data (),
138- static_cast <int >(_name.size ()), BSON_SUBTYPE_BINARY,
139- internal::ptr_cast<const uint8_t *>(_var.data ()),
140- static_cast <uint32_t >(_var.size ()));
151+ const bool ok = bson_append_utf8 (
152+ _parent->val_ , _name.data (), static_cast <int >(_name.size ()),
153+ _var.c_str (), static_cast <int >(_var.size ()));
154+ if (!ok) {
155+ throw std::runtime_error (" Could not utf-8 field '" +
156+ std::string (_name) + " ' to object." );
157+ }
158+
159+ } else if constexpr (concepts::MutableContiguousByteContainer<
160+ std::remove_cvref_t <T>>) {
161+ const bool ok = bson_append_binary (
162+ _parent->val_ , _name.data (), static_cast <int >(_name.size ()),
163+ BSON_SUBTYPE_BINARY, internal::ptr_cast<const uint8_t *>(_var.data ()),
164+ static_cast <uint32_t >(_var.size ()));
165+ if (!ok) {
166+ throw std::runtime_error (" Could not binary field '" +
167+ std::string (_name) + " ' to object." );
168+ }
169+
141170 } else if constexpr (std::is_same<std::remove_cvref_t <T>, bool >()) {
142- bson_append_bool (_parent->val_ , _name.data (),
143- static_cast <int >(_name.size ()), _var);
171+ const bool ok = bson_append_bool (_parent->val_ , _name.data (),
172+ static_cast <int >(_name.size ()), _var);
173+ if (!ok) {
174+ throw std::runtime_error (" Could not boolean field '" +
175+ std::string (_name) + " ' to object." );
176+ }
177+
144178 } else if constexpr (std::is_floating_point<std::remove_cvref_t <T>>()) {
145- bson_append_double (_parent->val_ , _name.data (),
146- static_cast <int >(_name.size ()),
147- static_cast <double >(_var));
179+ const bool ok = bson_append_double (_parent->val_ , _name.data (),
180+ static_cast <int >(_name.size ()),
181+ static_cast <double >(_var));
182+ if (!ok) {
183+ throw std::runtime_error (" Could not floating point field '" +
184+ std::string (_name) + " ' to object." );
185+ }
186+
148187 } else if constexpr (std::is_integral<std::remove_cvref_t <T>>()) {
149- bson_append_int64 (_parent->val_ , _name.data (),
150- static_cast <int >(_name.size ()),
151- static_cast <std::int64_t >(_var));
188+ const bool ok = bson_append_int64 (_parent->val_ , _name.data (),
189+ static_cast <int >(_name.size ()),
190+ static_cast <std::int64_t >(_var));
191+ if (!ok) {
192+ throw std::runtime_error (" Could not int field '" + std::string (_name) +
193+ " ' to object." );
194+ }
195+
152196 } else if constexpr (std::is_same<std::remove_cvref_t <T>, bson_oid_t >()) {
153- bson_append_oid (_parent->val_ , _name.data (),
154- static_cast <int >(_name.size ()), &_var);
197+ const bool ok = bson_append_oid (_parent->val_ , _name.data (),
198+ static_cast <int >(_name.size ()), &_var);
199+ if (!ok) {
200+ throw std::runtime_error (" Could not oid field '" + std::string (_name) +
201+ " ' to object." );
202+ }
203+
155204 } else {
156205 static_assert (rfl::always_false_v<T>, " Unsupported type." );
157206 }
158207 return OutputVarType{};
159208 }
160209
161- OutputVarType add_null_to_array (OutputArrayType* _parent) const noexcept ;
210+ OutputVarType add_null_to_array (OutputArrayType* _parent) const ;
162211
163212 OutputVarType add_null_to_object (const std::string_view& _name,
164- OutputObjectType* _parent) const noexcept ;
213+ OutputObjectType* _parent) const ;
165214
166- void end_array (OutputArrayType* _arr) const noexcept ;
215+ void end_array (OutputArrayType* _arr) const ;
167216
168- void end_object (OutputObjectType* _obj) const noexcept ;
217+ void end_object (OutputObjectType* _obj) const ;
169218
170219 private:
171220 // / Pointer to the main document. In BSON, documents are what are usually
0 commit comments