diff --git a/include/rfl/cbor/write.hpp b/include/rfl/cbor/write.hpp index d16e9399..b3048869 100644 --- a/include/rfl/cbor/write.hpp +++ b/include/rfl/cbor/write.hpp @@ -1,8 +1,9 @@ #ifndef RFL_CBOR_WRITE_HPP_ #define RFL_CBOR_WRITE_HPP_ -#include +#include +#include #include #include #include @@ -14,45 +15,41 @@ namespace rfl { namespace cbor { -/// Returns CBOR bytes. Careful: It is the responsibility of the caller to call -/// bson_free on the returned pointer. template -std::pair to_buffer(const T& _obj) noexcept { +void write_into_buffer(const T& _obj, CborEncoder* _encoder, + std::vector* _buffer) noexcept { using ParentType = parsing::Parent; - bson_t* doc = nullptr; - uint8_t* buf = nullptr; - size_t buflen = 0; - bson_writer_t* bson_writer = - bson_writer_new(&buf, &buflen, 0, bson_realloc_ctx, NULL); - bson_writer_begin(bson_writer, &doc); - const auto rfl_writer = Writer(doc); - Parser::write(rfl_writer, _obj, typename ParentType::Root{}); - bson_writer_end(bson_writer); - const auto len = bson_writer_get_length(bson_writer); - bson_writer_destroy(bson_writer); - return std::make_pair(buf, len); + cbor_encoder_init(_encoder, _buffer->data(), _buffer->size(), 0); + const auto writer = Writer(_encoder); + Parser::write(writer, _obj, typename ParentType::Root{}); } /// Returns CBOR bytes. template std::vector write(const T& _obj) noexcept { - auto [buf, len] = to_buffer(_obj); - const auto result = std::vector(reinterpret_cast(buf), - reinterpret_cast(buf) + len); - bson_free(buf); - return result; + std::vector buffer(128); + CborEncoder encoder; + write_into_buffer(_obj, &encoder, &buffer); + const auto total_bytes_needed = + buffer.size() + cbor_encoder_get_extra_bytes_needed(&encoder); + if (total_bytes_needed != buffer.size()) { + buffer.resize(total_bytes_needed); + write_into_buffer(_obj, &encoder, &buffer); + } + const auto length = cbor_encoder_get_buffer_size(&encoder); + buffer.resize(length); + return buffer; } /// Writes a CBOR into an ostream. template std::ostream& write(const T& _obj, std::ostream& _stream) noexcept { - auto [buf, len] = to_buffer(_obj); - _stream.write(reinterpret_cast(buf), len); - bson_free(buf); + auto buffer = write(_obj); + _stream.write(buffer.data(), buffer.size()); return _stream; } } // namespace cbor } // namespace rfl -#endif // CBOR_PARSER_HPP_ +#endif