Skip to content

Commit

Permalink
Better solution for the writer
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed Jan 16, 2024
1 parent 661dced commit bbf7a66
Showing 1 changed file with 30 additions and 22 deletions.
52 changes: 30 additions & 22 deletions include/rfl/bson/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ namespace bson {

/// Please refer to https://mongoc.org/libbson/current/api.html
class Writer {
struct BSONType {
bson_t val_;
};

struct IsArray {
bson_array_builder_t* ptr_;
};
Expand All @@ -43,10 +47,10 @@ class Writer {
};

struct BSONOutputObject {
BSONOutputObject(bson_t _val, ParentType _parent)
BSONOutputObject(bson_t* _val, ParentType _parent)
: parent_(_parent), val_(_val) {}
ParentType parent_;
bson_t val_;
bson_t* val_;
};

struct BSONOutputVar {};
Expand All @@ -65,9 +69,7 @@ class Writer {
}

OutputObjectType object_as_root(const size_t _size) const noexcept {
bson_t val;
bson_init(&val);
return OutputObjectType(val, IsRoot{});
return OutputObjectType(doc_, IsRoot{});
}

OutputVarType null_as_root() const noexcept {
Expand All @@ -93,25 +95,27 @@ class Writer {
const std::string& _name, const size_t _size,
OutputObjectType* _parent) const noexcept {
bson_array_builder_t* val;
bson_append_array_builder_begin(&(_parent->val_), _name.c_str(),
bson_append_array_builder_begin(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()), &val);
return OutputArrayType(val, IsObject{&(_parent->val_)});
return OutputArrayType(val, IsObject{_parent->val_});
}

OutputObjectType add_object_to_array(
const size_t _size, OutputArrayType* _parent) const noexcept {
bson_t val;
bson_array_builder_append_document_begin(_parent->val_, &val);
return OutputObjectType(val, IsArray{_parent->val_});
subdocs_->push_back(BSONType{});
bson_array_builder_append_document_begin(_parent->val_,
&subdocs_->back().val_);
return OutputObjectType(&subdocs_->back().val_, IsArray{_parent->val_});
}

OutputObjectType add_object_to_object(
const std::string& _name, const size_t _size,
OutputObjectType* _parent) const noexcept {
bson_t val;
bson_append_document_begin(&(_parent->val_), _name.c_str(),
static_cast<int>(_name.size()), &val);
return OutputObjectType(val, IsObject{&(_parent->val_)});
subdocs_->push_back(BSONType{});
bson_append_document_begin(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()),
&subdocs_->back().val_);
return OutputObjectType(&subdocs_->back().val_, IsObject{_parent->val_});
}

template <class T>
Expand All @@ -138,18 +142,18 @@ class Writer {
OutputVarType add_value_to_object(const std::string& _name, const T& _var,
OutputObjectType* _parent) const noexcept {
if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
bson_append_utf8(&(_parent->val_), _name.c_str(),
bson_append_utf8(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()), _var.c_str(),
static_cast<int>(_var.size()));
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
bson_append_bool(&(_parent->val_), _name.c_str(),
bson_append_bool(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()), _var);
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
bson_append_double(&(_parent->val_), _name.c_str(),
bson_append_double(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()),
static_cast<double>(_var));
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
bson_append_int64(&(_parent->val_), _name.c_str(),
bson_append_int64(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()),
static_cast<std::int32_t>(_var));
} else {
Expand All @@ -165,7 +169,7 @@ class Writer {

OutputVarType add_null_to_object(const std::string& _name,
OutputObjectType* _parent) const noexcept {
bson_append_null(&(_parent->val_), _name.c_str(),
bson_append_null(_parent->val_, _name.c_str(),
static_cast<int>(_name.size()));
return OutputVarType{};
}
Expand All @@ -190,11 +194,10 @@ class Writer {
const auto handle = [&](const auto _parent) {
using Type = std::remove_cvref_t<decltype(_parent)>;
if constexpr (std::is_same<Type, IsArray>()) {
bson_array_builder_append_document_end(_parent.ptr_, &(_obj->val_));
bson_array_builder_append_document_end(_parent.ptr_, _obj->val_);
} else if constexpr (std::is_same<Type, IsObject>()) {
bson_append_document_end(_parent.ptr_, &(_obj->val_));
bson_append_document_end(_parent.ptr_, _obj->val_);
} else if constexpr (std::is_same<Type, IsRoot>()) {
*doc_ = _obj->val_;
} else {
static_assert(rfl::always_false_v<Type>, "Unsupported type.");
}
Expand All @@ -203,7 +206,12 @@ class Writer {
}

private:
/// Pointer to the main document. In BSON, documents are what are usually
/// called objects.
bson_t* const doc_;

/// Contain all of the subdocuments.
const rfl::Ref<std::vector<BSONType>> subdocs_;
};

} // namespace bson
Expand Down

0 comments on commit bbf7a66

Please sign in to comment.