blob: ddd5d478a54737472a5af793ebcdc573454b96bc [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#ifndef AOS_UTIL_FILE_H_
2#define AOS_UTIL_FILE_H_
Brian Silverman61175fb2016-03-13 15:35:56 -04003
James Kuszmaul0625b0d2022-09-21 11:38:48 -07004#include <fcntl.h>
Austin Schuhe3fc0532021-02-07 22:14:22 -08005#include <sys/stat.h>
James Kuszmaul0625b0d2022-09-21 11:38:48 -07006#include <sys/types.h>
davidjevans8b9b52f2021-09-17 08:57:30 -07007
8#include <memory>
James Kuszmaul5a88d412023-01-27 15:55:55 -08009#include <optional>
Brian Silverman61175fb2016-03-13 15:35:56 -040010#include <string>
James Kuszmaul3ae42262019-11-08 12:33:41 -080011#include <string_view>
Austin Schuhcb108412019-10-13 16:09:54 -070012
James Kuszmaul0625b0d2022-09-21 11:38:48 -070013#include "absl/strings/numbers.h"
davidjevans8b9b52f2021-09-17 08:57:30 -070014#include "absl/types/span.h"
James Kuszmaul0625b0d2022-09-21 11:38:48 -070015#include "aos/scoped/scoped_fd.h"
James Kuszmaul5a88d412023-01-27 15:55:55 -080016#include "flatbuffers/util.h"
Brian Silvermana9f2ec92020-10-06 18:00:53 -070017#include "glog/logging.h"
18
Brian Silverman61175fb2016-03-13 15:35:56 -040019namespace aos {
20namespace util {
21
22// Returns the complete contents of filename. LOG(FATAL)s if any errors are
23// encountered.
James Kuszmaul3ae42262019-11-08 12:33:41 -080024::std::string ReadFileToStringOrDie(const std::string_view filename);
Brian Silverman61175fb2016-03-13 15:35:56 -040025
Alex Perrycb7da4b2019-08-28 19:35:56 -070026// Creates filename if it doesn't exist and sets the contents to contents.
James Kuszmaul3ae42262019-11-08 12:33:41 -080027void WriteStringToFileOrDie(const std::string_view filename,
Austin Schuhe3fc0532021-02-07 22:14:22 -080028 const std::string_view contents,
29 mode_t permissions = S_IRWXU);
Alex Perrycb7da4b2019-08-28 19:35:56 -070030
Brian Silvermana9f2ec92020-10-06 18:00:53 -070031// Returns true if it succeeds or false if the filesystem is full.
32bool MkdirPIfSpace(std::string_view path, mode_t mode);
33
34inline void MkdirP(std::string_view path, mode_t mode) {
35 CHECK(MkdirPIfSpace(path, mode));
36}
Austin Schuhfccb2d02020-01-26 16:11:19 -080037
James Kuszmaulf8178092020-05-10 18:46:45 -070038bool PathExists(std::string_view path);
39
Austin Schuhe991fe22020-11-18 16:53:39 -080040// Recursively removes everything in the provided path. Ignores any errors it
41// runs across.
42void UnlinkRecursive(std::string_view path);
43
Austin Schuhe4d1a682021-10-01 15:04:50 -070044enum class FileOptions { kReadable, kWriteable };
45
davidjevans8b9b52f2021-09-17 08:57:30 -070046// Maps file from disk into memory
Austin Schuhe4d1a682021-10-01 15:04:50 -070047std::shared_ptr<absl::Span<uint8_t>> MMapFile(
48 const std::string &path, FileOptions options = FileOptions::kReadable);
davidjevans8b9b52f2021-09-17 08:57:30 -070049
James Kuszmaul0625b0d2022-09-21 11:38:48 -070050// Wrapper to handle reading the contents of a file into a buffer. Meant for
51// situations where the malloc'ing of ReadFileToStringOrDie is inappropriate,
52// but where you still want to read a file.
James Kuszmaul0625b0d2022-09-21 11:38:48 -070053class FileReader {
54 public:
James Kuszmaul5a88d412023-01-27 15:55:55 -080055 FileReader(std::string_view filename);
James Kuszmaul0625b0d2022-09-21 11:38:48 -070056 // Reads the entire contents of the file into the internal buffer and returns
57 // a string_view of it.
58 // Note: The result may not be null-terminated.
James Kuszmaul5a88d412023-01-27 15:55:55 -080059 absl::Span<char> ReadContents(absl::Span<char> buffer);
60 // Returns the value of the file as a string, for a fixed-length file.
61 // Returns nullopt if the result is smaller than kSize. Ignores any
62 // bytes beyond kSize.
63 template <int kSize>
64 std::optional<std::array<char, kSize>> ReadString() {
65 std::array<char, kSize> result;
66 const absl::Span<char> used_span =
67 ReadContents(absl::Span<char>(result.data(), result.size()));
68 if (used_span.size() == kSize) {
69 return result;
70 } else {
71 return std::nullopt;
72 }
James Kuszmaul0625b0d2022-09-21 11:38:48 -070073 }
James Kuszmaul5a88d412023-01-27 15:55:55 -080074 // Returns the value of the file as an integer. Crashes if it doesn't fit in a
75 // 32-bit integer. The value may start with 0x for a hex value, otherwise it
76 // must be base 10.
77 int32_t ReadInt32();
James Kuszmaul0625b0d2022-09-21 11:38:48 -070078
79 private:
80 aos::ScopedFD file_;
James Kuszmaul0625b0d2022-09-21 11:38:48 -070081};
82
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080083// Simple interface to allow opening a file for writing and then writing it
84// without any malloc's.
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080085class FileWriter {
86 public:
87 // The result of an individual call to WriteBytes().
88 // Because WriteBytes() may repeatedly call write() when partial writes occur,
89 // it is possible for a non-zero number of bytes to have been written while
90 // still having an error because a late call to write() failed.
91 struct WriteResult {
92 // Total number of bytes successfully written to the file.
93 size_t bytes_written;
94 // If the write was successful (return_code > 0), equal to bytes_written.
95 // Otherwise, equal to the return value of the final call to write.
96 int return_code;
97 };
98
99 FileWriter(std::string_view filename, mode_t permissions = S_IRWXU);
100
101 WriteResult WriteBytes(absl::Span<const uint8_t> bytes);
102 WriteResult WriteBytes(std::string_view bytes);
103 void WriteBytesOrDie(absl::Span<const uint8_t> bytes);
104 void WriteBytesOrDie(std::string_view bytes);
105 int fd() const { return file_.get(); }
106
107 private:
108 aos::ScopedFD file_;
109};
110
Brian Silverman61175fb2016-03-13 15:35:56 -0400111} // namespace util
112} // namespace aos
113
John Park33858a32018-09-28 23:05:48 -0700114#endif // AOS_UTIL_FILE_H_