xref: /aosp_15_r20/external/libchrome/base/files/file_enumerator.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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