Created
March 22, 2017 20:57
-
-
Save mavam/6aae479c66d0e93666c315e26935a7df to your computer and use it in GitHub Desktop.
A function that takes a discriminated union and writes it into a flatbuffers builder.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
flexbuffers::Builder& build(flexBuffers::Builder& builder, const data& x) { | |
struct converter { | |
converter(flatbuffers::FlatBufferBuilder& builder) : builder_{builder} { | |
} | |
using result_type = flatbuffers::Offset<detail::Data>; | |
result_type operator()(none) { | |
detail::DataBuilder db{builder_}; | |
return db.Finish(); | |
} | |
result_type operator()(boolean x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::BooleanType); | |
db.add_integer(x ? 1 : 0); | |
return db.Finish(); | |
} | |
result_type operator()(integer x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::IntegerType); | |
db.add_integer(x); | |
return db.Finish(); | |
} | |
result_type operator()(count x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::CountType); | |
db.add_count(x); | |
return db.Finish(); | |
} | |
result_type operator()(real x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::RealType); | |
db.add_real(x); | |
return db.Finish(); | |
} | |
result_type operator()(timestamp x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::TimestampType); | |
db.add_integer(x.time_since_epoch().count()); | |
return db.Finish(); | |
} | |
result_type operator()(timespan x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::TimespanType); | |
db.add_integer(x.count()); | |
return db.Finish(); | |
} | |
result_type operator()(const enumeration& x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::EnumerationType); | |
db.add_integer(x); | |
return db.Finish(); | |
} | |
result_type operator()(const std::string& x) { | |
auto ptr = reinterpret_cast<const uint8_t*>(x.data()); | |
auto bytes = builder_.CreateVector<uint8_t>(ptr, x.size()); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::StringType); | |
db.add_bytes(bytes); | |
return db.Finish(); | |
} | |
result_type operator()(const pattern& x) { | |
auto ptr = reinterpret_cast<const uint8_t*>(x.string().data()); | |
auto bytes = builder_.CreateVector<uint8_t>(ptr, x.string().size()); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::PatternType); | |
db.add_bytes(bytes); | |
return db.Finish(); | |
} | |
result_type operator()(const address& x) { | |
if (x.is_v4()) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::AddressType); | |
db.add_count(*reinterpret_cast<const count*>(x.data().data() + 12)); | |
return db.Finish(); | |
} else { | |
auto bytes = builder_.CreateVector<uint8_t>(x.data().data(), 16); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::AddressType); | |
db.add_bytes(bytes); | |
return db.Finish(); | |
} | |
} | |
result_type operator()(const subnet& x) { | |
if (x.network().is_v4()) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::AddressType); | |
auto ptr = x.network().data().data() + 12; | |
db.add_count(*reinterpret_cast<const count*>(ptr)); | |
db.add_integer(static_cast<integer>(x.length())); | |
return db.Finish(); | |
} else { | |
auto ptr = x.network().data().data(); | |
auto bytes = builder_.CreateVector<uint8_t>(ptr, 16); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::AddressType); | |
db.add_bytes(bytes); | |
db.add_integer(static_cast<integer>(x.length())); | |
return db.Finish(); | |
} | |
} | |
result_type operator()(const port& x) { | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::PortType); | |
db.add_integer(static_cast<integer>(x.type())); | |
db.add_count(static_cast<count>(x.number())); | |
return db.Finish(); | |
} | |
result_type operator()(const vector& xs) { | |
std::vector<flatbuffers::Offset<detail::Data>> offsets; | |
offsets.reserve(xs.size()); | |
std::transform(xs.begin(), xs.end(), std::back_inserter(offsets), | |
[&](auto& x) { return visit(*this, x); }); | |
auto v = builder_.CreateVector(offsets); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::VectorType); | |
db.add_vector(v); | |
return db.Finish(); | |
} | |
result_type operator()(const set& xs) { | |
std::vector<flatbuffers::Offset<detail::Data>> offsets; | |
offsets.reserve(xs.size()); | |
std::transform(xs.begin(), xs.end(), std::back_inserter(offsets), | |
[&](auto& x) { return visit(*this, x); }); | |
auto v = builder_.CreateVector(offsets); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::SetType); | |
db.add_vector(v); | |
return db.Finish(); | |
} | |
result_type operator()(const table& xs) { | |
std::vector<flatbuffers::Offset<detail::Data>> offsets; | |
offsets.reserve(xs.size() * 2); | |
for (auto& x : xs) { | |
offsets.push_back(visit(*this, x.first)); | |
offsets.push_back(visit(*this, x.second)); | |
}; | |
auto v = builder_.CreateVector(offsets); | |
detail::DataBuilder db{builder_}; | |
db.add_which(detail::DataType::MapType); | |
db.add_vector(v); | |
return db.Finish(); | |
} | |
flatbuffers::FlatBufferBuilder& builder_; | |
}; | |
return visit(converter{builder}, x); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment