blob: 9ea5e9716d9368721de658f6f8b806072571af61 [file] [log] [blame] [edit]
// 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_