Add CompareFlatBuffer method
We are using the simplest possible version of this, which is to copy the
two flatbuffers and see if the resulting memory matches. That should be
determistic between the two, so the exact resulting layout should match.
Change-Id: I5f9b553631cd13bfe93b5f3738d9b0659a7d993b
diff --git a/aos/flatbuffer_merge.cc b/aos/flatbuffer_merge.cc
index c8cc742..1f5c8a0 100644
--- a/aos/flatbuffer_merge.cc
+++ b/aos/flatbuffer_merge.cc
@@ -526,4 +526,27 @@
return fbb.Release();
}
+bool CompareFlatBuffer(const flatbuffers::TypeTable *typetable,
+ const flatbuffers::Table *t1,
+ const flatbuffers::Table *t2) {
+ // Copying flatbuffers is deterministic for the same typetable. So, copy both
+ // to guarantee that they are sorted the same, then check that the memory
+ // matches.
+ //
+ // There has to be a better way to do this, but the efficiency hit of this
+ // implementation is fine for the usages that we have now. We are better off
+ // abstracting this into a library call where we can fix it later easily.
+ flatbuffers::FlatBufferBuilder fbb1;
+ fbb1.ForceDefaults(1);
+ fbb1.Finish(MergeFlatBuffers(typetable, t1, nullptr, &fbb1));
+ flatbuffers::FlatBufferBuilder fbb2;
+ fbb2.ForceDefaults(1);
+ fbb2.Finish(MergeFlatBuffers(typetable, t2, nullptr, &fbb2));
+
+ if (fbb1.GetSize() != fbb2.GetSize()) return false;
+
+ return memcmp(fbb1.GetBufferPointer(), fbb2.GetBufferPointer(),
+ fbb1.GetSize()) == 0;
+}
+
} // namespace aos
diff --git a/aos/flatbuffer_merge.h b/aos/flatbuffer_merge.h
index dafba34..5e84160 100644
--- a/aos/flatbuffer_merge.h
+++ b/aos/flatbuffer_merge.h
@@ -77,6 +77,18 @@
return FlatbufferDetachedBuffer<T>(fbb.Release());
}
+// Compares 2 flatbuffers. Returns true if they match, false otherwise.
+bool CompareFlatBuffer(const flatbuffers::TypeTable *typetable,
+ const flatbuffers::Table *t1,
+ const flatbuffers::Table *t2);
+
+template <class T>
+inline bool CompareFlatBuffer(const T *t1, const T *t2) {
+ return CompareFlatBuffer(T::MiniReflectTypeTable(),
+ reinterpret_cast<const flatbuffers::Table *>(t1),
+ reinterpret_cast<const flatbuffers::Table *>(t2));
+}
+
} // namespace aos
#endif // AOS_FLATBUFFER_MERGE_H_
diff --git a/aos/flatbuffer_merge_test.cc b/aos/flatbuffer_merge_test.cc
index 079eb11..371639a 100644
--- a/aos/flatbuffer_merge_test.cc
+++ b/aos/flatbuffer_merge_test.cc
@@ -20,6 +20,13 @@
const ::std::string merged_output =
FlatbufferToJson(fb_merged, ConfigurationTypeTable());
EXPECT_EQ(expected_output, merged_output);
+
+ aos::FlatbufferDetachedBuffer<Configuration> expected_message(
+ JsonToFlatbuffer(std::string(expected_output).c_str(),
+ ConfigurationTypeTable()));
+ EXPECT_TRUE(
+ CompareFlatBuffer(flatbuffers::GetRoot<Configuration>(fb_merged.data()),
+ &expected_message.message()));
}
void JsonMerge(const ::std::string in1, const ::std::string in2,
@@ -335,6 +342,18 @@
"\"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }");
}
+// Tests a compare of 2 basic (different) messages.
+TEST_F(FlatbufferMerge, CompareDifferent) {
+ aos::FlatbufferDetachedBuffer<Configuration> message1(JsonToFlatbuffer(
+ "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
+ ConfigurationTypeTable()));
+ aos::FlatbufferDetachedBuffer<Configuration> message2(JsonToFlatbuffer(
+ "{ \"single_application\": { \"name\": \"wow\", \"priority\": 8 } }",
+ ConfigurationTypeTable()));
+
+ EXPECT_FALSE(CompareFlatBuffer(&message1.message(), &message2.message()));
+}
+
// TODO(austin): enums
// TODO(austin): unions
// TODO(austin): struct