Fix AOS logging when using non-EventLoop configuration

Fixed crash in aos::Logger when reading back a log that was made
by providing a different configuration to the Logger than was
used by the event loop.

Change event_loop_to_logged_channel_index_ to use
`std::optional<uint32_t>` instead of `int`. Channel indices
should be uint32_t. Changed to optional because the channel can
be missing from the configuration specified in the logger
Constructor.

Change-Id: I5203b390689cab27cd79ee35b029cfdd0f98dfd8
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/configuration.cc b/aos/configuration.cc
index 6cae0d4..4de5332 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -1729,5 +1729,39 @@
   return MergeWithConfig(config, new_channel_config);
 }
 
+FlatbufferDetachedBuffer<Configuration> GetPartialConfiguration(
+    const Configuration &configuration,
+    std::function<bool(const Channel &)> should_include_channel) {
+  // create new_configuration1, containing everything except the `channels`
+  // field.
+  FlatbufferDetachedBuffer<Configuration> new_configuration1 =
+      RecursiveCopyFlatBuffer(&configuration);
+  new_configuration1.mutable_message()->clear_channels();
+
+  // create new_configuration2, containing only the `channels` field.
+  flatbuffers::FlatBufferBuilder fbb;
+  std::vector<flatbuffers::Offset<Channel>> new_channels_vec;
+  for (const auto &channel : *configuration.channels()) {
+    CHECK_NOTNULL(channel);
+    if (should_include_channel(*channel)) {
+      new_channels_vec.push_back(RecursiveCopyFlatBuffer(channel, &fbb));
+    }
+  }
+  flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Channel>>>
+      new_channels_offset = fbb.CreateVector(new_channels_vec);
+  Configuration::Builder new_configuration2_builder(fbb);
+  new_configuration2_builder.add_channels(new_channels_offset);
+  fbb.Finish(new_configuration2_builder.Finish());
+  FlatbufferDetachedBuffer<Configuration> new_configuration2 = fbb.Release();
+
+  // Merge the configuration containing channels with the configuration
+  // containing everything else, creating a complete configuration.
+  const aos::FlatbufferDetachedBuffer<Configuration> raw_subset_configuration =
+      MergeFlatBuffers(&new_configuration1.message(),
+                       &new_configuration2.message());
+
+  // Use MergeConfiguration to clean up redundant schemas.
+  return configuration::MergeConfiguration(raw_subset_configuration);
+}
 }  // namespace configuration
 }  // namespace aos