| // Copyright 2019 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef DIAGNOSTICS_BASE_FILE_UTILS_H_ | |
| #define DIAGNOSTICS_BASE_FILE_UTILS_H_ | |
| #include <string> | |
| #include <string_view> | |
| #include <base/check.h> | |
| #include <base/files/file_path.h> | |
| #include <base/files/scoped_temp_dir.h> | |
| #include <brillo/brillo_export.h> | |
| namespace diagnostics { | |
| // Returns the root dir. This can be the overridden during unit tests. | |
| BRILLO_EXPORT base::FilePath GetRootDir(); | |
| // Returns the paths under the root dir. This does nothing in real | |
| // implementations. The root directory can be overridden in unit tests. Note | |
| // that the path must be absolute. | |
| BRILLO_EXPORT base::FilePath GetRootedPath(base::FilePath path); | |
| // Just like the above but turns a std::string_view into base::FilePath. | |
| inline base::FilePath GetRootedPath(std::string_view path) { | |
| return GetRootedPath(base::FilePath{path}); | |
| } | |
| #ifndef USE_TEST | |
| static_assert(false, | |
| "USE_TEST is not defined. Did you set right gn dependency?"); | |
| #elif USE_TEST == false | |
| // These real implementations are short. Just inline them in the header. | |
| inline base::FilePath GetRootDir() { | |
| return base::FilePath{"/"}; | |
| } | |
| inline base::FilePath GetRootedPath(base::FilePath path) { | |
| return path; | |
| } | |
| #else | |
| // Overrides the root dir by using a unique temporary directory for unit tests. | |
| // Doesn't support nested overriding. | |
| class BRILLO_EXPORT ScopedRootDirOverrides { | |
| public: | |
| ScopedRootDirOverrides(); | |
| ScopedRootDirOverrides(const ScopedRootDirOverrides&) = delete; | |
| ScopedRootDirOverrides& operator=(const ScopedRootDirOverrides&) = delete; | |
| ~ScopedRootDirOverrides(); | |
| private: | |
| base::ScopedTempDir temp_dir_; | |
| }; | |
| #endif | |
| // Reads the contents of |file_path| into |out|, trims leading and trailing | |
| // whitespace. Returns true on success. | |
| // |StringType| can be any type which can be converted from |std::string|. | |
| // For example, |std::optional<std::string>|. | |
| template <typename StringType> | |
| bool ReadAndTrimString(const base::FilePath& file_path, StringType* out) { | |
| DCHECK(out); | |
| std::string out_raw; | |
| if (!ReadAndTrimString(file_path, &out_raw)) | |
| return false; | |
| *out = static_cast<StringType>(out_raw); | |
| return true; | |
| } | |
| template <> | |
| BRILLO_EXPORT bool ReadAndTrimString<std::string>( | |
| const base::FilePath& file_path, std::string* out); | |
| // Like ReadAndTrimString() above, but expects a |filename| within |directory| | |
| // to be read. | |
| template <typename StringType> | |
| bool ReadAndTrimString(const base::FilePath& directory, | |
| std::string_view filename, | |
| StringType* out) { | |
| return ReadAndTrimString(directory.Append(filename), out); | |
| } | |
| // Reads an integer value from a file and converts it using the provided | |
| // function. Returns true on success. | |
| template <typename T> | |
| bool ReadInteger(const base::FilePath& file_path, | |
| bool (*StringToInteger)(std::string_view, T*), | |
| T* out) { | |
| DCHECK(StringToInteger); | |
| DCHECK(out); | |
| std::string buffer; | |
| if (!ReadAndTrimString(file_path, &buffer)) | |
| return false; | |
| return StringToInteger(buffer, out); | |
| } | |
| // Like ReadInteger() above, but expects a |filename| within |directory| to be | |
| // read. | |
| template <typename T> | |
| bool ReadInteger(const base::FilePath& directory, | |
| std::string_view filename, | |
| bool (*StringToInteger)(std::string_view, T*), | |
| T* out) { | |
| return ReadInteger(directory.AppendASCII(filename), StringToInteger, out); | |
| } | |
| } // namespace diagnostics | |
| #endif // DIAGNOSTICS_BASE_FILE_UTILS_H_ |