Add a Flatbuffers containing object, and more variants

We now have DetachedBuffers which represent flatbuffers, the new
Flatbuffer object, and Table objects.  It should be easy to merge and
copy these various objects now.  (And print).

Change-Id: Ie8fcff1e97f0ae5a7ef8a3becb1be467010460dc
diff --git a/aos/flatbuffer_merge.h b/aos/flatbuffer_merge.h
index c63b143..16372ed 100644
--- a/aos/flatbuffer_merge.h
+++ b/aos/flatbuffer_merge.h
@@ -4,20 +4,73 @@
 #include <cstddef>
 #include <string>
 
+#include "aos/flatbuffers.h"
 #include "flatbuffers/flatbuffers.h"
 
 namespace aos {
 
-::std::vector<uint8_t> MergeFlatBuffers(const flatbuffers::TypeTable *typetable,
-                                        const uint8_t *data1,
-                                        const uint8_t *data2);
+flatbuffers::DetachedBuffer MergeFlatBuffers(
+    const flatbuffers::TypeTable *typetable, const uint8_t *data1,
+    const uint8_t *data2);
+
+// Merges 2 flat buffers with the provided type table into the builder.  Returns
+// the offset to the flatbuffers.
+// One or both of t1 and t2 must be non-null.  If one is null, this method
+// coppies instead of merging.
+flatbuffers::Offset<flatbuffers::Table> MergeFlatBuffers(
+    const flatbuffers::TypeTable *typetable, const flatbuffers::Table *t1,
+    const flatbuffers::Table *t2, flatbuffers::FlatBufferBuilder *fbb);
 
 template <class T>
-::std::vector<uint8_t> MergeFlatBuffers(const uint8_t *data1,
-                                        const uint8_t *data2) {
+inline flatbuffers::Offset<T> MergeFlatBuffers(
+    const flatbuffers::Table *t1,
+    const flatbuffers::Table *t2, flatbuffers::FlatBufferBuilder *fbb) {
+  return MergeFlatBuffers(T::MiniReflectTypeTable(), t1, t2, fbb).o;
+}
+
+template <class T>
+inline flatbuffers::DetachedBuffer MergeFlatBuffers(const uint8_t *data1,
+                                                    const uint8_t *data2) {
   return MergeFlatBuffers(T::MiniReflectTypeTable(), data1, data2);
 }
 
+template <class T>
+inline flatbuffers::DetachedBuffer MergeFlatBuffers(
+    const flatbuffers::DetachedBuffer &data1,
+    const flatbuffers::DetachedBuffer &data2) {
+  return MergeFlatBuffers(T::MiniReflectTypeTable(), data1.data(),
+                          data2.data());
+}
+
+template <class T>
+inline aos::Flatbuffer<T> MergeFlatBuffers(const aos::Flatbuffer<T> &fb1,
+                                           const aos::Flatbuffer<T> &fb2) {
+  return aos::Flatbuffer<T>(
+      MergeFlatBuffers(T::MiniReflectTypeTable(), fb1.data(), fb2.data()));
+}
+
+template <class T>
+inline aos::Flatbuffer<T> MergeFlatBuffers(const T *fb1, const T *fb2) {
+  return aos::Flatbuffer<T>(MergeFlatBuffers(
+      T::MiniReflectTypeTable(), reinterpret_cast<const uint8_t *>(fb1),
+      reinterpret_cast<const uint8_t *>(fb2)));
+}
+
+template <class T>
+inline flatbuffers::Offset<T> CopyFlatBuffer(
+    const T *t1, flatbuffers::FlatBufferBuilder *fbb) {
+  return MergeFlatBuffers<T>(reinterpret_cast<const flatbuffers::Table *>(t1),
+                             nullptr, fbb);
+}
+
+template <class T>
+inline Flatbuffer<T> CopyFlatBuffer(const T *t) {
+  flatbuffers::FlatBufferBuilder fbb;
+  fbb.ForceDefaults(1);
+  fbb.Finish(CopyFlatBuffer<T>(t, &fbb));
+  return Flatbuffer<T>(fbb.Release());
+}
+
 }  // namespace aos
 
 #endif  // AOS_FLATBUFFER_MERGE_H_