From ee3981d7d7f8f59cdc40a9e572909dc9d58148ad Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Sat, 13 Jan 2024 17:57:14 +0100 Subject: [PATCH] Began implementing the BSON writer --- include/rfl/bson/Writer.hpp | 187 ++++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 85 deletions(-) diff --git a/include/rfl/bson/Writer.hpp b/include/rfl/bson/Writer.hpp index 285082eb..0b8586ab 100644 --- a/include/rfl/bson/Writer.hpp +++ b/include/rfl/bson/Writer.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "../Result.hpp" @@ -18,146 +19,162 @@ namespace rfl { namespace bson { +/// Please refer to https://mongoc.org/libbson/current/api.html class Writer { + using ParentType = std::variant; + public: - struct YYBSONOutputArray { - YYBSONOutputArray(yybson_mut_val* _val) : val_(_val) {} - yybson_mut_val* val_; + struct BSONOutputArray { + BSONOutputArray(bson_array_builder_t* _val, ParentType _parent) + : parent_(_parent), val_(_val) {} + ParentType parent_; + bson_array_builder_t* val_; }; - struct YYBSONOutputObject { - YYBSONOutputObject(yybson_mut_val* _val) : val_(_val) {} - yybson_mut_val* val_; + struct BSONOutputObject { + BSONOutputObject(bson_t _val, ParentType _parent) + : parent_(_parent), val_(_val) {} + ParentType parent_; + bson_array_builder_t* val_; }; - struct YYBSONOutputVar { - YYBSONOutputVar(yybson_mut_val* _val) : val_(_val) {} - - YYBSONOutputVar(YYBSONOutputArray _arr) : val_(_arr.val_) {} - - YYBSONOutputVar(YYBSONOutputObject _obj) : val_(_obj.val_) {} - - yybson_mut_val* val_; - }; + struct BSONOutputVar {}; - using OutputArrayType = YYBSONOutputArray; - using OutputObjectType = YYBSONOutputObject; - using OutputVarType = YYBSONOutputVar; + using OutputArrayType = BSONOutputArray; + using OutputObjectType = BSONOutputObject; + using OutputVarType = BSONOutputVar; - Writer(yybson_mut_doc* _doc) : doc_(_doc) {} + Writer() : { bson_init(&doc_); } ~Writer() = default; - OutputArrayType array_as_root(const size_t _size) const noexcept { - const auto arr = yybson_mut_arr(doc_); - yybson_mut_doc_set_root(doc_, arr); - return OutputArrayType(arr); - } + // TODO + OutputArrayType array_as_root(const size_t _size) const noexcept {} - OutputObjectType object_as_root(const size_t _size) const noexcept { - const auto obj = yybson_mut_obj(doc_); - yybson_mut_doc_set_root(doc_, obj); - return OutputObjectType(obj); - } + // TODO + OutputObjectType object_as_root(const size_t _size) const noexcept {} - OutputVarType null_as_root() const noexcept { - const auto null = yybson_mut_null(doc_); - yybson_mut_doc_set_root(doc_, null); - return OutputVarType(null); - } + // TODO + OutputVarType null_as_root() const noexcept {} + // TODO template - OutputVarType value_as_root(const T& _var) const noexcept { - const auto val = from_basic_type(_var); - yybson_mut_doc_set_root(doc_, val.val_); - return OutputVarType(val); - } + OutputVarType value_as_root(const T& _var) const noexcept {} OutputArrayType add_array_to_array(const size_t _size, OutputArrayType* _parent) const noexcept { - const auto arr = yybson_mut_arr(doc_); - yybson_mut_arr_add_val(_parent->val_, arr); - return OutputArrayType(arr); + bson_array_builder_t* val; + bson_array_builder_append_array_builder_begin(_parent->val_, &val); + return OutputArrayType(val, _parent->val_); } OutputArrayType add_array_to_object( const std::string& _name, const size_t _size, OutputObjectType* _parent) const noexcept { - const auto arr = yybson_mut_arr(doc_); - yybson_mut_obj_add(_parent->val_, yybson_mut_strcpy(doc_, _name.c_str()), - arr); - return OutputArrayType(arr); + bson_array_builder_t* val; + bson_append_array_builder_begin(_parent->val_, _name.c_str(), + static_cast(_name.size()), &val); + return OutputArrayType(val, _parent->val_); } OutputObjectType add_object_to_array( const size_t _size, OutputArrayType* _parent) const noexcept { - const auto obj = yybson_mut_obj(doc_); - yybson_mut_arr_add_val(_parent->val_, obj); - return OutputObjectType(obj); + bson_t val; + bson_array_builder_append_document_begin(_parent->val_, &val); + return OutputObjectType(val, _parent->val_); } OutputObjectType add_object_to_object( const std::string& _name, const size_t _size, OutputObjectType* _parent) const noexcept { - const auto obj = yybson_mut_obj(doc_); - yybson_mut_obj_add(_parent->val_, yybson_mut_strcpy(doc_, _name.c_str()), - obj); - return OutputObjectType(obj); + bson_t val; + bson_append_document_begin(_parent->val_, _name.c_str(), + static_cast(_name.size()), &val); + return OutputObjectType(val, _parent->val_); } template OutputVarType add_value_to_array(const T& _var, OutputArrayType* _parent) const noexcept { - const auto val = from_basic_type(_var); - yybson_mut_arr_add_val(_parent->val_, val.val_); - return OutputVarType(val); + if constexpr (std::is_same, std::string>()) { + bson_array_builder_append_utf8(_parent->val_, _val.c_str(), + static_cast(_var.size())); + } else if constexpr (std::is_same, bool>()) { + bson_array_builder_append_bool(_parent->val_, _var); + } else if constexpr (std::is_floating_point>()) { + bson_array_builder_append_double(_parent->val_, + static_cast(_var)); + } else if constexpr (std::is_integral>()) { + bson_array_builder_append_int64(_parent->val_, + static_cast(_var)); + } else { + static_assert(rfl::always_false_v, "Unsupported type."); + } + return OutputVarType{}; } template OutputVarType add_value_to_object(const std::string& _name, const T& _var, OutputObjectType* _parent) const noexcept { - const auto val = from_basic_type(_var); - yybson_mut_obj_add(_parent->val_, yybson_mut_strcpy(doc_, _name.c_str()), - val.val_); - return OutputVarType(val); + if constexpr (std::is_same, std::string>()) { + bson_append_utf8(_parent->val_, _name.c_str(), + static_cast(_name.c_str()), _val.c_str(), + static_cast(_var.size())); + } else if constexpr (std::is_same, bool>()) { + bson_append_bool(_parent->val_, _name.c_str(), + static_cast(_name.c_str()), _var); + } else if constexpr (std::is_floating_point>()) { + bson_append_double(_parent->val_, _name.c_str(), + static_cast(_name.c_str()), + static_cast(_var)); + } else if constexpr (std::is_integral>()) { + bson_append_int64(_parent->val_, _name.c_str(), + static_cast(_name.c_str()), + static_cast(_var)); + } else { + static_assert(rfl::always_false_v, "Unsupported type."); + } + return OutputVarType{}; } OutputVarType add_null_to_array(OutputArrayType* _parent) const noexcept { - const auto null = yybson_mut_null(doc_); - yybson_mut_arr_add_val(_parent->val_, null); - return OutputVarType(null); + bson_array_builder_append_null(_parent->val_); + return OutputVarType{}; } OutputVarType add_null_to_object(const std::string& _name, OutputObjectType* _parent) const noexcept { - const auto null = yybson_mut_null(doc_); - yybson_mut_obj_add(_parent->val_, yybson_mut_strcpy(doc_, _name.c_str()), - null); - return OutputVarType(null); + bson_array_builder_append_null(_parent->val_, _name.c_str(), + static_cast(_name.c_str())); + return OutputVarType{}; } - void end_array(OutputArrayType* _arr) const noexcept {} - - void end_object(OutputObjectType* _obj) const noexcept {} + void end_array(OutputArrayType* _arr) const noexcept { + const auto handle = [&](const auto _parent) { + using Type = std::remove_cvref_t; + if constexpr (std::is_same()) { + bson_array_builder_append_array_builder_end(_parent, _arr->val_); + } else { + bson_append_array_end(_parent, _arr->val_); + } + }; + std::visit(handle, _arr->parent_); + } - private: - template - OutputVarType from_basic_type(const T& _var) const noexcept { - if constexpr (std::is_same, std::string>()) { - return OutputVarType(yybson_mut_strcpy(doc_, _var.c_str())); - } else if constexpr (std::is_same, bool>()) { - return OutputVarType(yybson_mut_bool(doc_, _var)); - } else if constexpr (std::is_floating_point>()) { - return OutputVarType(yybson_mut_real(doc_, static_cast(_var))); - } else if constexpr (std::is_integral>()) { - return OutputVarType(yybson_mut_int(doc_, static_cast(_var))); - } else { - static_assert(rfl::always_false_v, "Unsupported type."); - } + void end_object(OutputObjectType* _obj) const noexcept { + const auto handle = [&](const auto _parent) { + using Type = std::remove_cvref_t; + if constexpr (std::is_same()) { + bson_array_builder_append_document_end(_parent, _arr->val_); + } else { + bson_append_document_end(_parent, _arr->val_); + } + }; + std::visit(handle, _arr->parent_); } public: - bson_t b; + bson_t doc_; }; } // namespace bson