Copy flatbuffers efficiently and respecting DAGs.

Deduce the memory region needed to be copied by traversing the DAG, and
then copy it.  This has no mallocs (yay!), and works with DAGs.

There are some cases where we actually want to copy things recursively.
Do that when asked.

Change-Id: Ia0ffde26d569fa92ee2bbb49706c17d9d657d125
diff --git a/aos/network/message_bridge_protocol.cc b/aos/network/message_bridge_protocol.cc
index 0a4a50e..8936da8 100644
--- a/aos/network/message_bridge_protocol.cc
+++ b/aos/network/message_bridge_protocol.cc
@@ -19,7 +19,8 @@
   flatbuffers::FlatBufferBuilder fbb;
   fbb.ForceDefaults(true);
 
-  flatbuffers::Offset<Node> node_offset = CopyFlatBuffer<Node>(my_node, &fbb);
+  flatbuffers::Offset<Node> node_offset =
+      RecursiveCopyFlatBuffer<Node>(my_node, &fbb);
   const std::string_view node_name = my_node->name()->string_view();
 
   std::vector<flatbuffers::Offset<Channel>> channel_offsets;
@@ -30,7 +31,7 @@
             channel->source_node()->string_view() == remote_name) {
           // Remove the schema to save some space on the wire.
           aos::FlatbufferDetachedBuffer<Channel> cleaned_channel =
-              CopyFlatBuffer<Channel>(channel);
+              RecursiveCopyFlatBuffer<Channel>(channel);
           cleaned_channel.mutable_message()->clear_schema();
           channel_offsets.emplace_back(
               CopyFlatBuffer<Channel>(&cleaned_channel.message(), &fbb));