diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/file_util.h | 14 | ||||
-rw-r--r-- | base/file_util_posix.cc | 48 | ||||
-rw-r--r-- | base/file_util_win.cc | 9 |
3 files changed, 52 insertions, 19 deletions
diff --git a/base/file_util.h b/base/file_util.h index e274d6a..0103003 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -14,6 +14,7 @@ #include <windows.h> #elif defined(OS_POSIX) #include <fts.h> +#include <sys/stat.h> #endif #include <stdio.h> @@ -323,6 +324,15 @@ bool SetCurrentDirectory(const std::wstring& current_directory); // program where latency does not matter. This class is blocking. class FileEnumerator { public: +#if defined(OS_WIN) + typedef WIN32_FIND_DATA FindInfo; +#elif defined(OS_POSIX) + typedef struct { + struct stat stat; + std::string filename; + } FindInfo; +#endif + enum FILE_TYPE { FILES = 0x1, DIRECTORIES = 0x2, @@ -361,6 +371,9 @@ class FileEnumerator { // Returns an empty string if there are no more results. std::wstring Next(); + // Write the file info into |info|. + void GetFindInfo(FindInfo* info); + private: std::wstring root_path_; bool recursive_; @@ -380,6 +393,7 @@ class FileEnumerator { HANDLE find_handle_; #elif defined(OS_POSIX) FTS* fts_; + FTSENT* fts_ent_; #endif DISALLOW_EVIL_CONSTRUCTORS(FileEnumerator); diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 1afb573..5760a68 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -409,6 +409,16 @@ FileEnumerator::~FileEnumerator() { fts_close(fts_); } +void FileEnumerator::GetFindInfo(FindInfo* info) { + DCHECK(info); + + if (!is_in_find_op_) + return; + + memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat)); + info->filename.assign(fts_ent_->fts_name); +} + // As it stands, this method calls itself recursively when the next item of // the fts enumeration doesn't match (type, pattern, etc.). In the case of // large directories with many files this can be quite deep. @@ -417,12 +427,12 @@ std::wstring FileEnumerator::Next() { if (!is_in_find_op_) { if (pending_paths_.empty()) return std::wstring(); - + // The last find FindFirstFile operation is done, prepare a new one. root_path_ = pending_paths_.top(); TrimTrailingSeparator(&root_path_); pending_paths_.pop(); - + // Start a new find operation. int ftsflags = FTS_LOGICAL; char top_dir[PATH_MAX]; @@ -433,41 +443,41 @@ std::wstring FileEnumerator::Next() { return Next(); is_in_find_op_ = true; } - - FTSENT* fts_ent = fts_read(fts_); - if (fts_ent == NULL) { + + fts_ent_ = fts_read(fts_); + if (fts_ent_ == NULL) { fts_close(fts_); fts_ = NULL; is_in_find_op_ = false; return Next(); } - + // Level 0 is the top, which is always skipped. - if (fts_ent->fts_level == 0) + if (fts_ent_->fts_level == 0) return Next(); - + // Patterns are only matched on the items in the top-most directory. // (see Windows implementation) - if (fts_ent->fts_level == 1 && pattern_.length() > 0) { - if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent->fts_path, 0) != 0) { - if (fts_ent->fts_info == FTS_D) - fts_set(fts_, fts_ent, FTS_SKIP); + if (fts_ent_->fts_level == 1 && pattern_.length() > 0) { + if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent_->fts_path, 0) != 0) { + if (fts_ent_->fts_info == FTS_D) + fts_set(fts_, fts_ent_, FTS_SKIP); return Next(); } } - - std::wstring cur_file(UTF8ToWide(fts_ent->fts_path)); - if (fts_ent->fts_info == FTS_D) { + + std::wstring cur_file(UTF8ToWide(fts_ent_->fts_path)); + if (fts_ent_->fts_info == FTS_D) { // If not recursive, then prune children. if (!recursive_) - fts_set(fts_, fts_ent, FTS_SKIP); + fts_set(fts_, fts_ent_, FTS_SKIP); return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); - } else if (fts_ent->fts_info == FTS_F) { + } else if (fts_ent_->fts_info == FTS_F) { return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); } // TODO(erikkay) - verify that the other fts_info types aren't interesting return Next(); } - - + + } // namespace file_util diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 459e3a8..fdfd6dd 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -625,6 +625,15 @@ FileEnumerator::~FileEnumerator() { FindClose(find_handle_); } +void FileEnumerator::GetFindInfo(FindInfo* info) { + DCHECK(info); + + if (!is_in_find_op_) + return; + + memcpy(info, &find_data_, sizeof(*info)); +} + std::wstring FileEnumerator::Next() { if (!is_in_find_op_) { if (pending_paths_.empty()) |