|
6 | 6 | #include <ostream>
|
7 | 7 | #include <sstream>
|
8 | 8 | #include <string>
|
| 9 | +#include <utility> |
9 | 10 |
|
10 | 11 | #include "../parsing/Parent.hpp"
|
11 | 12 | #include "Parser.hpp"
|
12 | 13 |
|
13 | 14 | namespace rfl {
|
14 | 15 | namespace bson {
|
15 | 16 |
|
16 |
| -/// Returns BSON bytes. |
| 17 | +/// Returns BSON bytes. Careful: It is the responsibility of the caller to call |
| 18 | +/// bson_free on the returned pointer. |
17 | 19 | template <class T>
|
18 |
| -std::vector<char> write(const T& _obj) { |
| 20 | +std::pair<uint8_t*, size_t> to_buffer(const T& _obj) noexcept { |
19 | 21 | using ParentType = parsing::Parent<Writer>;
|
20 |
| - bson_t* doc; |
| 22 | + bson_t* doc = nullptr; |
21 | 23 | uint8_t* buf = nullptr;
|
22 | 24 | size_t buflen = 0;
|
23 |
| - |
24 | 25 | bson_writer_t* bson_writer =
|
25 | 26 | bson_writer_new(&buf, &buflen, 0, bson_realloc_ctx, NULL);
|
26 |
| - |
27 | 27 | bson_writer_begin(bson_writer, &doc);
|
28 |
| - |
29 | 28 | const auto rfl_writer = Writer(doc);
|
30 |
| - |
31 | 29 | Parser<T>::write(rfl_writer, _obj, typename ParentType::Root{});
|
32 |
| - |
33 | 30 | bson_writer_end(bson_writer);
|
34 |
| - |
35 | 31 | const auto len = bson_writer_get_length(bson_writer);
|
36 |
| - |
37 | 32 | bson_writer_destroy(bson_writer);
|
| 33 | + return std::make_pair(buf, len); |
| 34 | +} |
38 | 35 |
|
| 36 | +/// Returns BSON bytes. |
| 37 | +template <class T> |
| 38 | +std::vector<char> write(const T& _obj) noexcept { |
| 39 | + auto [buf, len] = to_buffer(_obj); |
39 | 40 | const auto result = std::vector<char>(reinterpret_cast<char*>(buf),
|
40 | 41 | reinterpret_cast<char*>(buf) + len);
|
41 |
| - |
42 | 42 | bson_free(buf);
|
43 |
| - |
44 | 43 | return result;
|
45 | 44 | }
|
46 | 45 |
|
47 | 46 | /// Writes a BSON into an ostream.
|
48 | 47 | template <class T>
|
49 |
| -std::ostream& write(const T& _obj, std::ostream& _stream) { |
50 |
| - // TODO |
| 48 | +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); |
| 52 | + return _stream; |
51 | 53 | }
|
52 | 54 |
|
53 | 55 | } // namespace bson
|
|
0 commit comments