1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef BASE_FILES_FILE_ENUMERATOR_H_ 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define BASE_FILES_FILE_ENUMERATOR_H_ 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stack> 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector> 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/base_export.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/basictypes.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_path.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "build/build_config.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN) 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <windows.h> 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX) 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <sys/stat.h> 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <unistd.h> 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace base { 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A class for enumerating the files in a provided path. The order of the 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// results is not guaranteed. 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This is blocking. Do not use on critical threads. 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Example: 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// base::FileEnumerator enum(my_dir, false, base::FileEnumerator::FILES, 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// FILE_PATH_LITERAL("*.txt")); 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// for (base::FilePath name = enum.Next(); !name.empty(); name = enum.Next()) 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// ... 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class BASE_EXPORT FileEnumerator { 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Note: copy & assign supported. 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) class BASE_EXPORT FileInfo { 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileInfo(); 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~FileInfo(); 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool IsDirectory() const; 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The name of the file. This will not include any path information. This 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // is in constrast to the value returned by FileEnumerator.Next() which 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // includes the |root_path| passed into the FileEnumerator constructor. 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FilePath GetName() const; 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 GetSize() const; 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Time GetLastModifiedTime() const; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN) 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Note that the cAlternateFileName (used to hold the "short" 8.3 name) 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // of the WIN32_FIND_DATA will be empty. Since we don't use short file 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // names, we tell Windows to omit it which speeds up the query slightly. 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const WIN32_FIND_DATA& find_data() const { return find_data_; } 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const struct stat& stat() const { return stat_; } 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) friend class FileEnumerator; 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN) 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WIN32_FIND_DATA find_data_; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX) 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct stat stat_; 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FilePath filename_; 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) enum FileType { 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FILES = 1 << 0, 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DIRECTORIES = 1 << 1, 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) INCLUDE_DOT_DOT = 1 << 2, 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_POSIX) 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SHOW_SYM_LINKS = 1 << 4, 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |root_path| is the starting directory to search for. It may or may not end 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // in a slash. 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If |recursive| is true, this will enumerate all matches in any 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // subdirectories matched as well. It does a breadth-first search, so all 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // files in one directory will be returned before any files in a 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // subdirectory. 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |file_type|, a bit mask of FileType, specifies whether the enumerator 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // should match files, directories, or both. 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |pattern| is an optional pattern for which files to match. This 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // works like shell globbing. For example, "*.txt" or "Foo???.doc". 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // However, be careful in specifying patterns that aren't cross platform 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // since the underlying code uses OS-specific matching routines. In general, 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Windows matching is less featureful than others, so test there first. 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If unspecified, this will match all files. 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // NOTE: the pattern only matches the contents of root_path, not files in 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // recursive subdirectories. 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(erikkay): Fix the pattern matching to work at all levels. 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileEnumerator(const FilePath& root_path, 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool recursive, 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int file_type); 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileEnumerator(const FilePath& root_path, 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool recursive, 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int file_type, 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const FilePath::StringType& pattern); 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~FileEnumerator(); 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Returns the next file or an empty string if there are no more results. 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The returned path will incorporate the |root_path| passed in the 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // constructor: "<root_path>/file_name.txt". If the |root_path| is absolute, 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // then so will be the result of Next(). 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FilePath Next(); 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Write the file info into |info|. 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileInfo GetInfo() const; 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Returns true if the given path should be skipped in enumeration. 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ShouldSkip(const FilePath& path); 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN) 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // True when find_data_ is valid. 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool has_find_data_; 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WIN32_FIND_DATA find_data_; 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HANDLE find_handle_; 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX) 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Read the filenames in source into the vector of DirectoryEntryInfo's 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static bool ReadDirectory(std::vector<FileInfo>* entries, 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const FilePath& source, bool show_links); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The files in the current directory 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<FileInfo> directory_entries_; 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The next entry to use from the directory_entries_ vector 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t current_directory_entry_; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FilePath root_path_; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool recursive_; 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int file_type_; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FilePath::StringType pattern_; // Empty when we want to find everything. 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // A stack that keeps track of which subdirectories we still need to 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // enumerate in the breadth-first search. 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::stack<FilePath> pending_paths_; 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileEnumerator); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace base 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // BASE_FILES_FILE_ENUMERATOR_H_ 160