Alter FileReader's memory management
Make it so that the FileReader allows control of the memory before
at the callsite rather than over the whole lifetime of the FileReader
object.
Change-Id: Iee418af8dfa014dcf9718e9cff549ae69e5bc569
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/util/file.h b/aos/util/file.h
index 56479ce..ddd5d47 100644
--- a/aos/util/file.h
+++ b/aos/util/file.h
@@ -6,12 +6,14 @@
#include <sys/types.h>
#include <memory>
+#include <optional>
#include <string>
#include <string_view>
#include "absl/strings/numbers.h"
#include "absl/types/span.h"
#include "aos/scoped/scoped_fd.h"
+#include "flatbuffers/util.h"
#include "glog/logging.h"
namespace aos {
@@ -48,43 +50,38 @@
// 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);
- }
+ FileReader(std::string_view filename);
// 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)};
+ absl::Span<char> ReadContents(absl::Span<char> buffer);
+ // Returns the value of the file as a string, for a fixed-length file.
+ // Returns nullopt if the result is smaller than kSize. Ignores any
+ // bytes beyond kSize.
+ template <int kSize>
+ std::optional<std::array<char, kSize>> ReadString() {
+ std::array<char, kSize> result;
+ const absl::Span<char> used_span =
+ ReadContents(absl::Span<char>(result.data(), result.size()));
+ if (used_span.size() == kSize) {
+ return result;
+ } else {
+ return std::nullopt;
+ }
}
- // 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;
- }
+ // Returns the value of the file as an integer. Crashes if it doesn't fit in a
+ // 32-bit integer. The value may start with 0x for a hex value, otherwise it
+ // must be base 10.
+ int32_t ReadInt32();
private:
aos::ScopedFD file_;
- char buffer_[kBufferSize];
};
// Simple interface to allow opening a file for writing and then writing it
// without any malloc's.
-// TODO(james): It may make sense to add a ReadBytes() interface here that can
-// take a memory buffer to fill, to avoid the templating required by the
-// self-managed buffer of FileReader<>.
class FileWriter {
public:
// The result of an individual call to WriteBytes().