1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_FILES_FILE_ENUMERATOR_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_FILES_FILE_ENUMERATOR_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 9*635a8641SAndroid Build Coastguard Worker #include <stdint.h> 10*635a8641SAndroid Build Coastguard Worker 11*635a8641SAndroid Build Coastguard Worker #include <vector> 12*635a8641SAndroid Build Coastguard Worker 13*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 14*635a8641SAndroid Build Coastguard Worker #include "base/containers/stack.h" 15*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h" 16*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 17*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h" 18*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h" 19*635a8641SAndroid Build Coastguard Worker 20*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 21*635a8641SAndroid Build Coastguard Worker #include <windows.h> 22*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA) 23*635a8641SAndroid Build Coastguard Worker #include <sys/stat.h> 24*635a8641SAndroid Build Coastguard Worker #include <unistd.h> 25*635a8641SAndroid Build Coastguard Worker #endif 26*635a8641SAndroid Build Coastguard Worker 27*635a8641SAndroid Build Coastguard Worker namespace base { 28*635a8641SAndroid Build Coastguard Worker 29*635a8641SAndroid Build Coastguard Worker // A class for enumerating the files in a provided path. The order of the 30*635a8641SAndroid Build Coastguard Worker // results is not guaranteed. 31*635a8641SAndroid Build Coastguard Worker // 32*635a8641SAndroid Build Coastguard Worker // This is blocking. Do not use on critical threads. 33*635a8641SAndroid Build Coastguard Worker // 34*635a8641SAndroid Build Coastguard Worker // Example: 35*635a8641SAndroid Build Coastguard Worker // 36*635a8641SAndroid Build Coastguard Worker // base::FileEnumerator enum(my_dir, false, base::FileEnumerator::FILES, 37*635a8641SAndroid Build Coastguard Worker // FILE_PATH_LITERAL("*.txt")); 38*635a8641SAndroid Build Coastguard Worker // for (base::FilePath name = enum.Next(); !name.empty(); name = enum.Next()) 39*635a8641SAndroid Build Coastguard Worker // ... 40*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT FileEnumerator { 41*635a8641SAndroid Build Coastguard Worker public: 42*635a8641SAndroid Build Coastguard Worker // Note: copy & assign supported. 43*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT FileInfo { 44*635a8641SAndroid Build Coastguard Worker public: 45*635a8641SAndroid Build Coastguard Worker FileInfo(); 46*635a8641SAndroid Build Coastguard Worker ~FileInfo(); 47*635a8641SAndroid Build Coastguard Worker 48*635a8641SAndroid Build Coastguard Worker bool IsDirectory() const; 49*635a8641SAndroid Build Coastguard Worker 50*635a8641SAndroid Build Coastguard Worker // The name of the file. This will not include any path information. This 51*635a8641SAndroid Build Coastguard Worker // is in constrast to the value returned by FileEnumerator.Next() which 52*635a8641SAndroid Build Coastguard Worker // includes the |root_path| passed into the FileEnumerator constructor. 53*635a8641SAndroid Build Coastguard Worker FilePath GetName() const; 54*635a8641SAndroid Build Coastguard Worker 55*635a8641SAndroid Build Coastguard Worker int64_t GetSize() const; 56*635a8641SAndroid Build Coastguard Worker Time GetLastModifiedTime() const; 57*635a8641SAndroid Build Coastguard Worker 58*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 59*635a8641SAndroid Build Coastguard Worker // Note that the cAlternateFileName (used to hold the "short" 8.3 name) 60*635a8641SAndroid Build Coastguard Worker // of the WIN32_FIND_DATA will be empty. Since we don't use short file 61*635a8641SAndroid Build Coastguard Worker // names, we tell Windows to omit it which speeds up the query slightly. find_data()62*635a8641SAndroid Build Coastguard Worker const WIN32_FIND_DATA& find_data() const { return find_data_; } 63*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA) stat()64*635a8641SAndroid Build Coastguard Worker const struct stat& stat() const { return stat_; } 65*635a8641SAndroid Build Coastguard Worker #endif 66*635a8641SAndroid Build Coastguard Worker 67*635a8641SAndroid Build Coastguard Worker private: 68*635a8641SAndroid Build Coastguard Worker friend class FileEnumerator; 69*635a8641SAndroid Build Coastguard Worker 70*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 71*635a8641SAndroid Build Coastguard Worker WIN32_FIND_DATA find_data_; 72*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA) 73*635a8641SAndroid Build Coastguard Worker struct stat stat_; 74*635a8641SAndroid Build Coastguard Worker FilePath filename_; 75*635a8641SAndroid Build Coastguard Worker #endif 76*635a8641SAndroid Build Coastguard Worker }; 77*635a8641SAndroid Build Coastguard Worker 78*635a8641SAndroid Build Coastguard Worker enum FileType { 79*635a8641SAndroid Build Coastguard Worker FILES = 1 << 0, 80*635a8641SAndroid Build Coastguard Worker DIRECTORIES = 1 << 1, 81*635a8641SAndroid Build Coastguard Worker INCLUDE_DOT_DOT = 1 << 2, 82*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA) 83*635a8641SAndroid Build Coastguard Worker SHOW_SYM_LINKS = 1 << 4, 84*635a8641SAndroid Build Coastguard Worker #endif 85*635a8641SAndroid Build Coastguard Worker }; 86*635a8641SAndroid Build Coastguard Worker 87*635a8641SAndroid Build Coastguard Worker // Search policy for intermediate folders. 88*635a8641SAndroid Build Coastguard Worker enum class FolderSearchPolicy { 89*635a8641SAndroid Build Coastguard Worker // Recursive search will pass through folders whose names match the 90*635a8641SAndroid Build Coastguard Worker // pattern. Inside each one, all files will be returned. Folders with names 91*635a8641SAndroid Build Coastguard Worker // that do not match the pattern will be ignored within their interior. 92*635a8641SAndroid Build Coastguard Worker MATCH_ONLY, 93*635a8641SAndroid Build Coastguard Worker // Recursive search will pass through every folder and perform pattern 94*635a8641SAndroid Build Coastguard Worker // matching inside each one. 95*635a8641SAndroid Build Coastguard Worker ALL, 96*635a8641SAndroid Build Coastguard Worker }; 97*635a8641SAndroid Build Coastguard Worker 98*635a8641SAndroid Build Coastguard Worker // |root_path| is the starting directory to search for. It may or may not end 99*635a8641SAndroid Build Coastguard Worker // in a slash. 100*635a8641SAndroid Build Coastguard Worker // 101*635a8641SAndroid Build Coastguard Worker // If |recursive| is true, this will enumerate all matches in any 102*635a8641SAndroid Build Coastguard Worker // subdirectories matched as well. It does a breadth-first search, so all 103*635a8641SAndroid Build Coastguard Worker // files in one directory will be returned before any files in a 104*635a8641SAndroid Build Coastguard Worker // subdirectory. 105*635a8641SAndroid Build Coastguard Worker // 106*635a8641SAndroid Build Coastguard Worker // |file_type|, a bit mask of FileType, specifies whether the enumerator 107*635a8641SAndroid Build Coastguard Worker // should match files, directories, or both. 108*635a8641SAndroid Build Coastguard Worker // 109*635a8641SAndroid Build Coastguard Worker // |pattern| is an optional pattern for which files to match. This 110*635a8641SAndroid Build Coastguard Worker // works like shell globbing. For example, "*.txt" or "Foo???.doc". 111*635a8641SAndroid Build Coastguard Worker // However, be careful in specifying patterns that aren't cross platform 112*635a8641SAndroid Build Coastguard Worker // since the underlying code uses OS-specific matching routines. In general, 113*635a8641SAndroid Build Coastguard Worker // Windows matching is less featureful than others, so test there first. 114*635a8641SAndroid Build Coastguard Worker // If unspecified, this will match all files. 115*635a8641SAndroid Build Coastguard Worker FileEnumerator(const FilePath& root_path, 116*635a8641SAndroid Build Coastguard Worker bool recursive, 117*635a8641SAndroid Build Coastguard Worker int file_type); 118*635a8641SAndroid Build Coastguard Worker FileEnumerator(const FilePath& root_path, 119*635a8641SAndroid Build Coastguard Worker bool recursive, 120*635a8641SAndroid Build Coastguard Worker int file_type, 121*635a8641SAndroid Build Coastguard Worker const FilePath::StringType& pattern); 122*635a8641SAndroid Build Coastguard Worker FileEnumerator(const FilePath& root_path, 123*635a8641SAndroid Build Coastguard Worker bool recursive, 124*635a8641SAndroid Build Coastguard Worker int file_type, 125*635a8641SAndroid Build Coastguard Worker const FilePath::StringType& pattern, 126*635a8641SAndroid Build Coastguard Worker FolderSearchPolicy folder_search_policy); 127*635a8641SAndroid Build Coastguard Worker ~FileEnumerator(); 128*635a8641SAndroid Build Coastguard Worker 129*635a8641SAndroid Build Coastguard Worker // Returns the next file or an empty string if there are no more results. 130*635a8641SAndroid Build Coastguard Worker // 131*635a8641SAndroid Build Coastguard Worker // The returned path will incorporate the |root_path| passed in the 132*635a8641SAndroid Build Coastguard Worker // constructor: "<root_path>/file_name.txt". If the |root_path| is absolute, 133*635a8641SAndroid Build Coastguard Worker // then so will be the result of Next(). 134*635a8641SAndroid Build Coastguard Worker FilePath Next(); 135*635a8641SAndroid Build Coastguard Worker 136*635a8641SAndroid Build Coastguard Worker // Write the file info into |info|. 137*635a8641SAndroid Build Coastguard Worker FileInfo GetInfo() const; 138*635a8641SAndroid Build Coastguard Worker 139*635a8641SAndroid Build Coastguard Worker private: 140*635a8641SAndroid Build Coastguard Worker // Returns true if the given path should be skipped in enumeration. 141*635a8641SAndroid Build Coastguard Worker bool ShouldSkip(const FilePath& path); 142*635a8641SAndroid Build Coastguard Worker 143*635a8641SAndroid Build Coastguard Worker bool IsTypeMatched(bool is_dir) const; 144*635a8641SAndroid Build Coastguard Worker 145*635a8641SAndroid Build Coastguard Worker bool IsPatternMatched(const FilePath& src) const; 146*635a8641SAndroid Build Coastguard Worker 147*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 148*635a8641SAndroid Build Coastguard Worker // True when find_data_ is valid. 149*635a8641SAndroid Build Coastguard Worker bool has_find_data_ = false; 150*635a8641SAndroid Build Coastguard Worker WIN32_FIND_DATA find_data_; 151*635a8641SAndroid Build Coastguard Worker HANDLE find_handle_ = INVALID_HANDLE_VALUE; 152*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA) 153*635a8641SAndroid Build Coastguard Worker // The files in the current directory 154*635a8641SAndroid Build Coastguard Worker std::vector<FileInfo> directory_entries_; 155*635a8641SAndroid Build Coastguard Worker 156*635a8641SAndroid Build Coastguard Worker // The next entry to use from the directory_entries_ vector 157*635a8641SAndroid Build Coastguard Worker size_t current_directory_entry_; 158*635a8641SAndroid Build Coastguard Worker #endif 159*635a8641SAndroid Build Coastguard Worker FilePath root_path_; 160*635a8641SAndroid Build Coastguard Worker const bool recursive_; 161*635a8641SAndroid Build Coastguard Worker const int file_type_; 162*635a8641SAndroid Build Coastguard Worker FilePath::StringType pattern_; 163*635a8641SAndroid Build Coastguard Worker const FolderSearchPolicy folder_search_policy_; 164*635a8641SAndroid Build Coastguard Worker 165*635a8641SAndroid Build Coastguard Worker // A stack that keeps track of which subdirectories we still need to 166*635a8641SAndroid Build Coastguard Worker // enumerate in the breadth-first search. 167*635a8641SAndroid Build Coastguard Worker base::stack<FilePath> pending_paths_; 168*635a8641SAndroid Build Coastguard Worker 169*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(FileEnumerator); 170*635a8641SAndroid Build Coastguard Worker }; 171*635a8641SAndroid Build Coastguard Worker 172*635a8641SAndroid Build Coastguard Worker } // namespace base 173*635a8641SAndroid Build Coastguard Worker 174*635a8641SAndroid Build Coastguard Worker #endif // BASE_FILES_FILE_ENUMERATOR_H_ 175