Add support for parsing JSON into a FlatBufferBuilder
This lets us parse JSON into a sub-message as well, and create a size
prefixed flatbuffer.
Change-Id: I7a6301a74feab06e62686f28e87140b69065dd1f
diff --git a/aos/json_to_flatbuffer.cc b/aos/json_to_flatbuffer.cc
index 6508786..249a59e 100644
--- a/aos/json_to_flatbuffer.cc
+++ b/aos/json_to_flatbuffer.cc
@@ -120,25 +120,21 @@
// each message. Same goes for vectors.
class JsonParser {
public:
- JsonParser() { fbb_.ForceDefaults(1); }
+ JsonParser(flatbuffers::FlatBufferBuilder *fbb) : fbb_(fbb) {}
~JsonParser() {}
// Parses the json into a flatbuffer. Returns either an empty vector on
// error, or a vector with the flatbuffer data in it.
- flatbuffers::DetachedBuffer Parse(const std::string_view data,
- const flatbuffers::TypeTable *typetable) {
+ flatbuffers::Offset<flatbuffers::Table> Parse(
+ const std::string_view data, const flatbuffers::TypeTable *typetable) {
flatbuffers::uoffset_t end = 0;
bool result = DoParse(typetable, data, &end);
if (result) {
// On success, finish the table and build the vector.
- auto o = flatbuffers::Offset<flatbuffers::Table>(end);
- fbb_.Finish(o);
-
- return fbb_.Release();
+ return flatbuffers::Offset<flatbuffers::Table>(end);
} else {
- // Otherwise return an empty vector.
- return flatbuffers::DetachedBuffer();
+ return flatbuffers::Offset<flatbuffers::Table>(0);
}
}
@@ -170,7 +166,7 @@
bool PushElement(flatbuffers::ElementaryType elementary_type,
flatbuffers::Offset<flatbuffers::String> offset_value);
- flatbuffers::FlatBufferBuilder fbb_;
+ flatbuffers::FlatBufferBuilder *fbb_;
// This holds the state information that is needed as you recurse into
// nested structures.
@@ -254,7 +250,7 @@
} else {
// End of a nested struct! Add it.
const flatbuffers::uoffset_t end = WriteTable(
- stack_.back().typetable, stack_.back().elements, &fbb_);
+ stack_.back().typetable, stack_.back().elements, fbb_);
// We now want to talk about the parent structure. Pop the child.
stack_.pop_back();
@@ -453,9 +449,9 @@
}
if (in_vector()) {
- stack_.back().vector_elements.emplace_back(fbb_.CreateString(data));
+ stack_.back().vector_elements.emplace_back(fbb_->CreateString(data));
} else {
- stack_.back().elements.emplace_back(field_index, fbb_.CreateString(data));
+ stack_.back().elements.emplace_back(field_index, fbb_->CreateString(data));
}
return true;
}
@@ -631,7 +627,7 @@
static_cast<flatbuffers::ElementaryType>(type_code.base_type);
// Vectors have a start (unfortunately which needs to know the size)
- fbb_.StartVector(
+ fbb_->StartVector(
stack_.back().vector_elements.size(),
flatbuffers::InlineSize(elementary_type, stack_.back().typetable));
@@ -656,7 +652,7 @@
// Then an End which is placed into the buffer the same as any other offset.
stack_.back().elements.emplace_back(
field_index, flatbuffers::Offset<flatbuffers::String>(
- fbb_.EndVector(stack_.back().vector_elements.size())));
+ fbb_->EndVector(stack_.back().vector_elements.size())));
stack_.back().vector_elements.clear();
return true;
}
@@ -665,37 +661,37 @@
int64_t int_value) {
switch (elementary_type) {
case flatbuffers::ET_BOOL:
- fbb_.PushElement<bool>(int_value);
+ fbb_->PushElement<bool>(int_value);
return true;
case flatbuffers::ET_CHAR:
- fbb_.PushElement<int8_t>(int_value);
+ fbb_->PushElement<int8_t>(int_value);
return true;
case flatbuffers::ET_UCHAR:
- fbb_.PushElement<uint8_t>(int_value);
+ fbb_->PushElement<uint8_t>(int_value);
return true;
case flatbuffers::ET_SHORT:
- fbb_.PushElement<int16_t>(int_value);
+ fbb_->PushElement<int16_t>(int_value);
return true;
case flatbuffers::ET_USHORT:
- fbb_.PushElement<uint16_t>(int_value);
+ fbb_->PushElement<uint16_t>(int_value);
return true;
case flatbuffers::ET_INT:
- fbb_.PushElement<int32_t>(int_value);
+ fbb_->PushElement<int32_t>(int_value);
return true;
case flatbuffers::ET_UINT:
- fbb_.PushElement<uint32_t>(int_value);
+ fbb_->PushElement<uint32_t>(int_value);
return true;
case flatbuffers::ET_LONG:
- fbb_.PushElement<int64_t>(int_value);
+ fbb_->PushElement<int64_t>(int_value);
return true;
case flatbuffers::ET_ULONG:
- fbb_.PushElement<uint64_t>(int_value);
+ fbb_->PushElement<uint64_t>(int_value);
return true;
case flatbuffers::ET_FLOAT:
- fbb_.PushElement<float>(int_value);
+ fbb_->PushElement<float>(int_value);
return true;
case flatbuffers::ET_DOUBLE:
- fbb_.PushElement<double>(int_value);
+ fbb_->PushElement<double>(int_value);
return true;
case flatbuffers::ET_STRING:
case flatbuffers::ET_UTYPE:
@@ -730,10 +726,10 @@
ElementaryTypeName(elementary_type));
return false;
case flatbuffers::ET_FLOAT:
- fbb_.PushElement<float>(double_value);
+ fbb_->PushElement<float>(double_value);
return true;
case flatbuffers::ET_DOUBLE:
- fbb_.PushElement<double>(double_value);
+ fbb_->PushElement<double>(double_value);
return true;
}
return false;
@@ -762,7 +758,7 @@
return false;
case flatbuffers::ET_STRING:
case flatbuffers::ET_SEQUENCE:
- fbb_.PushElement(offset_value);
+ fbb_->PushElement(offset_value);
return true;
}
return false;
@@ -770,11 +766,29 @@
} // namespace
+flatbuffers::Offset<flatbuffers::Table> JsonToFlatbuffer(
+ const std::string_view data, const flatbuffers::TypeTable *typetable,
+ flatbuffers::FlatBufferBuilder *fbb) {
+ JsonParser p(fbb);
+ return p.Parse(data, typetable);
+}
+
flatbuffers::DetachedBuffer JsonToFlatbuffer(
const std::string_view data,
const flatbuffers::TypeTable *typetable) {
- JsonParser p;
- return p.Parse(data, typetable);
+ flatbuffers::FlatBufferBuilder fbb;
+ fbb.ForceDefaults(1);
+
+ const flatbuffers::Offset<flatbuffers::Table> result =
+ JsonToFlatbuffer(data, typetable, &fbb);
+ if (result.o != 0) {
+ fbb.Finish(result);
+
+ return fbb.Release();
+ } else {
+ // Otherwise return an empty vector.
+ return flatbuffers::DetachedBuffer();
+ }
}
::std::string BufferFlatbufferToJson(const uint8_t *buffer,