Skip to content

Commit

Permalink
Added the write function
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed Jan 21, 2024
1 parent cb11d71 commit a85ef66
Showing 1 changed file with 22 additions and 25 deletions.
47 changes: 22 additions & 25 deletions include/rfl/cbor/write.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#ifndef RFL_CBOR_WRITE_HPP_
#define RFL_CBOR_WRITE_HPP_

#include <bson/bson.h>
#include <cbor.h>

#include <cstdint>
#include <ostream>
#include <sstream>
#include <string>
Expand All @@ -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 <class T>
std::pair<uint8_t*, size_t> to_buffer(const T& _obj) noexcept {
void write_into_buffer(const T& _obj, CborEncoder* _encoder,
std::vector<char>* _buffer) noexcept {
using ParentType = parsing::Parent<Writer>;
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<T>::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<T>::write(writer, _obj, typename ParentType::Root{});
}

/// Returns CBOR bytes.
template <class T>
std::vector<char> write(const T& _obj) noexcept {
auto [buf, len] = to_buffer(_obj);
const auto result = std::vector<char>(reinterpret_cast<char*>(buf),
reinterpret_cast<char*>(buf) + len);
bson_free(buf);
return result;
std::vector<char> 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 <class T>
std::ostream& write(const T& _obj, std::ostream& _stream) noexcept {
auto [buf, len] = to_buffer(_obj);
_stream.write(reinterpret_cast<const char*>(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

0 comments on commit a85ef66

Please sign in to comment.