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 | |