Begin the first small step towards using FilePath everywhere:
- Add some transition APIs. - Start migrating some code to transition APIs. Review URL: http://codereview.chromium.org/8825 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4254 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
|
||||
#include "base/base_paths.h"
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
|
||||
@ -12,15 +13,15 @@ namespace base {
|
||||
bool PathProvider(int key, std::wstring* result) {
|
||||
// NOTE: DIR_CURRENT is a special cased in PathService::Get
|
||||
|
||||
std::wstring cur;
|
||||
FilePath cur;
|
||||
switch (key) {
|
||||
case base::DIR_EXE:
|
||||
PathService::Get(base::FILE_EXE, &cur);
|
||||
file_util::TrimFilename(&cur);
|
||||
cur = cur.DirName();
|
||||
break;
|
||||
case base::DIR_MODULE:
|
||||
PathService::Get(base::FILE_MODULE, &cur);
|
||||
file_util::TrimFilename(&cur);
|
||||
cur = cur.DirName();
|
||||
break;
|
||||
case base::DIR_TEMP:
|
||||
if (!file_util::GetTempDir(&cur))
|
||||
@ -30,7 +31,7 @@ bool PathProvider(int key, std::wstring* result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
result->swap(cur);
|
||||
*result = cur.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
@ -15,7 +16,7 @@
|
||||
namespace base {
|
||||
|
||||
bool PathProviderLinux(int key, std::wstring* result) {
|
||||
std::wstring cur;
|
||||
FilePath path;
|
||||
switch (key) {
|
||||
case base::FILE_EXE:
|
||||
case base::FILE_MODULE: { // TODO(evanm): is this correct?
|
||||
@ -32,10 +33,11 @@ bool PathProviderLinux(int key, std::wstring* result) {
|
||||
case base::DIR_SOURCE_ROOT:
|
||||
// On linux, unit tests execute two levels deep from the source root.
|
||||
// For example: chrome/{Debug|Hammer}/net_unittest
|
||||
PathService::Get(base::DIR_EXE, &cur);
|
||||
file_util::UpOneDirectory(&cur);
|
||||
file_util::UpOneDirectory(&cur);
|
||||
*result = cur;
|
||||
if (!PathService::Get(base::DIR_EXE, &path))
|
||||
return false;
|
||||
path = path.Append(FilePath::kParentDirectory)
|
||||
.Append(FilePath::kParentDirectory);
|
||||
*result = path.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -4,6 +4,11 @@
|
||||
|
||||
#include "base/file_path.h"
|
||||
|
||||
// These includes are just for the *Hack functions, and should be removed
|
||||
// when those functions are removed.
|
||||
#include "base/string_piece.h"
|
||||
#include "base/sys_string_conversions.h"
|
||||
|
||||
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
|
||||
const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/");
|
||||
#else // FILE_PATH_USES_WIN_SEPARATORS
|
||||
@ -152,6 +157,29 @@ bool FilePath::IsAbsolute() const {
|
||||
#endif // FILE_PATH_USES_DRIVE_LETTERS
|
||||
}
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
// See file_path.h for a discussion of the encoding of paths on POSIX
|
||||
// platforms. These *Hack() functions are not quite correct, but they're
|
||||
// only temporary while we fix the remainder of the code.
|
||||
// Remember to remove the #includes at the top when you remove these.
|
||||
|
||||
// static
|
||||
FilePath FilePath::FromWStringHack(const std::wstring& wstring) {
|
||||
return FilePath(base::SysWideToNativeMB(wstring));
|
||||
}
|
||||
std::wstring FilePath::ToWStringHack() const {
|
||||
return base::SysNativeMBToWide(path_);
|
||||
}
|
||||
#elif defined(OS_WIN)
|
||||
// static
|
||||
FilePath FilePath::FromWStringHack(const std::wstring& wstring) {
|
||||
return FilePath(wstring);
|
||||
}
|
||||
std::wstring FilePath::ToWStringHack() const {
|
||||
return path_;
|
||||
}
|
||||
#endif
|
||||
|
||||
void FilePath::StripTrailingSeparators() {
|
||||
// If there is no drive letter, start will be 1, which will prevent stripping
|
||||
// the leading separator if there is only one separator. If there is a drive
|
||||
|
@ -145,6 +145,20 @@ class FilePath {
|
||||
// platforms, an absolute path begins with a separator character.
|
||||
bool IsAbsolute() const;
|
||||
|
||||
// Older Chromium code assumes that paths are always wstrings.
|
||||
// This function converts a wstring to a FilePath, and is useful to smooth
|
||||
// porting that old code to the FilePath API.
|
||||
// It has "Hack" in its name so people feel bad about using it.
|
||||
// TODO(port): remove these functions.
|
||||
static FilePath FromWStringHack(const std::wstring& wstring);
|
||||
|
||||
// Older Chromium code assumes that paths are always wstrings.
|
||||
// This function produces a wstring from a FilePath, and is useful to smooth
|
||||
// porting that old code to the FilePath API.
|
||||
// It has "Hack" in its name so people feel bad about using it.
|
||||
// TODO(port): remove these functions.
|
||||
std::wstring ToWStringHack() const;
|
||||
|
||||
private:
|
||||
// If this FilePath contains a drive letter specification, returns the
|
||||
// position of the last character of the drive letter specification,
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
#include "unicode/uniset.h"
|
||||
@ -229,20 +230,14 @@ void ReplaceExtension(std::wstring* file_name, const std::wstring& extension) {
|
||||
file_name->swap(result);
|
||||
}
|
||||
|
||||
bool ContentsEqual(const std::wstring& filename1,
|
||||
const std::wstring& filename2) {
|
||||
bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
|
||||
// We open the file in binary format even if they are text files because
|
||||
// we are just comparing that bytes are exactly same in both files and not
|
||||
// doing anything smart with text formatting.
|
||||
#if defined(OS_WIN)
|
||||
std::ifstream file1(filename1.c_str(), std::ios::in | std::ios::binary);
|
||||
std::ifstream file2(filename2.c_str(), std::ios::in | std::ios::binary);
|
||||
#elif defined(OS_POSIX)
|
||||
std::ifstream file1(WideToUTF8(filename1).c_str(),
|
||||
std::ifstream file1(filename1.value().c_str(),
|
||||
std::ios::in | std::ios::binary);
|
||||
std::ifstream file2(WideToUTF8(filename2).c_str(),
|
||||
std::ifstream file2(filename2.value().c_str(),
|
||||
std::ios::in | std::ios::binary);
|
||||
#endif
|
||||
|
||||
// Even if both files aren't openable (and thus, in some sense, "equal"),
|
||||
// any unusable file yields a result of "false".
|
||||
@ -300,5 +295,60 @@ bool CloseFile(FILE* file) {
|
||||
return fclose(file) == 0;
|
||||
}
|
||||
|
||||
// Deprecated functions ----------------------------------------------------
|
||||
|
||||
bool AbsolutePath(std::wstring* path_str) {
|
||||
FilePath path;
|
||||
if (!AbsolutePath(&path))
|
||||
return false;
|
||||
*path_str = path.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
bool Delete(const std::wstring& path, bool recursive) {
|
||||
return Delete(FilePath::FromWStringHack(path), recursive);
|
||||
}
|
||||
bool Move(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
return Move(FilePath::FromWStringHack(from_path),
|
||||
FilePath::FromWStringHack(to_path));
|
||||
}
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
return CopyFile(FilePath::FromWStringHack(from_path),
|
||||
FilePath::FromWStringHack(to_path));
|
||||
}
|
||||
bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
|
||||
bool recursive) {
|
||||
return CopyDirectory(FilePath::FromWStringHack(from_path),
|
||||
FilePath::FromWStringHack(to_path),
|
||||
recursive);
|
||||
}
|
||||
bool PathExists(const std::wstring& path) {
|
||||
return PathExists(FilePath::FromWStringHack(path));
|
||||
}
|
||||
bool DirectoryExists(const std::wstring& path) {
|
||||
return DirectoryExists(FilePath::FromWStringHack(path));
|
||||
}
|
||||
bool ContentsEqual(const std::wstring& filename1,
|
||||
const std::wstring& filename2) {
|
||||
return ContentsEqual(FilePath::FromWStringHack(filename1),
|
||||
FilePath::FromWStringHack(filename2));
|
||||
}
|
||||
bool CreateDirectory(const std::wstring& full_path) {
|
||||
return CreateDirectory(FilePath::FromWStringHack(full_path));
|
||||
}
|
||||
bool GetCurrentDirectory(std::wstring* path_str) {
|
||||
FilePath path;
|
||||
if (!GetCurrentDirectory(&path))
|
||||
return false;
|
||||
*path_str = path.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
bool GetTempDir(std::wstring* path_str) {
|
||||
FilePath path;
|
||||
if (!GetTempDir(&path))
|
||||
return false;
|
||||
*path_str = path.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
class FilePath;
|
||||
|
||||
namespace file_util {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -83,6 +85,8 @@ void AppendToPath(std::wstring* path, const std::wstring& new_ending);
|
||||
|
||||
// Convert provided relative path into an absolute path. Returns false on
|
||||
// error.
|
||||
bool AbsolutePath(FilePath* path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool AbsolutePath(std::wstring* path);
|
||||
|
||||
// Inserts |suffix| after the file name portion of |path| but before the
|
||||
@ -127,13 +131,19 @@ int CountFilesCreatedAfter(const std::wstring& path,
|
||||
//
|
||||
// WARNING: USING THIS WITH recursive==true IS EQUIVALENT
|
||||
// TO "rm -rf", SO USE WITH CAUTION.
|
||||
bool Delete(const FilePath& path, bool recursive);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool Delete(const std::wstring& path, bool recursive);
|
||||
|
||||
// Moves the given path, whether it's a file or a directory.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool Move(const FilePath& from_path, const FilePath& to_path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool Move(const std::wstring& from_path, const std::wstring& to_path);
|
||||
|
||||
// Copies a single file. Use CopyDirectory to copy directories.
|
||||
bool CopyFile(const FilePath& from_path, const FilePath& to_path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path);
|
||||
|
||||
// Copies the given path, and optionally all subdirectories and their contents
|
||||
@ -143,17 +153,24 @@ bool CopyFile(const std::wstring& from_path, const std::wstring& to_path);
|
||||
// Dont't use wildcards on the names, it may stop working without notice.
|
||||
//
|
||||
// If you only need to copy a file use CopyFile, it's faster.
|
||||
bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
|
||||
bool recursive);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
|
||||
bool recursive);
|
||||
|
||||
// Returns true if the given path exists on the local filesystem,
|
||||
// false otherwise.
|
||||
bool PathExists(const FilePath& path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool PathExists(const std::wstring& path);
|
||||
|
||||
// Returns true if the given path is writable by the user, false otherwise.
|
||||
bool PathIsWritable(const std::wstring& path);
|
||||
|
||||
// Returns true if the given path exists and is a directory, false otherwise.
|
||||
bool DirectoryExists(const FilePath& path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool DirectoryExists(const std::wstring& path);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@ -170,6 +187,9 @@ bool GetFileCreationLocalTimeFromHandle(HANDLE file_handle,
|
||||
|
||||
// Returns true if the contents of the two files given are equal, false
|
||||
// otherwise. If either file can't be read, returns false.
|
||||
bool ContentsEqual(const FilePath& filename1,
|
||||
const FilePath& filename2);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool ContentsEqual(const std::wstring& filename1,
|
||||
const std::wstring& filename2);
|
||||
|
||||
@ -216,6 +236,8 @@ bool IsDirectoryEmpty(const std::wstring& dir_path);
|
||||
|
||||
|
||||
// Get the temporary directory provided by the system.
|
||||
bool GetTempDir(FilePath* path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool GetTempDir(std::wstring* path);
|
||||
|
||||
// Creates a temporary file. The full path is placed in 'temp_file', and the
|
||||
@ -237,6 +259,8 @@ bool CreateNewTempDirectory(const std::wstring& prefix,
|
||||
// Creates a directory, as well as creating any parent directories, if they
|
||||
// don't exist. Returns 'true' on successful creation, or if the directory
|
||||
// already exists.
|
||||
bool CreateDirectory(const FilePath& full_path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool CreateDirectory(const std::wstring& full_path);
|
||||
|
||||
// Returns the file size. Returns true on success.
|
||||
@ -257,6 +281,8 @@ struct FileInfo {
|
||||
bool GetFileInfo(const std::wstring& file_path, FileInfo* info);
|
||||
|
||||
// Wrapper for fopen-like calls. Returns non-NULL FILE* on success.
|
||||
FILE* OpenFile(const FilePath& filename, const char* mode);
|
||||
// Deprecated temporary compatibility functions.
|
||||
FILE* OpenFile(const std::string& filename, const char* mode);
|
||||
FILE* OpenFile(const std::wstring& filename, const char* mode);
|
||||
|
||||
@ -272,6 +298,8 @@ int ReadFile(const std::wstring& filename, char* data, int size);
|
||||
int WriteFile(const std::wstring& filename, const char* data, int size);
|
||||
|
||||
// Gets the current working directory for the process.
|
||||
bool GetCurrentDirectory(FilePath* path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool GetCurrentDirectory(std::wstring* path);
|
||||
|
||||
// Sets the current working directory for the process.
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
@ -16,21 +17,21 @@ namespace file_util {
|
||||
|
||||
const wchar_t kPathSeparator = L'/';
|
||||
|
||||
bool GetTempDir(std::wstring* path) {
|
||||
bool GetTempDir(FilePath* path) {
|
||||
const char* tmp = getenv("TMPDIR");
|
||||
if (tmp)
|
||||
*path = UTF8ToWide(tmp);
|
||||
*path = FilePath(tmp);
|
||||
else
|
||||
*path = L"/tmp";
|
||||
*path = FilePath("/tmp");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
int infile = open(WideToUTF8(from_path).c_str(), O_RDONLY);
|
||||
bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
|
||||
int infile = open(from_path.value().c_str(), O_RDONLY);
|
||||
if (infile < 0)
|
||||
return false;
|
||||
|
||||
int outfile = creat(WideToUTF8(to_path).c_str(), 0666);
|
||||
int outfile = creat(to_path.value().c_str(), 0666);
|
||||
if (outfile < 0) {
|
||||
close(infile);
|
||||
return false;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <copyfile.h>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
@ -14,18 +15,17 @@ namespace file_util {
|
||||
|
||||
const wchar_t kPathSeparator = L'/';
|
||||
|
||||
bool GetTempDir(std::wstring* path) {
|
||||
bool GetTempDir(FilePath* path) {
|
||||
NSString* tmp = NSTemporaryDirectory();
|
||||
if (tmp == nil)
|
||||
return false;
|
||||
*path = reinterpret_cast<const wchar_t*>(
|
||||
[tmp cStringUsingEncoding:NSUTF32StringEncoding]);
|
||||
*path = FilePath([tmp fileSystemRepresentation]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
return (copyfile(WideToUTF8(from_path).c_str(),
|
||||
WideToUTF8(to_path).c_str(), NULL, COPYFILE_ALL) == 0);
|
||||
bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
|
||||
return (copyfile(from_path.value().c_str(),
|
||||
to_path.value().c_str(), NULL, COPYFILE_ALL) == 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <fstream>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
@ -37,11 +38,11 @@ std::wstring GetDirectoryFromPath(const std::wstring& path) {
|
||||
}
|
||||
}
|
||||
|
||||
bool AbsolutePath(std::wstring* path) {
|
||||
bool AbsolutePath(FilePath* path) {
|
||||
char full_path[PATH_MAX];
|
||||
if (realpath(WideToUTF8(*path).c_str(), full_path) == NULL)
|
||||
if (realpath(path->value().c_str(), full_path) == NULL)
|
||||
return false;
|
||||
*path = UTF8ToWide(full_path);
|
||||
*path = FilePath(full_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -49,25 +50,24 @@ bool AbsolutePath(std::wstring* path) {
|
||||
// which works both with and without the recursive flag. I'm not sure we need
|
||||
// that functionality. If not, remove from file_util_win.cc, otherwise add it
|
||||
// here.
|
||||
bool Delete(const std::wstring& path, bool recursive) {
|
||||
std::string utf8_path_string = WideToUTF8(path);
|
||||
const char* utf8_path = utf8_path_string.c_str();
|
||||
bool Delete(const FilePath& path, bool recursive) {
|
||||
const char* path_str = path.value().c_str();
|
||||
struct stat64 file_info;
|
||||
int test = stat64(utf8_path, &file_info);
|
||||
int test = stat64(path_str, &file_info);
|
||||
if (test != 0) {
|
||||
// The Windows version defines this condition as success.
|
||||
bool ret = (errno == ENOENT || errno == ENOTDIR);
|
||||
return ret;
|
||||
}
|
||||
if (!S_ISDIR(file_info.st_mode))
|
||||
return (unlink(utf8_path) == 0);
|
||||
return (unlink(path_str) == 0);
|
||||
if (!recursive)
|
||||
return (rmdir(utf8_path) == 0);
|
||||
return (rmdir(path_str) == 0);
|
||||
|
||||
bool success = true;
|
||||
int ftsflags = FTS_PHYSICAL | FTS_NOSTAT;
|
||||
char top_dir[PATH_MAX];
|
||||
if (base::strlcpy(top_dir, utf8_path,
|
||||
if (base::strlcpy(top_dir, path_str,
|
||||
arraysize(top_dir)) >= arraysize(top_dir)) {
|
||||
return false;
|
||||
}
|
||||
@ -105,26 +105,23 @@ bool Delete(const std::wstring& path, bool recursive) {
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Move(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
return (rename(WideToUTF8(from_path).c_str(),
|
||||
WideToUTF8(to_path).c_str()) == 0);
|
||||
bool Move(const FilePath& from_path, const FilePath& to_path) {
|
||||
return (rename(from_path.value().c_str(),
|
||||
to_path.value().c_str()) == 0);
|
||||
}
|
||||
|
||||
bool CopyDirectory(const std::wstring& from_path_wide,
|
||||
const std::wstring& to_path_wide,
|
||||
bool CopyDirectory(const FilePath& from_path,
|
||||
const FilePath& to_path,
|
||||
bool recursive) {
|
||||
const std::string to_path = WideToUTF8(to_path_wide);
|
||||
const std::string from_path = WideToUTF8(from_path_wide);
|
||||
|
||||
// Some old callers of CopyDirectory want it to support wildcards.
|
||||
// After some discussion, we decided to fix those callers.
|
||||
// Break loudly here if anyone tries to do this.
|
||||
// TODO(evanm): remove this once we're sure it's ok.
|
||||
DCHECK(to_path.find('*') == std::string::npos);
|
||||
DCHECK(from_path.find('*') == std::string::npos);
|
||||
DCHECK(to_path.value().find('*') == std::string::npos);
|
||||
DCHECK(from_path.value().find('*') == std::string::npos);
|
||||
|
||||
char top_dir[PATH_MAX];
|
||||
if (base::strlcpy(top_dir, from_path.c_str(),
|
||||
if (base::strlcpy(top_dir, from_path.value().c_str(),
|
||||
arraysize(top_dir)) >= arraysize(top_dir)) {
|
||||
return false;
|
||||
}
|
||||
@ -141,7 +138,8 @@ bool CopyDirectory(const std::wstring& from_path_wide,
|
||||
while (!error && (ent = fts_read(fts)) != NULL) {
|
||||
// ent->fts_path is the source path, including from_path, so paste
|
||||
// the suffix after from_path onto to_path to create the target_path.
|
||||
const std::string target_path = to_path + &ent->fts_path[from_path.size()];
|
||||
const std::string target_path =
|
||||
to_path.value() + &ent->fts_path[from_path.value().size()];
|
||||
switch (ent->fts_info) {
|
||||
case FTS_D: // Preorder directory.
|
||||
// If we encounter a subdirectory in a non-recursive copy, prune it
|
||||
@ -211,14 +209,14 @@ bool CopyDirectory(const std::wstring& from_path_wide,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathExists(const std::wstring& path) {
|
||||
bool PathExists(const FilePath& path) {
|
||||
struct stat64 file_info;
|
||||
return (stat64(WideToUTF8(path).c_str(), &file_info) == 0);
|
||||
return (stat64(path.value().c_str(), &file_info) == 0);
|
||||
}
|
||||
|
||||
bool DirectoryExists(const std::wstring& path) {
|
||||
bool DirectoryExists(const FilePath& path) {
|
||||
struct stat64 file_info;
|
||||
if (stat64(WideToUTF8(path).c_str(), &file_info) == 0)
|
||||
if (stat64(path.value().c_str(), &file_info) == 0)
|
||||
return S_ISDIR(file_info.st_mode);
|
||||
return false;
|
||||
}
|
||||
@ -290,18 +288,23 @@ bool CreateNewTempDirectory(const std::wstring& prefix,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateDirectory(const std::wstring& full_path) {
|
||||
std::vector<std::wstring> components;
|
||||
PathComponents(full_path, &components);
|
||||
std::wstring path;
|
||||
std::vector<std::wstring>::iterator i = components.begin();
|
||||
for (; i != components.end(); ++i) {
|
||||
if (path.length() == 0)
|
||||
path = *i;
|
||||
else
|
||||
AppendToPath(&path, *i);
|
||||
if (!DirectoryExists(path)) {
|
||||
if (mkdir(WideToUTF8(path).c_str(), 0777) != 0)
|
||||
bool CreateDirectory(const FilePath& full_path) {
|
||||
std::vector<FilePath> subpaths;
|
||||
|
||||
// Collect a list of all parent directories.
|
||||
FilePath last_path = full_path;
|
||||
subpaths.push_back(full_path);
|
||||
for (FilePath path = full_path.DirName();
|
||||
path.value() != last_path.value(); path = path.DirName()) {
|
||||
subpaths.push_back(path);
|
||||
last_path = path;
|
||||
}
|
||||
|
||||
// Iterate through the parents and create the missing ones.
|
||||
for (std::vector<FilePath>::reverse_iterator i = subpaths.rbegin();
|
||||
i != subpaths.rend(); ++i) {
|
||||
if (!DirectoryExists(*i)) {
|
||||
if (mkdir(i->value().c_str(), 0777) != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -358,10 +361,13 @@ int WriteFile(const std::wstring& filename, const char* data, int size) {
|
||||
}
|
||||
|
||||
// Gets the current working directory for the process.
|
||||
bool GetCurrentDirectory(std::wstring* dir) {
|
||||
bool GetCurrentDirectory(FilePath* dir) {
|
||||
char system_buffer[PATH_MAX] = "";
|
||||
getcwd(system_buffer, sizeof(system_buffer));
|
||||
*dir = UTF8ToWide(system_buffer);
|
||||
if (!getcwd(system_buffer, sizeof(system_buffer))) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
*dir = FilePath(system_buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
@ -32,11 +33,11 @@ class FileUtilTest : public PlatformTest {
|
||||
PlatformTest::SetUp();
|
||||
// Name a subdirectory of the temp directory.
|
||||
ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_dir_));
|
||||
file_util::AppendToPath(&test_dir_, L"FileUtilTest");
|
||||
test_dir_ = test_dir_.Append(FILE_PATH_LITERAL("FileUtilTest"));
|
||||
|
||||
// Create a fresh, empty copy of this directory.
|
||||
file_util::Delete(test_dir_, true);
|
||||
file_util::CreateDirectory(test_dir_.c_str());
|
||||
file_util::CreateDirectory(test_dir_);
|
||||
}
|
||||
virtual void TearDown() {
|
||||
PlatformTest::TearDown();
|
||||
@ -46,7 +47,7 @@ class FileUtilTest : public PlatformTest {
|
||||
}
|
||||
|
||||
// the path to temporary directory used to contain the test operations
|
||||
std::wstring test_dir_;
|
||||
FilePath test_dir_;
|
||||
};
|
||||
|
||||
// Collects all the results from the given file enumerator, and provides an
|
||||
@ -56,43 +57,44 @@ class FindResultCollector {
|
||||
FindResultCollector(file_util::FileEnumerator& enumerator) {
|
||||
std::wstring cur_file;
|
||||
while (!(cur_file = enumerator.Next()).empty()) {
|
||||
FilePath::StringType path = FilePath::FromWStringHack(cur_file).value();
|
||||
// The file should not be returned twice.
|
||||
EXPECT_TRUE(files_.end() == files_.find(cur_file))
|
||||
EXPECT_TRUE(files_.end() == files_.find(path))
|
||||
<< "Same file returned twice";
|
||||
|
||||
// Save for later.
|
||||
files_.insert(cur_file);
|
||||
files_.insert(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the enumerator found the file.
|
||||
bool HasFile(const std::wstring& file) const {
|
||||
return files_.find(file) != files_.end();
|
||||
bool HasFile(const FilePath& file) const {
|
||||
return files_.find(file.value()) != files_.end();
|
||||
}
|
||||
|
||||
|
||||
int size() {
|
||||
return static_cast<int>(files_.size());
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::wstring> files_;
|
||||
std::set<FilePath::StringType> files_;
|
||||
};
|
||||
|
||||
// Simple function to dump some text into a new file.
|
||||
void CreateTextFile(const std::wstring& filename,
|
||||
void CreateTextFile(const FilePath& filename,
|
||||
const std::wstring& contents) {
|
||||
std::ofstream file;
|
||||
file.open(WideToUTF8(filename).c_str());
|
||||
file.open(WideToUTF8(filename.ToWStringHack()).c_str());
|
||||
ASSERT_TRUE(file.is_open());
|
||||
file << contents;
|
||||
file.close();
|
||||
}
|
||||
|
||||
// Simple function to take out some text from a file.
|
||||
std::wstring ReadTextFile(const std::wstring& filename) {
|
||||
std::wstring ReadTextFile(const FilePath& filename) {
|
||||
wchar_t contents[64];
|
||||
std::wifstream file;
|
||||
file.open(WideToUTF8(filename).c_str());
|
||||
file.open(WideToUTF8(filename.ToWStringHack()).c_str());
|
||||
EXPECT_TRUE(file.is_open());
|
||||
file.getline(contents, 64);
|
||||
file.close();
|
||||
@ -310,8 +312,7 @@ TEST_F(FileUtilTest, GetDirectoryFromPath) {
|
||||
#if defined OS_WIN
|
||||
TEST_F(FileUtilTest, CountFilesCreatedAfter) {
|
||||
// Create old file (that we don't want to count)
|
||||
std::wstring old_file_name = test_dir_;
|
||||
file_util::AppendToPath(&old_file_name, L"Old File.txt");
|
||||
FilePath old_file_name = test_dir_.Append(L"Old File.txt");
|
||||
CreateTextFile(old_file_name, L"Just call me Mr. Creakybits");
|
||||
|
||||
// Age to perfection
|
||||
@ -320,19 +321,21 @@ TEST_F(FileUtilTest, CountFilesCreatedAfter) {
|
||||
// Establish our cutoff time
|
||||
FILETIME test_start_time;
|
||||
GetSystemTimeAsFileTime(&test_start_time);
|
||||
EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_, test_start_time));
|
||||
EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_.value(),
|
||||
test_start_time));
|
||||
|
||||
// Create a new file (that we do want to count)
|
||||
std::wstring new_file_name = test_dir_;
|
||||
file_util::AppendToPath(&new_file_name, L"New File.txt");
|
||||
FilePath new_file_name = test_dir_.Append(L"New File.txt");
|
||||
CreateTextFile(new_file_name, L"Waaaaaaaaaaaaaah.");
|
||||
|
||||
// We should see only the new file.
|
||||
EXPECT_EQ(1, file_util::CountFilesCreatedAfter(test_dir_, test_start_time));
|
||||
EXPECT_EQ(1, file_util::CountFilesCreatedAfter(test_dir_.value(),
|
||||
test_start_time));
|
||||
|
||||
// Delete new file, we should see no files after cutoff now
|
||||
EXPECT_TRUE(file_util::Delete(new_file_name, false));
|
||||
EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_, test_start_time));
|
||||
EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_.value(),
|
||||
test_start_time));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -340,23 +343,20 @@ TEST_F(FileUtilTest, CountFilesCreatedAfter) {
|
||||
// the recursion flag. Also coincidentally tests PathExists.
|
||||
TEST_F(FileUtilTest, Delete) {
|
||||
// Create a file
|
||||
std::wstring file_name = test_dir_;
|
||||
file_util::AppendToPath(&file_name, L"Test File.txt");
|
||||
FilePath file_name = test_dir_.Append(FILE_PATH_LITERAL("Test File.txt"));
|
||||
CreateTextFile(file_name, L"I'm cannon fodder.");
|
||||
|
||||
ASSERT_TRUE(file_util::PathExists(file_name));
|
||||
|
||||
std::wstring subdir_path = test_dir_;
|
||||
file_util::AppendToPath(&subdir_path, L"Subdirectory");
|
||||
file_util::CreateDirectory(subdir_path.c_str());
|
||||
FilePath subdir_path = test_dir_.Append(FILE_PATH_LITERAL("Subdirectory"));
|
||||
file_util::CreateDirectory(subdir_path);
|
||||
|
||||
ASSERT_TRUE(file_util::PathExists(subdir_path));
|
||||
|
||||
std::wstring directory_contents = test_dir_;
|
||||
FilePath directory_contents = test_dir_;
|
||||
#if defined(OS_WIN)
|
||||
// TODO(erikkay): see if anyone's actually using this feature of the API
|
||||
file_util::AppendToPath(&directory_contents, L"*");
|
||||
|
||||
directory_contents = directory_contents.Append(FILE_PATH_LITERAL("*"));
|
||||
// Delete non-recursively and check that only the file is deleted
|
||||
ASSERT_TRUE(file_util::Delete(directory_contents, false));
|
||||
EXPECT_FALSE(file_util::PathExists(file_name));
|
||||
@ -371,22 +371,21 @@ TEST_F(FileUtilTest, Delete) {
|
||||
|
||||
TEST_F(FileUtilTest, Move) {
|
||||
// Create a directory
|
||||
std::wstring dir_name_from(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_from, L"Move_From_Subdir");
|
||||
file_util::CreateDirectory(dir_name_from.c_str());
|
||||
FilePath dir_name_from =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("Move_From_Subdir"));
|
||||
file_util::CreateDirectory(dir_name_from);
|
||||
ASSERT_TRUE(file_util::PathExists(dir_name_from));
|
||||
|
||||
// Create a file under the directory
|
||||
std::wstring file_name_from(dir_name_from);
|
||||
file_util::AppendToPath(&file_name_from, L"Move_Test_File.txt");
|
||||
FilePath file_name_from =
|
||||
dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
|
||||
CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
|
||||
ASSERT_TRUE(file_util::PathExists(file_name_from));
|
||||
|
||||
// Move the directory
|
||||
std::wstring dir_name_to(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_to, L"Move_To_Subdir");
|
||||
std::wstring file_name_to(dir_name_to);
|
||||
file_util::AppendToPath(&file_name_to, L"Move_Test_File.txt");
|
||||
FilePath dir_name_to = test_dir_.Append(FILE_PATH_LITERAL("Move_To_Subdir"));
|
||||
FilePath file_name_to =
|
||||
dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
|
||||
|
||||
ASSERT_FALSE(file_util::PathExists(dir_name_to));
|
||||
|
||||
@ -401,38 +400,38 @@ TEST_F(FileUtilTest, Move) {
|
||||
|
||||
TEST_F(FileUtilTest, CopyDirectoryRecursively) {
|
||||
// Create a directory.
|
||||
std::wstring dir_name_from(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_from, L"Copy_From_Subdir");
|
||||
file_util::CreateDirectory(dir_name_from.c_str());
|
||||
FilePath dir_name_from =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
|
||||
file_util::CreateDirectory(dir_name_from);
|
||||
ASSERT_TRUE(file_util::PathExists(dir_name_from));
|
||||
|
||||
// Create a file under the directory.
|
||||
std::wstring file_name_from(dir_name_from);
|
||||
file_util::AppendToPath(&file_name_from, L"Copy_Test_File.txt");
|
||||
FilePath file_name_from =
|
||||
dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
|
||||
ASSERT_TRUE(file_util::PathExists(file_name_from));
|
||||
|
||||
// Create a subdirectory.
|
||||
std::wstring subdir_name_from(dir_name_from);
|
||||
file_util::AppendToPath(&subdir_name_from, L"Subdir");
|
||||
file_util::CreateDirectory(subdir_name_from.c_str());
|
||||
FilePath subdir_name_from =
|
||||
dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
|
||||
file_util::CreateDirectory(subdir_name_from);
|
||||
ASSERT_TRUE(file_util::PathExists(subdir_name_from));
|
||||
|
||||
// Create a file under the subdirectory.
|
||||
std::wstring file_name2_from(subdir_name_from);
|
||||
file_util::AppendToPath(&file_name2_from, L"Copy_Test_File.txt");
|
||||
FilePath file_name2_from =
|
||||
subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
|
||||
ASSERT_TRUE(file_util::PathExists(file_name2_from));
|
||||
|
||||
// Copy the directory recursively.
|
||||
std::wstring dir_name_to(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_to, L"Copy_To_Subdir");
|
||||
std::wstring file_name_to(dir_name_to);
|
||||
file_util::AppendToPath(&file_name_to, L"Copy_Test_File.txt");
|
||||
std::wstring subdir_name_to(dir_name_to);
|
||||
file_util::AppendToPath(&subdir_name_to, L"Subdir");
|
||||
std::wstring file_name2_to(subdir_name_to);
|
||||
file_util::AppendToPath(&file_name2_to, L"Copy_Test_File.txt");
|
||||
FilePath dir_name_to =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
|
||||
FilePath file_name_to =
|
||||
dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
FilePath subdir_name_to =
|
||||
dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
|
||||
FilePath file_name2_to =
|
||||
subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
|
||||
ASSERT_FALSE(file_util::PathExists(dir_name_to));
|
||||
|
||||
@ -451,36 +450,36 @@ TEST_F(FileUtilTest, CopyDirectoryRecursively) {
|
||||
|
||||
TEST_F(FileUtilTest, CopyDirectory) {
|
||||
// Create a directory.
|
||||
std::wstring dir_name_from(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_from, L"Copy_From_Subdir");
|
||||
file_util::CreateDirectory(dir_name_from.c_str());
|
||||
FilePath dir_name_from =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
|
||||
file_util::CreateDirectory(dir_name_from);
|
||||
ASSERT_TRUE(file_util::PathExists(dir_name_from));
|
||||
|
||||
// Create a file under the directory.
|
||||
std::wstring file_name_from(dir_name_from);
|
||||
file_util::AppendToPath(&file_name_from, L"Copy_Test_File.txt");
|
||||
FilePath file_name_from =
|
||||
dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
|
||||
ASSERT_TRUE(file_util::PathExists(file_name_from));
|
||||
|
||||
// Create a subdirectory.
|
||||
std::wstring subdir_name_from(dir_name_from);
|
||||
file_util::AppendToPath(&subdir_name_from, L"Subdir");
|
||||
file_util::CreateDirectory(subdir_name_from.c_str());
|
||||
FilePath subdir_name_from =
|
||||
dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
|
||||
file_util::CreateDirectory(subdir_name_from);
|
||||
ASSERT_TRUE(file_util::PathExists(subdir_name_from));
|
||||
|
||||
// Create a file under the subdirectory.
|
||||
std::wstring file_name2_from(subdir_name_from);
|
||||
file_util::AppendToPath(&file_name2_from, L"Copy_Test_File.txt");
|
||||
FilePath file_name2_from =
|
||||
subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
|
||||
ASSERT_TRUE(file_util::PathExists(file_name2_from));
|
||||
|
||||
// Copy the directory not recursively.
|
||||
std::wstring dir_name_to(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_to, L"Copy_To_Subdir");
|
||||
std::wstring file_name_to(dir_name_to);
|
||||
file_util::AppendToPath(&file_name_to, L"Copy_Test_File.txt");
|
||||
std::wstring subdir_name_to(dir_name_to);
|
||||
file_util::AppendToPath(&subdir_name_to, L"Subdir");
|
||||
FilePath dir_name_to =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
|
||||
FilePath file_name_to =
|
||||
dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
FilePath subdir_name_to =
|
||||
dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
|
||||
|
||||
ASSERT_FALSE(file_util::PathExists(dir_name_to));
|
||||
|
||||
@ -498,29 +497,29 @@ TEST_F(FileUtilTest, CopyDirectory) {
|
||||
|
||||
TEST_F(FileUtilTest, CopyFile) {
|
||||
// Create a directory
|
||||
std::wstring dir_name_from(test_dir_);
|
||||
file_util::AppendToPath(&dir_name_from, L"Copy_From_Subdir");
|
||||
file_util::CreateDirectory(dir_name_from.c_str());
|
||||
FilePath dir_name_from =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
|
||||
file_util::CreateDirectory(dir_name_from);
|
||||
ASSERT_TRUE(file_util::PathExists(dir_name_from));
|
||||
|
||||
// Create a file under the directory
|
||||
std::wstring file_name_from(dir_name_from);
|
||||
file_util::AppendToPath(&file_name_from, L"Copy_Test_File.txt");
|
||||
FilePath file_name_from =
|
||||
dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
|
||||
const std::wstring file_contents(L"Gooooooooooooooooooooogle");
|
||||
CreateTextFile(file_name_from, file_contents);
|
||||
ASSERT_TRUE(file_util::PathExists(file_name_from));
|
||||
|
||||
// Copy the file.
|
||||
std::wstring dest_file(dir_name_from);
|
||||
file_util::AppendToPath(&dest_file, L"DestFile.txt");
|
||||
FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt"));
|
||||
ASSERT_TRUE(file_util::CopyFile(file_name_from, dest_file));
|
||||
|
||||
// Copy the file to another location using '..' in the path.
|
||||
std::wstring dest_file2(dir_name_from);
|
||||
std::wstring dest_file2(dir_name_from.ToWStringHack());
|
||||
file_util::AppendToPath(&dest_file2, L"..");
|
||||
file_util::AppendToPath(&dest_file2, L"DestFile.txt");
|
||||
ASSERT_TRUE(file_util::CopyFile(file_name_from, dest_file2));
|
||||
std::wstring dest_file2_test(dir_name_from);
|
||||
ASSERT_TRUE(file_util::CopyFile(file_name_from,
|
||||
FilePath::FromWStringHack(dest_file2)));
|
||||
std::wstring dest_file2_test(dir_name_from.ToWStringHack());
|
||||
file_util::UpOneDirectory(&dest_file2_test);
|
||||
file_util::AppendToPath(&dest_file2_test, L"DestFile.txt");
|
||||
|
||||
@ -529,15 +528,15 @@ TEST_F(FileUtilTest, CopyFile) {
|
||||
EXPECT_TRUE(file_util::PathExists(dest_file));
|
||||
const std::wstring read_contents = ReadTextFile(dest_file);
|
||||
EXPECT_EQ(file_contents, read_contents);
|
||||
EXPECT_TRUE(file_util::PathExists(dest_file2_test));
|
||||
EXPECT_TRUE(file_util::PathExists(dest_file2));
|
||||
EXPECT_TRUE(file_util::PathExists(
|
||||
FilePath::FromWStringHack(dest_file2_test)));
|
||||
EXPECT_TRUE(file_util::PathExists(FilePath::FromWStringHack(dest_file2)));
|
||||
}
|
||||
|
||||
// TODO(erikkay): implement
|
||||
#if defined(OS_WIN)
|
||||
TEST_F(FileUtilTest, GetFileCreationLocalTime) {
|
||||
std::wstring file_name = test_dir_;
|
||||
file_util::AppendToPath(&file_name, L"Test File.txt");
|
||||
FilePath file_name = test_dir_.Append(L"Test File.txt");
|
||||
|
||||
SYSTEMTIME start_time;
|
||||
GetLocalTime(&start_time);
|
||||
@ -548,7 +547,7 @@ TEST_F(FileUtilTest, GetFileCreationLocalTime) {
|
||||
GetLocalTime(&end_time);
|
||||
|
||||
SYSTEMTIME file_creation_time;
|
||||
file_util::GetFileCreationLocalTime(file_name, &file_creation_time);
|
||||
file_util::GetFileCreationLocalTime(file_name.value(), &file_creation_time);
|
||||
|
||||
FILETIME start_filetime;
|
||||
SystemTimeToFileTime(&start_time, &start_filetime);
|
||||
@ -565,46 +564,46 @@ TEST_F(FileUtilTest, GetFileCreationLocalTime) {
|
||||
"creation time: " << FileTimeAsUint64(file_creation_filetime) << ", " <<
|
||||
"end time: " << FileTimeAsUint64(end_filetime);
|
||||
|
||||
ASSERT_TRUE(DeleteFile(file_name.c_str()));
|
||||
ASSERT_TRUE(DeleteFile(file_name.value().c_str()));
|
||||
}
|
||||
#endif
|
||||
|
||||
// file_util winds up using autoreleased objects on the Mac, so this needs
|
||||
// to be a PlatformTest
|
||||
// to be a PlatformTest.
|
||||
typedef PlatformTest ReadOnlyFileUtilTest;
|
||||
|
||||
TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
|
||||
std::wstring data_dir;
|
||||
FilePath data_dir;
|
||||
ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir));
|
||||
file_util::AppendToPath(&data_dir, L"base");
|
||||
file_util::AppendToPath(&data_dir, L"data");
|
||||
file_util::AppendToPath(&data_dir, L"file_util_unittest");
|
||||
data_dir = data_dir.Append(FILE_PATH_LITERAL("base"))
|
||||
.Append(FILE_PATH_LITERAL("data"))
|
||||
.Append(FILE_PATH_LITERAL("file_util_unittest"));
|
||||
ASSERT_TRUE(file_util::PathExists(data_dir));
|
||||
|
||||
std::wstring original_file = data_dir;
|
||||
file_util::AppendToPath(&original_file, L"original.txt");
|
||||
std::wstring same_file = data_dir;
|
||||
file_util::AppendToPath(&same_file, L"same.txt");
|
||||
std::wstring same_length_file = data_dir;
|
||||
file_util::AppendToPath(&same_length_file, L"same_length.txt");
|
||||
std::wstring different_file = data_dir;
|
||||
file_util::AppendToPath(&different_file, L"different.txt");
|
||||
std::wstring different_first_file = data_dir;
|
||||
file_util::AppendToPath(&different_first_file, L"different_first.txt");
|
||||
std::wstring different_last_file = data_dir;
|
||||
file_util::AppendToPath(&different_last_file, L"different_last.txt");
|
||||
std::wstring empty1_file = data_dir;
|
||||
file_util::AppendToPath(&empty1_file, L"empty1.txt");
|
||||
std::wstring empty2_file = data_dir;
|
||||
file_util::AppendToPath(&empty2_file, L"empty2.txt");
|
||||
std::wstring shortened_file = data_dir;
|
||||
file_util::AppendToPath(&shortened_file, L"shortened.txt");
|
||||
std::wstring binary_file = data_dir;
|
||||
file_util::AppendToPath(&binary_file, L"binary_file.bin");
|
||||
std::wstring binary_file_same = data_dir;
|
||||
file_util::AppendToPath(&binary_file_same, L"binary_file_same.bin");
|
||||
std::wstring binary_file_diff = data_dir;
|
||||
file_util::AppendToPath(&binary_file_diff, L"binary_file_diff.bin");
|
||||
FilePath original_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("original.txt"));
|
||||
FilePath same_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("same.txt"));
|
||||
FilePath same_length_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("same_length.txt"));
|
||||
FilePath different_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("different.txt"));
|
||||
FilePath different_first_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
|
||||
FilePath different_last_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
|
||||
FilePath empty1_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
|
||||
FilePath empty2_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
|
||||
FilePath shortened_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
|
||||
FilePath binary_file =
|
||||
data_dir.Append(FILE_PATH_LITERAL("binary_file.bin"));
|
||||
FilePath binary_file_same =
|
||||
data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin"));
|
||||
FilePath binary_file_diff =
|
||||
data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin"));
|
||||
|
||||
EXPECT_TRUE(file_util::ContentsEqual(original_file, original_file));
|
||||
EXPECT_TRUE(file_util::ContentsEqual(original_file, same_file));
|
||||
@ -623,12 +622,10 @@ TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
|
||||
// We don't need equivalent functionality outside of Windows.
|
||||
#if defined(OS_WIN)
|
||||
TEST_F(FileUtilTest, ResolveShortcutTest) {
|
||||
std::wstring target_file = test_dir_;
|
||||
file_util::AppendToPath(&target_file, L"Target.txt");
|
||||
FilePath target_file = test_dir_.Append(L"Target.txt");
|
||||
CreateTextFile(target_file, L"This is the target.");
|
||||
|
||||
std::wstring link_file = test_dir_;
|
||||
file_util::AppendToPath(&link_file, L"Link.lnk");
|
||||
FilePath link_file = test_dir_.Append(L"Link.lnk");
|
||||
|
||||
HRESULT result;
|
||||
IShellLink *shell = NULL;
|
||||
@ -643,11 +640,11 @@ TEST_F(FileUtilTest, ResolveShortcutTest) {
|
||||
result = shell->QueryInterface(IID_IPersistFile,
|
||||
reinterpret_cast<LPVOID*>(&persist));
|
||||
EXPECT_TRUE(SUCCEEDED(result));
|
||||
result = shell->SetPath(target_file.c_str());
|
||||
result = shell->SetPath(target_file.value().c_str());
|
||||
EXPECT_TRUE(SUCCEEDED(result));
|
||||
result = shell->SetDescription(L"ResolveShortcutTest");
|
||||
EXPECT_TRUE(SUCCEEDED(result));
|
||||
result = persist->Save(link_file.c_str(), TRUE);
|
||||
result = persist->Save(link_file.value().c_str(), TRUE);
|
||||
EXPECT_TRUE(SUCCEEDED(result));
|
||||
if (persist)
|
||||
persist->Release();
|
||||
@ -655,38 +652,37 @@ TEST_F(FileUtilTest, ResolveShortcutTest) {
|
||||
shell->Release();
|
||||
|
||||
bool is_solved;
|
||||
is_solved = file_util::ResolveShortcut(&link_file);
|
||||
std::wstring link_file_str = link_file.value();
|
||||
is_solved = file_util::ResolveShortcut(&link_file_str);
|
||||
EXPECT_TRUE(is_solved);
|
||||
std::wstring contents;
|
||||
contents = ReadTextFile(link_file);
|
||||
contents = ReadTextFile(FilePath(link_file_str));
|
||||
EXPECT_EQ(L"This is the target.", contents);
|
||||
|
||||
// Cleaning
|
||||
DeleteFile(target_file.c_str());
|
||||
DeleteFile(link_file.c_str());
|
||||
DeleteFile(target_file.value().c_str());
|
||||
DeleteFile(link_file_str.c_str());
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
TEST_F(FileUtilTest, CreateShortcutTest) {
|
||||
const wchar_t file_contents[] = L"This is another target.";
|
||||
std::wstring target_file = test_dir_;
|
||||
file_util::AppendToPath(&target_file, L"Target1.txt");
|
||||
FilePath target_file = test_dir_.Append(L"Target1.txt");
|
||||
CreateTextFile(target_file, file_contents);
|
||||
|
||||
std::wstring link_file = test_dir_;
|
||||
file_util::AppendToPath(&link_file, L"Link1.lnk");
|
||||
FilePath link_file = test_dir_.Append(L"Link1.lnk");
|
||||
|
||||
CoInitialize(NULL);
|
||||
EXPECT_TRUE(file_util::CreateShortcutLink(target_file.c_str(),
|
||||
link_file.c_str(),
|
||||
EXPECT_TRUE(file_util::CreateShortcutLink(target_file.value().c_str(),
|
||||
link_file.value().c_str(),
|
||||
NULL, NULL, NULL, NULL, 0));
|
||||
std::wstring resolved_name = link_file;
|
||||
std::wstring resolved_name = link_file.value();
|
||||
EXPECT_TRUE(file_util::ResolveShortcut(&resolved_name));
|
||||
std::wstring read_contents = ReadTextFile(resolved_name);
|
||||
std::wstring read_contents = ReadTextFile(FilePath(resolved_name));
|
||||
EXPECT_EQ(file_contents, read_contents);
|
||||
|
||||
DeleteFile(target_file.c_str());
|
||||
DeleteFile(link_file.c_str());
|
||||
DeleteFile(target_file.value().c_str());
|
||||
DeleteFile(link_file.value().c_str());
|
||||
CoUninitialize();
|
||||
}
|
||||
#endif
|
||||
@ -706,13 +702,14 @@ TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
|
||||
}
|
||||
|
||||
TEST_F(FileUtilTest, CreateDirectoryTest) {
|
||||
std::wstring test_root = test_dir_;
|
||||
file_util::AppendToPath(&test_root, L"create_directory_test");
|
||||
std::wstring test_path(test_root);
|
||||
FilePath test_root =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("create_directory_test"));
|
||||
#if defined(OS_WIN)
|
||||
file_util::AppendToPath(&test_path, L"dir\\tree\\likely\\doesnt\\exist\\");
|
||||
FilePath test_path =
|
||||
test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\"));
|
||||
#elif defined(OS_POSIX)
|
||||
file_util::AppendToPath(&test_path, L"dir/tree/likely/doesnt/exist/");
|
||||
FilePath test_path =
|
||||
test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/"));
|
||||
#endif
|
||||
|
||||
EXPECT_FALSE(file_util::PathExists(test_path));
|
||||
@ -722,7 +719,7 @@ TEST_F(FileUtilTest, CreateDirectoryTest) {
|
||||
EXPECT_TRUE(file_util::CreateDirectory(test_path));
|
||||
|
||||
// Doesn't work to create it on top of a non-dir
|
||||
file_util::AppendToPath(&test_path, L"foobar.txt");
|
||||
test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt"));
|
||||
EXPECT_FALSE(file_util::PathExists(test_path));
|
||||
CreateTextFile(test_path, L"test file");
|
||||
EXPECT_TRUE(file_util::PathExists(test_path));
|
||||
@ -735,16 +732,16 @@ TEST_F(FileUtilTest, CreateDirectoryTest) {
|
||||
|
||||
TEST_F(FileUtilTest, DetectDirectoryTest) {
|
||||
// Check a directory
|
||||
std::wstring test_root = test_dir_;
|
||||
file_util::AppendToPath(&test_root, L"detect_directory_test");
|
||||
FilePath test_root =
|
||||
test_dir_.Append(FILE_PATH_LITERAL("detect_directory_test"));
|
||||
EXPECT_FALSE(file_util::PathExists(test_root));
|
||||
EXPECT_TRUE(file_util::CreateDirectory(test_root));
|
||||
EXPECT_TRUE(file_util::PathExists(test_root));
|
||||
EXPECT_TRUE(file_util::DirectoryExists(test_root));
|
||||
|
||||
// Check a file
|
||||
std::wstring test_path(test_root);
|
||||
file_util::AppendToPath(&test_path, L"foobar.txt");
|
||||
FilePath test_path =
|
||||
test_root.Append(FILE_PATH_LITERAL("foobar.txt"));
|
||||
EXPECT_FALSE(file_util::PathExists(test_path));
|
||||
CreateTextFile(test_path, L"test file");
|
||||
EXPECT_TRUE(file_util::PathExists(test_path));
|
||||
@ -833,41 +830,34 @@ TEST_F(FileUtilTest, ReplaceExtensionTestWithPathSeparators) {
|
||||
|
||||
TEST_F(FileUtilTest, FileEnumeratorTest) {
|
||||
// Test an empty directory.
|
||||
file_util::FileEnumerator f0(test_dir_, true,
|
||||
file_util::FileEnumerator f0(test_dir_.ToWStringHack(), true,
|
||||
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
|
||||
EXPECT_EQ(f0.Next(), L"");
|
||||
EXPECT_EQ(f0.Next(), L"");
|
||||
|
||||
// create the directories
|
||||
std::wstring dir1 = test_dir_;
|
||||
file_util::AppendToPath(&dir1, L"dir1");
|
||||
FilePath dir1 = test_dir_.Append(FILE_PATH_LITERAL("dir1"));
|
||||
EXPECT_TRUE(file_util::CreateDirectory(dir1));
|
||||
std::wstring dir2 = test_dir_;
|
||||
file_util::AppendToPath(&dir2, L"dir2");
|
||||
FilePath dir2 = test_dir_.Append(FILE_PATH_LITERAL("dir2"));
|
||||
EXPECT_TRUE(file_util::CreateDirectory(dir2));
|
||||
std::wstring dir2inner = dir2;
|
||||
file_util::AppendToPath(&dir2inner, L"inner");
|
||||
FilePath dir2inner = dir2.Append(FILE_PATH_LITERAL("inner"));
|
||||
EXPECT_TRUE(file_util::CreateDirectory(dir2inner));
|
||||
|
||||
|
||||
// create the files
|
||||
std::wstring dir2file = dir2;
|
||||
file_util::AppendToPath(&dir2file, L"dir2file.txt");
|
||||
FilePath dir2file = dir2.Append(FILE_PATH_LITERAL("dir2file.txt"));
|
||||
CreateTextFile(dir2file, L"");
|
||||
std::wstring dir2innerfile = dir2inner;
|
||||
file_util::AppendToPath(&dir2innerfile, L"innerfile.txt");
|
||||
FilePath dir2innerfile = dir2inner.Append(FILE_PATH_LITERAL("innerfile.txt"));
|
||||
CreateTextFile(dir2innerfile, L"");
|
||||
std::wstring file1 = test_dir_;
|
||||
file_util::AppendToPath(&file1, L"file1.txt");
|
||||
FilePath file1 = test_dir_.Append(FILE_PATH_LITERAL("file1.txt"));
|
||||
CreateTextFile(file1, L"");
|
||||
std::wstring file2_rel = dir2;
|
||||
file_util::AppendToPath(&file2_rel, L"..");
|
||||
file_util::AppendToPath(&file2_rel, L"file2.txt");
|
||||
FilePath file2_rel =
|
||||
dir2.Append(FilePath::kParentDirectory)
|
||||
.Append(FILE_PATH_LITERAL("file2.txt"));
|
||||
CreateTextFile(file2_rel, L"");
|
||||
std::wstring file2_abs = test_dir_;
|
||||
file_util::AppendToPath(&file2_abs, L"file2.txt");
|
||||
FilePath file2_abs = test_dir_.Append(FILE_PATH_LITERAL("file2.txt"));
|
||||
|
||||
// Only enumerate files.
|
||||
file_util::FileEnumerator f1(test_dir_, true,
|
||||
file_util::FileEnumerator f1(test_dir_.ToWStringHack(), true,
|
||||
file_util::FileEnumerator::FILES);
|
||||
FindResultCollector c1(f1);
|
||||
EXPECT_TRUE(c1.HasFile(file1));
|
||||
@ -877,7 +867,7 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
|
||||
EXPECT_EQ(c1.size(), 4);
|
||||
|
||||
// Only enumerate directories.
|
||||
file_util::FileEnumerator f2(test_dir_, true,
|
||||
file_util::FileEnumerator f2(test_dir_.ToWStringHack(), true,
|
||||
file_util::FileEnumerator::DIRECTORIES);
|
||||
FindResultCollector c2(f2);
|
||||
EXPECT_TRUE(c2.HasFile(dir1));
|
||||
@ -887,14 +877,14 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
|
||||
|
||||
// Only enumerate directories non-recursively.
|
||||
file_util::FileEnumerator f2_non_recursive(
|
||||
test_dir_, false, file_util::FileEnumerator::DIRECTORIES);
|
||||
test_dir_.ToWStringHack(), false, file_util::FileEnumerator::DIRECTORIES);
|
||||
FindResultCollector c2_non_recursive(f2_non_recursive);
|
||||
EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
|
||||
EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
|
||||
EXPECT_EQ(c2_non_recursive.size(), 2);
|
||||
|
||||
// Enumerate files and directories.
|
||||
file_util::FileEnumerator f3(test_dir_, true,
|
||||
file_util::FileEnumerator f3(test_dir_.ToWStringHack(), true,
|
||||
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
|
||||
FindResultCollector c3(f3);
|
||||
EXPECT_TRUE(c3.HasFile(dir1));
|
||||
@ -907,7 +897,7 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
|
||||
EXPECT_EQ(c3.size(), 7);
|
||||
|
||||
// Non-recursive operation.
|
||||
file_util::FileEnumerator f4(test_dir_, false,
|
||||
file_util::FileEnumerator f4(test_dir_.ToWStringHack(), false,
|
||||
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
|
||||
FindResultCollector c4(f4);
|
||||
EXPECT_TRUE(c4.HasFile(dir2));
|
||||
@ -917,7 +907,7 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
|
||||
EXPECT_EQ(c4.size(), 4);
|
||||
|
||||
// Enumerate with a pattern.
|
||||
file_util::FileEnumerator f5(test_dir_, true,
|
||||
file_util::FileEnumerator f5(test_dir_.ToWStringHack(), true,
|
||||
file_util::FileEnumerator::FILES_AND_DIRECTORIES, L"dir*");
|
||||
FindResultCollector c5(f5);
|
||||
EXPECT_TRUE(c5.HasFile(dir1));
|
||||
@ -929,7 +919,7 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
|
||||
|
||||
// Make sure the destructor closes the find handle while in the middle of a
|
||||
// query to allow TearDown to delete the directory.
|
||||
file_util::FileEnumerator f6(test_dir_, true,
|
||||
file_util::FileEnumerator f6(test_dir_.ToWStringHack(), true,
|
||||
file_util::FileEnumerator::FILES_AND_DIRECTORIES);
|
||||
EXPECT_FALSE(f6.Next().empty()); // Should have found something
|
||||
// (we don't care what).
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/scoped_handle.h"
|
||||
#include "base/string_util.h"
|
||||
@ -32,11 +33,11 @@ std::wstring GetDirectoryFromPath(const std::wstring& path) {
|
||||
return directory;
|
||||
}
|
||||
|
||||
bool AbsolutePath(std::wstring* path) {
|
||||
bool AbsolutePath(FilePath* path) {
|
||||
wchar_t file_path_buf[MAX_PATH];
|
||||
if (!_wfullpath(file_path_buf, path->c_str(), MAX_PATH))
|
||||
if (!_wfullpath(file_path_buf, path->value().c_str(), MAX_PATH))
|
||||
return false;
|
||||
*path = file_path_buf;
|
||||
*path = FilePath(file_path_buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,14 +67,14 @@ int CountFilesCreatedAfter(const std::wstring& path,
|
||||
return file_count;
|
||||
}
|
||||
|
||||
bool Delete(const std::wstring& path, bool recursive) {
|
||||
if (path.length() >= MAX_PATH)
|
||||
bool Delete(const FilePath& path, bool recursive) {
|
||||
if (path.value().length() >= MAX_PATH)
|
||||
return false;
|
||||
|
||||
// If we're not recursing use DeleteFile; it should be faster. DeleteFile
|
||||
// fails if passed a directory though, which is why we fall through on
|
||||
// failure to the SHFileOperation.
|
||||
if (!recursive && DeleteFile(path.c_str()) != 0)
|
||||
if (!recursive && DeleteFile(path.value().c_str()) != 0)
|
||||
return true;
|
||||
|
||||
// SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
|
||||
@ -81,7 +82,7 @@ bool Delete(const std::wstring& path, bool recursive) {
|
||||
// into the rest of the buffer.
|
||||
wchar_t double_terminated_path[MAX_PATH + 1] = {0};
|
||||
#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
|
||||
wcscpy(double_terminated_path, path.c_str());
|
||||
wcscpy(double_terminated_path, path.value().c_str());
|
||||
|
||||
SHFILEOPSTRUCT file_operation = {0};
|
||||
file_operation.wFunc = FO_DELETE;
|
||||
@ -92,29 +93,36 @@ bool Delete(const std::wstring& path, bool recursive) {
|
||||
return (SHFileOperation(&file_operation) == 0);
|
||||
}
|
||||
|
||||
bool Move(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
bool Move(const FilePath& from_path, const FilePath& to_path) {
|
||||
// NOTE: I suspect we could support longer paths, but that would involve
|
||||
// analyzing all our usage of files.
|
||||
if (from_path.length() >= MAX_PATH || to_path.length() >= MAX_PATH)
|
||||
if (from_path.value().length() >= MAX_PATH ||
|
||||
to_path.value().length() >= MAX_PATH) {
|
||||
return false;
|
||||
return (MoveFileEx(from_path.c_str(), to_path.c_str(),
|
||||
}
|
||||
return (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(),
|
||||
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0);
|
||||
}
|
||||
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
|
||||
// NOTE: I suspect we could support longer paths, but that would involve
|
||||
// analyzing all our usage of files.
|
||||
if (from_path.length() >= MAX_PATH || to_path.length() >= MAX_PATH)
|
||||
if (from_path.value().length() >= MAX_PATH ||
|
||||
to_path.value().length() >= MAX_PATH) {
|
||||
return false;
|
||||
return (::CopyFile(from_path.c_str(), to_path.c_str(), false) != 0);
|
||||
}
|
||||
return (::CopyFile(from_path.value().c_str(), to_path.value().c_str(),
|
||||
false) != 0);
|
||||
}
|
||||
|
||||
bool ShellCopy(const std::wstring& from_path, const std::wstring& to_path,
|
||||
bool ShellCopy(const FilePath& from_path, const FilePath& to_path,
|
||||
bool recursive) {
|
||||
// NOTE: I suspect we could support longer paths, but that would involve
|
||||
// analyzing all our usage of files.
|
||||
if (from_path.length() >= MAX_PATH || to_path.length() >= MAX_PATH)
|
||||
if (from_path.value().length() >= MAX_PATH ||
|
||||
to_path.value().length() >= MAX_PATH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
|
||||
// so we have to use wcscpy because wcscpy_s writes non-NULLs
|
||||
@ -122,9 +130,9 @@ bool ShellCopy(const std::wstring& from_path, const std::wstring& to_path,
|
||||
wchar_t double_terminated_path_from[MAX_PATH + 1] = {0};
|
||||
wchar_t double_terminated_path_to[MAX_PATH + 1] = {0};
|
||||
#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
|
||||
wcscpy(double_terminated_path_from, from_path.c_str());
|
||||
wcscpy(double_terminated_path_from, from_path.value().c_str());
|
||||
#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
|
||||
wcscpy(double_terminated_path_to, to_path.c_str());
|
||||
wcscpy(double_terminated_path_to, to_path.value().c_str());
|
||||
|
||||
SHFILEOPSTRUCT file_operation = {0};
|
||||
file_operation.wFunc = FO_COPY;
|
||||
@ -138,7 +146,7 @@ bool ShellCopy(const std::wstring& from_path, const std::wstring& to_path,
|
||||
return (SHFileOperation(&file_operation) == 0);
|
||||
}
|
||||
|
||||
bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
|
||||
bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
|
||||
bool recursive) {
|
||||
if (recursive)
|
||||
return ShellCopy(from_path, to_path, true);
|
||||
@ -154,13 +162,12 @@ bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
|
||||
ShellCopy(from_path, to_path, false);
|
||||
}
|
||||
|
||||
std::wstring directory(from_path);
|
||||
AppendToPath(&directory, L"*.*");
|
||||
FilePath directory = from_path.Append(L"*.*");
|
||||
return ShellCopy(directory, to_path, false);
|
||||
}
|
||||
|
||||
bool PathExists(const std::wstring& path) {
|
||||
return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
|
||||
bool PathExists(const FilePath& path) {
|
||||
return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES);
|
||||
}
|
||||
|
||||
bool PathIsWritable(const std::wstring& path) {
|
||||
@ -176,8 +183,8 @@ bool PathIsWritable(const std::wstring& path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectoryExists(const std::wstring& path) {
|
||||
DWORD fileattr = GetFileAttributes(path.c_str());
|
||||
bool DirectoryExists(const FilePath& path) {
|
||||
DWORD fileattr = GetFileAttributes(path.value().c_str());
|
||||
if (fileattr != INVALID_FILE_ATTRIBUTES)
|
||||
return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
return false;
|
||||
@ -372,13 +379,17 @@ bool IsDirectoryEmpty(const std::wstring& dir_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetTempDir(std::wstring* path) {
|
||||
bool GetTempDir(FilePath* path) {
|
||||
wchar_t temp_path[MAX_PATH + 1];
|
||||
DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
|
||||
if (path_len >= MAX_PATH || path_len <= 0)
|
||||
return false;
|
||||
path->assign(temp_path);
|
||||
TrimTrailingSeparator(path);
|
||||
// TODO(evanm): the old behavior of this function was to always strip the
|
||||
// trailing slash. We duplicate this here, but it shouldn't be necessary
|
||||
// when everyone is using the appropriate FilePath APIs.
|
||||
std::wstring path_str(temp_path);
|
||||
TrimTrailingSeparator(&path_str);
|
||||
*path = FilePath(path_str);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -438,10 +449,10 @@ bool CreateNewTempDirectory(const std::wstring& prefix,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateDirectory(const std::wstring& full_path) {
|
||||
bool CreateDirectory(const FilePath& full_path) {
|
||||
if (DirectoryExists(full_path))
|
||||
return true;
|
||||
int err = SHCreateDirectoryEx(NULL, full_path.c_str(), NULL);
|
||||
int err = SHCreateDirectoryEx(NULL, full_path.value().c_str(), NULL);
|
||||
return err == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -460,6 +471,15 @@ bool GetFileInfo(const std::wstring& file_path, FileInfo* results) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE* OpenFile(const FilePath& filename, const char* mode) {
|
||||
std::wstring w_mode = ASCIIToWide(std::string(mode));
|
||||
FILE* file;
|
||||
if (_wfopen_s(&file, filename.value().c_str(), w_mode.c_str()) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
FILE* OpenFile(const std::string& filename, const char* mode) {
|
||||
FILE* file;
|
||||
if (fopen_s(&file, filename.c_str(), mode) != 0) {
|
||||
@ -469,12 +489,7 @@ FILE* OpenFile(const std::string& filename, const char* mode) {
|
||||
}
|
||||
|
||||
FILE* OpenFile(const std::wstring& filename, const char* mode) {
|
||||
std::wstring w_mode = ASCIIToWide(std::string(mode));
|
||||
FILE* file;
|
||||
if (_wfopen_s(&file, filename.c_str(), w_mode.c_str()) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
return file;
|
||||
return OpenFile(FilePath(filename), mode);
|
||||
}
|
||||
|
||||
int ReadFile(const std::wstring& filename, char* data, int size) {
|
||||
@ -556,14 +571,18 @@ bool RenameFileAndResetSecurityDescriptor(
|
||||
}
|
||||
|
||||
// Gets the current working directory for the process.
|
||||
bool GetCurrentDirectory(std::wstring* dir) {
|
||||
bool GetCurrentDirectory(FilePath* dir) {
|
||||
wchar_t system_buffer[MAX_PATH];
|
||||
system_buffer[0] = 0;
|
||||
DWORD len = ::GetCurrentDirectory(MAX_PATH, system_buffer);
|
||||
if (len == 0 || len > MAX_PATH)
|
||||
return false;
|
||||
*dir = system_buffer;
|
||||
file_util::TrimTrailingSeparator(dir);
|
||||
// TODO(evanm): the old behavior of this function was to always strip the
|
||||
// trailing slash. We duplicate this here, but it shouldn't be necessary
|
||||
// when everyone is using the appropriate FilePath APIs.
|
||||
std::wstring dir_str(system_buffer);
|
||||
file_util::TrimTrailingSeparator(&dir_str);
|
||||
*dir = FilePath(dir_str);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,9 @@
|
||||
|
||||
#include "base/icu_util.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/sys_string_conversions.h"
|
||||
#include "unicode/putil.h"
|
||||
@ -76,10 +77,10 @@ bool Initialize() {
|
||||
// For now, expect the data file to be alongside the executable.
|
||||
// This is sufficient while we work on unit tests, but will eventually
|
||||
// likely live in a data directory.
|
||||
std::wstring data_path;
|
||||
FilePath data_path;
|
||||
bool path_ok = PathService::Get(base::DIR_EXE, &data_path);
|
||||
DCHECK(path_ok);
|
||||
u_setDataDirectory(base::SysWideToNativeMB(data_path).c_str());
|
||||
u_setDataDirectory(data_path.value().c_str());
|
||||
// Only look for the packaged data file;
|
||||
// the default behavior is to look for individual files.
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
@ -10,8 +10,9 @@
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "base/hash_tables.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/hash_tables.h"
|
||||
#include "base/lock.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/singleton.h"
|
||||
@ -30,7 +31,7 @@ namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
typedef base::hash_map<int, std::wstring> PathMap;
|
||||
typedef base::hash_map<int, FilePath> PathMap;
|
||||
typedef base::hash_set<int> PathSet;
|
||||
|
||||
// We keep a linked list of providers. In a debug build we ensure that no two
|
||||
@ -127,7 +128,7 @@ static PathData* GetPathData() {
|
||||
|
||||
|
||||
// static
|
||||
bool PathService::GetFromCache(int key, std::wstring* result) {
|
||||
bool PathService::GetFromCache(int key, FilePath* result) {
|
||||
PathData* path_data = GetPathData();
|
||||
AutoLock scoped_lock(path_data->lock);
|
||||
|
||||
@ -141,7 +142,7 @@ bool PathService::GetFromCache(int key, std::wstring* result) {
|
||||
}
|
||||
|
||||
// static
|
||||
void PathService::AddToCache(int key, const std::wstring& path) {
|
||||
void PathService::AddToCache(int key, const FilePath& path) {
|
||||
PathData* path_data = GetPathData();
|
||||
AutoLock scoped_lock(path_data->lock);
|
||||
// Save the computed path in our cache.
|
||||
@ -152,7 +153,7 @@ void PathService::AddToCache(int key, const std::wstring& path) {
|
||||
// characters). This isn't supported very well by Windows right now, so it is
|
||||
// moot, but we should keep this in mind for the future.
|
||||
// static
|
||||
bool PathService::Get(int key, std::wstring* result) {
|
||||
bool PathService::Get(int key, FilePath* result) {
|
||||
PathData* path_data = GetPathData();
|
||||
DCHECK(path_data);
|
||||
DCHECK(result);
|
||||
@ -165,25 +166,36 @@ bool PathService::Get(int key, std::wstring* result) {
|
||||
if (GetFromCache(key, result))
|
||||
return true;
|
||||
|
||||
std::wstring path;
|
||||
std::wstring path_string;
|
||||
|
||||
// search providers for the requested path
|
||||
// NOTE: it should be safe to iterate here without the lock
|
||||
// since RegisterProvider always prepends.
|
||||
Provider* provider = path_data->providers;
|
||||
while (provider) {
|
||||
if (provider->func(key, &path))
|
||||
if (provider->func(key, &path_string))
|
||||
break;
|
||||
DCHECK(path.empty()) << "provider should not have modified path";
|
||||
DCHECK(path_string.empty()) << "provider should not have modified path";
|
||||
provider = provider->next;
|
||||
}
|
||||
|
||||
if (path.empty())
|
||||
if (path_string.empty())
|
||||
return false;
|
||||
|
||||
FilePath path = FilePath::FromWStringHack(path_string);
|
||||
AddToCache(key, path);
|
||||
|
||||
result->swap(path);
|
||||
*result = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool PathService::Get(int key, std::wstring* result) {
|
||||
// Deprecated compatibility function.
|
||||
FilePath path;
|
||||
if (!Get(key, &path))
|
||||
return false;
|
||||
*result = path.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -211,7 +223,7 @@ bool PathService::Override(int key, const std::wstring& path) {
|
||||
file_util::TrimTrailingSeparator(&file_path);
|
||||
|
||||
AutoLock scoped_lock(path_data->lock);
|
||||
path_data->cache[key] = file_path;
|
||||
path_data->cache[key] = FilePath::FromWStringHack(file_path);
|
||||
path_data->overrides.insert(key);
|
||||
return true;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "base/base_paths.h"
|
||||
|
||||
class FilePath;
|
||||
|
||||
// The path service is a global table mapping keys to file system paths. It is
|
||||
// OK to use this service from multiple threads.
|
||||
//
|
||||
@ -31,6 +33,9 @@ class PathService {
|
||||
//
|
||||
// Returns true if the directory or file was successfully retrieved. On
|
||||
// failure, 'path' will not be changed.
|
||||
static bool Get(int key, FilePath* path);
|
||||
// This version, producing a wstring, is deprecated and only kept around
|
||||
// until we can fix all callers.
|
||||
static bool Get(int key, std::wstring* path);
|
||||
|
||||
// Overrides the path to a special directory or file. This cannot be used to
|
||||
@ -66,8 +71,8 @@ class PathService {
|
||||
int key_start,
|
||||
int key_end);
|
||||
private:
|
||||
static bool GetFromCache(int key, std::wstring* path);
|
||||
static void AddToCache(int key, const std::wstring& path);
|
||||
static bool GetFromCache(int key, FilePath* path);
|
||||
static void AddToCache(int key, const FilePath& path);
|
||||
|
||||
};
|
||||
|
||||
|
@ -2,10 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/path_service.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/platform_test.h"
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win_util.h"
|
||||
@ -18,9 +20,9 @@ namespace {
|
||||
// Returns true if PathService::Get returns true and sets the path parameter
|
||||
// to non-empty for the given PathService::DirType enumeration value.
|
||||
bool ReturnsValidPath(int dir_type) {
|
||||
std::wstring path;
|
||||
FilePath path;
|
||||
bool result = PathService::Get(dir_type, &path);
|
||||
return result && !path.empty() && file_util::PathExists(path);
|
||||
return result && !path.value().empty() && file_util::PathExists(path);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "base/trace_event.h"
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/platform_thread.h"
|
||||
@ -21,7 +22,8 @@ static const char* kEventTypeNames[] = {
|
||||
"INSTANT"
|
||||
};
|
||||
|
||||
static const wchar_t* kLogFileName = L"trace_%d.log";
|
||||
static const FilePath::CharType* kLogFileName =
|
||||
FILE_PATH_LITERAL("trace_%d.log");
|
||||
|
||||
TraceLog::TraceLog() : enabled_(false), log_file_(NULL) {
|
||||
ProcessHandle proc = process_util::GetCurrentProcessHandle();
|
||||
@ -83,15 +85,16 @@ void TraceLog::CloseLogFile() {
|
||||
}
|
||||
|
||||
bool TraceLog::OpenLogFile() {
|
||||
std::wstring pid_filename =
|
||||
StringPrintf(kLogFileName, process_util::GetCurrentProcId());
|
||||
std::wstring log_file_name;
|
||||
PathService::Get(base::DIR_EXE, &log_file_name);
|
||||
file_util::AppendToPath(&log_file_name, pid_filename);
|
||||
log_file_ = file_util::OpenFile(log_file_name, "a");
|
||||
FilePath::StringType pid_filename =
|
||||
StringPrintf(kLogFileName, process_util::GetCurrentProcId());
|
||||
FilePath log_file_path;
|
||||
if (!PathService::Get(base::DIR_EXE, &log_file_path))
|
||||
return false;
|
||||
log_file_path = log_file_path.Append(pid_filename);
|
||||
log_file_ = file_util::OpenFile(log_file_path, "a");
|
||||
if (!log_file_) {
|
||||
// try the current directory
|
||||
log_file_ = file_util::OpenFile(pid_filename, "a");
|
||||
log_file_ = file_util::OpenFile(FilePath(pid_filename), "a");
|
||||
if (!log_file_) {
|
||||
return false;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ class DownloadTest : public UITest {
|
||||
// Find the path on the client.
|
||||
std::wstring file_on_client(download_prefix_);
|
||||
file_on_client.append(client_filename);
|
||||
EXPECT_PRED1(file_util::PathExists, file_on_client);
|
||||
EXPECT_TRUE(file_util::PathExists(file_on_client));
|
||||
|
||||
// Find the path on the server.
|
||||
std::wstring file_on_server;
|
||||
@ -84,14 +84,15 @@ class DownloadTest : public UITest {
|
||||
ASSERT_TRUE(file_util::PathExists(file_on_server));
|
||||
|
||||
// Check that we downloaded the file correctly.
|
||||
EXPECT_PRED2(file_util::ContentsEqual, file_on_server, file_on_client);
|
||||
EXPECT_TRUE(file_util::ContentsEqual(file_on_server,
|
||||
file_on_client));
|
||||
|
||||
// Check if the Zone Identifier is correclty set.
|
||||
if (VolumeSupportsADS(file_on_client))
|
||||
CheckZoneIdentifier(file_on_client);
|
||||
|
||||
// Delete the client copy of the file.
|
||||
EXPECT_PRED2(file_util::Delete, file_on_client, false);
|
||||
EXPECT_TRUE(file_util::Delete(file_on_client, false));
|
||||
}
|
||||
|
||||
void CleanUpDownload(const std::wstring& file) {
|
||||
@ -131,7 +132,7 @@ class DownloadTest : public UITest {
|
||||
}
|
||||
|
||||
std::wstring filename = file_util::GetFilenameFromPath(url);
|
||||
EXPECT_PRED1(file_util::PathExists, download_prefix_ + filename);
|
||||
EXPECT_TRUE(file_util::PathExists(download_prefix_ + filename));
|
||||
|
||||
// Delete the file we just downloaded.
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
|
@ -43,7 +43,7 @@ class SavePageTest : public UITest {
|
||||
EXPECT_TRUE(file_util::GetFileSize(client_file, &client_file_size));
|
||||
EXPECT_TRUE(file_util::GetFileSize(server_file_name, &server_file_size));
|
||||
EXPECT_EQ(client_file_size, server_file_size);
|
||||
EXPECT_PRED2(file_util::ContentsEqual, client_file, server_file_name);
|
||||
EXPECT_TRUE(file_util::ContentsEqual(client_file, server_file_name));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(DieFileDie(client_file, false));
|
||||
|
Reference in New Issue
Block a user