2024-06-05 19:04:53 -04:00
|
|
|
#ifndef RFL_CBOR_WRITE_HPP_
|
|
|
|
#define RFL_CBOR_WRITE_HPP_
|
|
|
|
|
|
|
|
#include <cbor.h>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <ostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
#include "../parsing/Parent.hpp"
|
|
|
|
#include "Parser.hpp"
|
|
|
|
|
|
|
|
namespace rfl {
|
2024-06-08 14:10:59 -04:00
|
|
|
namespace cbor {
|
|
|
|
|
|
|
|
template <class... Ps>
|
2024-06-08 15:53:06 -04:00
|
|
|
void write_into_buffer(
|
|
|
|
const auto& _obj,
|
|
|
|
CborEncoder* _encoder,
|
|
|
|
std::vector<char>* _buffer
|
|
|
|
) noexcept {
|
2024-06-08 14:10:59 -04:00
|
|
|
using T = std::remove_cvref_t<decltype(_obj)>;
|
|
|
|
using ParentType = parsing::Parent<Writer>;
|
2024-06-08 15:53:06 -04:00
|
|
|
cbor_encoder_init(
|
|
|
|
_encoder, reinterpret_cast<uint8_t*>(_buffer->data()),
|
|
|
|
_buffer->size(), 0
|
|
|
|
);
|
2024-06-08 14:10:59 -04:00
|
|
|
const auto writer = Writer(_encoder);
|
2024-06-08 15:53:06 -04:00
|
|
|
Parser<T, Processors<Ps...>>::write(
|
|
|
|
writer, _obj, typename ParentType::Root {}
|
|
|
|
);
|
2024-06-08 14:10:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns CBOR bytes.
|
|
|
|
template <class... Ps>
|
|
|
|
std::vector<char> write(const auto& _obj) noexcept {
|
|
|
|
std::vector<char> buffer(4096);
|
2024-06-08 15:53:06 -04:00
|
|
|
CborEncoder encoder;
|
2024-06-08 14:10:59 -04:00
|
|
|
write_into_buffer<Ps...>(_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<Ps...>(_obj, &encoder, &buffer);
|
|
|
|
}
|
|
|
|
const auto length = cbor_encoder_get_buffer_size(
|
2024-06-08 15:53:06 -04:00
|
|
|
&encoder, reinterpret_cast<uint8_t*>(buffer.data())
|
|
|
|
);
|
2024-06-08 14:10:59 -04:00
|
|
|
buffer.resize(length);
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Writes a CBOR into an ostream.
|
|
|
|
template <class... Ps>
|
|
|
|
std::ostream& write(const auto& _obj, std::ostream& _stream) noexcept {
|
|
|
|
auto buffer = write<Ps...>(_obj);
|
|
|
|
_stream.write(buffer.data(), buffer.size());
|
|
|
|
return _stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace cbor
|
|
|
|
} // namespace rfl
|
2024-06-05 19:04:53 -04:00
|
|
|
|
|
|
|
#endif
|