MMapping for flatbuffers

This lets us lazily load flatbuffers using mmap to both reduce memory
usage and to increase speed for use cases where we don't need to access
everything.

Change-Id: Ia271350b4c7cbb7a0a86ca094ef69c34716ba754
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/util/file.cc b/aos/util/file.cc
index 4473d4d..cec5a6e 100644
--- a/aos/util/file.cc
+++ b/aos/util/file.cc
@@ -2,6 +2,7 @@
 
 #include <fcntl.h>
 #include <fts.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -151,5 +152,24 @@
   }
 }
 
+std::shared_ptr<absl::Span<uint8_t>> MMapFile(const std::string &path) {
+  int fd = open(path.c_str(), O_RDONLY);
+  PCHECK(fd != -1) << "Unable to open file " << path;
+  struct stat sb;
+  PCHECK(fstat(fd, &sb) != -1) << ": Unable to get file size of " << path;
+  uint8_t *start = reinterpret_cast<uint8_t *>(
+      mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
+  CHECK(start != MAP_FAILED) << ": Unable to open mapping to file " << path;
+  std::shared_ptr<absl::Span<uint8_t>> span =
+      std::shared_ptr<absl::Span<uint8_t>>(
+          new absl::Span<uint8_t>(start, sb.st_size),
+          [](absl::Span<uint8_t> *span) {
+            PCHECK(munmap(span->data(), span->size()) != -1);
+            delete span;
+          });
+  close(fd);
+  return span;
+}
+
 }  // namespace util
 }  // namespace aos