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