| 1 | // Copyright 2013 The Flutter 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 FLUTTER_FML_FILE_H_ |
| 6 | #define FLUTTER_FML_FILE_H_ |
| 7 | |
| 8 | #include <functional> |
| 9 | #include <initializer_list> |
| 10 | #include <string> |
| 11 | #include <vector> |
| 12 | |
| 13 | #include "flutter/fml/macros.h" |
| 14 | #include "flutter/fml/unique_fd.h" |
| 15 | |
| 16 | #ifdef ERROR |
| 17 | #undef ERROR |
| 18 | #endif |
| 19 | |
| 20 | namespace fml { |
| 21 | |
| 22 | class Mapping; |
| 23 | |
| 24 | enum class FilePermission { |
| 25 | kRead, |
| 26 | kWrite, |
| 27 | kReadWrite, |
| 28 | }; |
| 29 | |
| 30 | std::string CreateTemporaryDirectory(); |
| 31 | |
| 32 | /// This can open a directory on POSIX, but not on Windows. |
| 33 | fml::UniqueFD OpenFile(const char* path, |
| 34 | bool create_if_necessary, |
| 35 | FilePermission permission); |
| 36 | |
| 37 | /// This can open a directory on POSIX, but not on Windows. |
| 38 | fml::UniqueFD OpenFile(const fml::UniqueFD& base_directory, |
| 39 | const char* path, |
| 40 | bool create_if_necessary, |
| 41 | FilePermission permission); |
| 42 | |
| 43 | /// Helper method that calls `OpenFile` with create_if_necessary = false |
| 44 | /// and permission = kRead. |
| 45 | /// |
| 46 | /// This can open a directory on POSIX, but not on Windows. |
| 47 | fml::UniqueFD OpenFileReadOnly(const fml::UniqueFD& base_directory, |
| 48 | const char* path); |
| 49 | |
| 50 | fml::UniqueFD OpenDirectory(const char* path, |
| 51 | bool create_if_necessary, |
| 52 | FilePermission permission); |
| 53 | |
| 54 | fml::UniqueFD OpenDirectory(const fml::UniqueFD& base_directory, |
| 55 | const char* path, |
| 56 | bool create_if_necessary, |
| 57 | FilePermission permission); |
| 58 | |
| 59 | /// Helper method that calls `OpenDirectory` with create_if_necessary = false |
| 60 | /// and permission = kRead. |
| 61 | fml::UniqueFD OpenDirectoryReadOnly(const fml::UniqueFD& base_directory, |
| 62 | const char* path); |
| 63 | |
| 64 | fml::UniqueFD Duplicate(fml::UniqueFD::element_type descriptor); |
| 65 | |
| 66 | bool IsDirectory(const fml::UniqueFD& directory); |
| 67 | |
| 68 | bool IsDirectory(const fml::UniqueFD& base_directory, const char* path); |
| 69 | |
| 70 | // Returns whether the given path is a file. |
| 71 | bool IsFile(const std::string& path); |
| 72 | |
| 73 | bool TruncateFile(const fml::UniqueFD& file, size_t size); |
| 74 | |
| 75 | bool FileExists(const fml::UniqueFD& base_directory, const char* path); |
| 76 | |
| 77 | bool UnlinkDirectory(const char* path); |
| 78 | |
| 79 | bool UnlinkDirectory(const fml::UniqueFD& base_directory, const char* path); |
| 80 | |
| 81 | bool UnlinkFile(const char* path); |
| 82 | |
| 83 | bool UnlinkFile(const fml::UniqueFD& base_directory, const char* path); |
| 84 | |
| 85 | fml::UniqueFD CreateDirectory(const fml::UniqueFD& base_directory, |
| 86 | const std::vector<std::string>& components, |
| 87 | FilePermission permission); |
| 88 | |
| 89 | bool WriteAtomically(const fml::UniqueFD& base_directory, |
| 90 | const char* file_name, |
| 91 | const Mapping& mapping); |
| 92 | |
| 93 | /// Signature of a callback on a file in `directory` with `filename` (relative |
| 94 | /// to `directory`). The returned bool should be false if and only if further |
| 95 | /// traversal should be stopped. For example, a file-search visitor may return |
| 96 | /// false when the file is found so no more visiting is needed. |
| 97 | using FileVisitor = std::function<bool(const fml::UniqueFD& directory, |
| 98 | const std::string& filename)>; |
| 99 | |
| 100 | /// Call `visitor` on all files inside the `directory` non-recursively. The |
| 101 | /// trivial file "." and ".." will not be visited. |
| 102 | /// |
| 103 | /// Return false if and only if the visitor returns false during the |
| 104 | /// traversal. |
| 105 | /// |
| 106 | /// If recursive visiting is needed, call `VisitFiles` inside the `visitor`, or |
| 107 | /// use our helper method `VisitFilesRecursively`. |
| 108 | /// |
| 109 | /// @see `VisitFilesRecursively`. |
| 110 | /// @note Procedure doesn't copy all closures. |
| 111 | bool VisitFiles(const fml::UniqueFD& directory, const FileVisitor& visitor); |
| 112 | |
| 113 | /// Recursively call `visitor` on all files inside the `directory`. Return false |
| 114 | /// if and only if the visitor returns false during the traversal. |
| 115 | /// |
| 116 | /// This is a helper method that wraps the general `VisitFiles` method. The |
| 117 | /// `VisitFiles` is strictly more powerful as it has the access of the recursion |
| 118 | /// stack to the file. For example, `VisitFiles` may be able to maintain a |
| 119 | /// vector of directory names that lead to a file. That could be useful to |
| 120 | /// compute the relative path between the root directory and the visited file. |
| 121 | /// |
| 122 | /// @see `VisitFiles`. |
| 123 | /// @note Procedure doesn't copy all closures. |
| 124 | bool VisitFilesRecursively(const fml::UniqueFD& directory, |
| 125 | const FileVisitor& visitor); |
| 126 | |
| 127 | /// Helper method to recursively remove files and subdirectories inside the |
| 128 | /// directory. The directory itself will not be removed. |
| 129 | /// |
| 130 | /// Return true if and only if all files have been successfully removed. |
| 131 | bool RemoveFilesInDirectory(const fml::UniqueFD& directory); |
| 132 | |
| 133 | /// Helper method to recursively remove files and subdirectories inside the |
| 134 | /// directory. The directory itself will also be removed. |
| 135 | /// |
| 136 | /// Return true if and only if all files have been successfully removed. |
| 137 | bool RemoveDirectoryRecursively(const fml::UniqueFD& parent, |
| 138 | const char* directory_name); |
| 139 | |
| 140 | class ScopedTemporaryDirectory { |
| 141 | public: |
| 142 | ScopedTemporaryDirectory(); |
| 143 | |
| 144 | ~ScopedTemporaryDirectory(); |
| 145 | |
| 146 | const std::string& path() const { return path_; } |
| 147 | const UniqueFD& fd() { return dir_fd_; } |
| 148 | |
| 149 | private: |
| 150 | std::string path_; |
| 151 | UniqueFD dir_fd_; |
| 152 | }; |
| 153 | |
| 154 | } // namespace fml |
| 155 | |
| 156 | #endif // FLUTTER_FML_FILE_H_ |
| 157 | |