Add malloc-free file contents reader
If you have a file that can be read safely in realtime code, this
provides a convenient wrapper for grabbing the entire contents of
said file. This should also just be a bit faster than
ReadFileToStringOrDie just by virtue of avoiding all the malloc's in
std::string and not having to re-open the file.
Change-Id: I90a3fa9433ac3a8773027327bde245ebf0c13b10
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/util/file.h b/aos/util/file.h
index 2d37ec2..d2fb9fa 100644
--- a/aos/util/file.h
+++ b/aos/util/file.h
@@ -1,13 +1,17 @@
#ifndef AOS_UTIL_FILE_H_
#define AOS_UTIL_FILE_H_
+#include <fcntl.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <memory>
#include <string>
#include <string_view>
+#include "absl/strings/numbers.h"
#include "absl/types/span.h"
+#include "aos/scoped/scoped_fd.h"
#include "glog/logging.h"
namespace aos {
@@ -41,6 +45,41 @@
std::shared_ptr<absl::Span<uint8_t>> MMapFile(
const std::string &path, FileOptions options = FileOptions::kReadable);
+// Wrapper to handle reading the contents of a file into a buffer. Meant for
+// situations where the malloc'ing of ReadFileToStringOrDie is inappropriate,
+// but where you still want to read a file.
+template <int kBufferSize = 1024>
+class FileReader {
+ public:
+ FileReader(std::string_view filename)
+ : file_(open(::std::string(filename).c_str(), O_RDONLY)) {
+ PCHECK(file_.get() != -1) << ": opening " << filename;
+ memset(buffer_, 0, kBufferSize);
+ }
+ // Reads the entire contents of the file into the internal buffer and returns
+ // a string_view of it.
+ // Note: The result may not be null-terminated.
+ std::string_view ReadContents() {
+ PCHECK(0 == lseek(file_.get(), 0, SEEK_SET));
+ const ssize_t result = read(file_.get(), buffer_, sizeof(buffer_));
+ PCHECK(result >= 0);
+ return {buffer_, static_cast<size_t>(result)};
+ }
+ // Calls ReadContents() and attempts to convert the result into an integer, or
+ // dies trying.
+ int ReadInt() {
+ int result;
+ std::string_view contents = ReadContents();
+ CHECK(absl::SimpleAtoi(contents, &result))
+ << "Failed to parse \"" << contents << "\" as int.";
+ return result;
+ }
+
+ private:
+ aos::ScopedFD file_;
+ char buffer_[kBufferSize];
+};
+
} // namespace util
} // namespace aos