blob: 881af33964032ddae44457e4fa18a1ece0ec1828 [file] [log] [blame]
#ifndef AOS_UTIL_FILE_H_
#define AOS_UTIL_FILE_H_
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <array>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/types/span.h"
#include "aos/scoped/scoped_fd.h"
namespace aos::util {
// Returns the complete contents of filename. LOG(FATAL)s if any errors are
// encountered.
std::string ReadFileToStringOrDie(const std::string_view filename);
// Returns the complete contents of filename. Returns nullopt, but never dies
// if any errors are encountered.
std::optional<std::string> MaybeReadFileToString(
const std::string_view filename);
// Returns the complete contents of filename as a byte vector. LOG(FATAL)s if
// any errors are encountered.
std::vector<uint8_t> ReadFileToVecOrDie(const std::string_view filename);
// Creates filename if it doesn't exist and sets the contents to contents.
void WriteStringToFileOrDie(const std::string_view filename,
const std::string_view contents,
mode_t permissions = S_IRWXU);
// Returns true if it succeeds or false if the filesystem is full.
bool MkdirPIfSpace(std::string_view path, mode_t mode);
inline void MkdirP(std::string_view path, mode_t mode) {
CHECK(MkdirPIfSpace(path, mode));
}
bool PathExists(std::string_view path);
// Recursively removes everything in the provided path. Ignores any errors it
// runs across.
void UnlinkRecursive(std::string_view path);
enum class FileOptions { kReadable, kWriteable };
enum class FileReaderErrorType { kFatal, kNonFatal };
// Maps file from disk into memory
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.
class FileReader {
public:
// Opens the file for reading. Crashes if file does not open when flag is set
// to fatal (default). Logs error if file does not open and flag is non-fatal.
FileReader(std::string_view filename,
FileReaderErrorType error_type = FileReaderErrorType::kFatal);
// Reads the entire contents of the file into the internal buffer and returns
// a string_view of it. Returns nullopt if we failed to read the contents
// (currently only on EREMOTEIO). Note: The result may not be null-terminated.
std::optional<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 std::optional<absl::Span<char>> used_span =
ReadContents(absl::Span<char>(result.data(), result.size()));
if (!used_span.has_value()) {
return std::nullopt;
}
if (used_span->size() == kSize) {
return result;
} else {
return std::nullopt;
}
}
// 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. Returns nullopt if we failed to read the file.
std::optional<int32_t> ReadInt32();
// Checks if file could be opened.
bool is_open() const { return file_.get() != -1; }
private:
aos::ScopedFD file_;
};
// Simple interface to allow opening a file for writing and then writing it
// without any malloc's.
class FileWriter {
public:
// The result of an individual call to WriteBytes().
// Because WriteBytes() may repeatedly call write() when partial writes occur,
// it is possible for a non-zero number of bytes to have been written while
// still having an error because a late call to write() failed.
struct WriteResult {
// Total number of bytes successfully written to the file.
size_t bytes_written;
// If the write was successful (return_code > 0), equal to bytes_written.
// Otherwise, equal to the return value of the final call to write.
int return_code;
};
FileWriter(std::string_view filename, mode_t permissions = S_IRWXU);
WriteResult WriteBytes(absl::Span<const uint8_t> bytes);
WriteResult WriteBytes(std::string_view bytes);
void WriteBytesOrDie(absl::Span<const uint8_t> bytes);
void WriteBytesOrDie(std::string_view bytes);
int fd() const { return file_.get(); }
private:
aos::ScopedFD file_;
};
} // namespace aos::util
#endif // AOS_UTIL_FILE_H_