add support for replaying log messages

For example, this allows reproducing logged but hard to physically
reproduce problems to control loops with more logging to help debug the
problem, and then verifying that it does something different under the
same conditions.

Change-Id: I1e55e7a7c0b3154bcaf86373a9e6c57c594310a0
diff --git a/aos/linux_code/logging/log_replay.cc b/aos/linux_code/logging/log_replay.cc
new file mode 100644
index 0000000..32991de
--- /dev/null
+++ b/aos/linux_code/logging/log_replay.cc
@@ -0,0 +1,44 @@
+#include "aos/linux_code/logging/log_replay.h"
+
+namespace aos {
+namespace logging {
+namespace linux_code {
+
+bool LogReplayer::ProcessMessage() {
+  const LogFileMessageHeader *message = reader_->ReadNextMessage(false);
+  if (message == nullptr) return true;
+  if (message->type != LogFileMessageHeader::MessageType::kStruct) return false;
+
+  const char *position = reinterpret_cast<const char *>(message + 1);
+
+  ::std::string process(position, message->name_size);
+  position += message->name_size;
+
+  uint32_t type_id;
+  memcpy(&type_id, position, sizeof(type_id));
+  position += sizeof(type_id);
+
+  uint32_t message_length;
+  memcpy(&message_length, position, sizeof(message_length));
+  position += sizeof(message_length);
+  ::std::string message_text(position, message_length);
+  position += message_length;
+
+  size_t split_index = message_text.find_first_of(':') + 2;
+  split_index = message_text.find_first_of(':', split_index) + 2;
+  message_text = message_text.substr(split_index);
+
+  auto handler = handlers_.find(Key(process, message_text));
+  if (handler == handlers_.end()) return false;
+
+  handler->second->HandleStruct(
+      ::aos::time::Time(message->time_sec, message->time_nsec), type_id,
+      position,
+      message->message_size -
+          (sizeof(type_id) + sizeof(message_length) + message_length));
+  return false;
+}
+
+}  // namespace linux_code
+}  // namespace logging
+}  // namespace aos