|
1 | 1 | #ifndef RFL_CBOR_WRITE_HPP_
|
2 | 2 | #define RFL_CBOR_WRITE_HPP_
|
3 | 3 |
|
4 |
| -#include <bson/bson.h> |
| 4 | +#include <cbor.h> |
5 | 5 |
|
| 6 | +#include <cstdint> |
6 | 7 | #include <ostream>
|
7 | 8 | #include <sstream>
|
8 | 9 | #include <string>
|
|
14 | 15 | namespace rfl {
|
15 | 16 | namespace cbor {
|
16 | 17 |
|
17 |
| -/// Returns CBOR bytes. Careful: It is the responsibility of the caller to call |
18 |
| -/// bson_free on the returned pointer. |
19 | 18 | template <class T>
|
20 |
| -std::pair<uint8_t*, size_t> to_buffer(const T& _obj) noexcept { |
| 19 | +void write_into_buffer(const T& _obj, CborEncoder* _encoder, |
| 20 | + std::vector<char>* _buffer) noexcept { |
21 | 21 | using ParentType = parsing::Parent<Writer>;
|
22 |
| - bson_t* doc = nullptr; |
23 |
| - uint8_t* buf = nullptr; |
24 |
| - size_t buflen = 0; |
25 |
| - bson_writer_t* bson_writer = |
26 |
| - bson_writer_new(&buf, &buflen, 0, bson_realloc_ctx, NULL); |
27 |
| - bson_writer_begin(bson_writer, &doc); |
28 |
| - const auto rfl_writer = Writer(doc); |
29 |
| - Parser<T>::write(rfl_writer, _obj, typename ParentType::Root{}); |
30 |
| - bson_writer_end(bson_writer); |
31 |
| - const auto len = bson_writer_get_length(bson_writer); |
32 |
| - bson_writer_destroy(bson_writer); |
33 |
| - return std::make_pair(buf, len); |
| 22 | + cbor_encoder_init(_encoder, _buffer->data(), _buffer->size(), 0); |
| 23 | + const auto writer = Writer(_encoder); |
| 24 | + Parser<T>::write(writer, _obj, typename ParentType::Root{}); |
34 | 25 | }
|
35 | 26 |
|
36 | 27 | /// Returns CBOR bytes.
|
37 | 28 | template <class T>
|
38 | 29 | std::vector<char> write(const T& _obj) noexcept {
|
39 |
| - auto [buf, len] = to_buffer(_obj); |
40 |
| - const auto result = std::vector<char>(reinterpret_cast<char*>(buf), |
41 |
| - reinterpret_cast<char*>(buf) + len); |
42 |
| - bson_free(buf); |
43 |
| - return result; |
| 30 | + std::vector<char> buffer(128); |
| 31 | + CborEncoder encoder; |
| 32 | + write_into_buffer(_obj, &encoder, &buffer); |
| 33 | + const auto total_bytes_needed = |
| 34 | + buffer.size() + cbor_encoder_get_extra_bytes_needed(&encoder); |
| 35 | + if (total_bytes_needed != buffer.size()) { |
| 36 | + buffer.resize(total_bytes_needed); |
| 37 | + write_into_buffer(_obj, &encoder, &buffer); |
| 38 | + } |
| 39 | + const auto length = cbor_encoder_get_buffer_size(&encoder); |
| 40 | + buffer.resize(length); |
| 41 | + return buffer; |
44 | 42 | }
|
45 | 43 |
|
46 | 44 | /// Writes a CBOR into an ostream.
|
47 | 45 | template <class T>
|
48 | 46 | std::ostream& write(const T& _obj, std::ostream& _stream) noexcept {
|
49 |
| - auto [buf, len] = to_buffer(_obj); |
50 |
| - _stream.write(reinterpret_cast<const char*>(buf), len); |
51 |
| - bson_free(buf); |
| 47 | + auto buffer = write(_obj); |
| 48 | + _stream.write(buffer.data(), buffer.size()); |
52 | 49 | return _stream;
|
53 | 50 | }
|
54 | 51 |
|
55 | 52 | } // namespace cbor
|
56 | 53 | } // namespace rfl
|
57 | 54 |
|
58 |
| -#endif // CBOR_PARSER_HPP_ |
| 55 | +#endif |
0 commit comments