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
20namespace fml {
21
22class Mapping;
23
24enum class FilePermission {
25 kRead,
26 kWrite,
27 kReadWrite,
28};
29
30std::string CreateTemporaryDirectory();
31
32/// This can open a directory on POSIX, but not on Windows.
33fml::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.
38fml::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.
47fml::UniqueFD OpenFileReadOnly(const fml::UniqueFD& base_directory,
48 const char* path);
49
50fml::UniqueFD OpenDirectory(const char* path,
51 bool create_if_necessary,
52 FilePermission permission);
53
54fml::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.
61fml::UniqueFD OpenDirectoryReadOnly(const fml::UniqueFD& base_directory,
62 const char* path);
63
64fml::UniqueFD Duplicate(fml::UniqueFD::element_type descriptor);
65
66bool IsDirectory(const fml::UniqueFD& directory);
67
68bool IsDirectory(const fml::UniqueFD& base_directory, const char* path);
69
70// Returns whether the given path is a file.
71bool IsFile(const std::string& path);
72
73bool TruncateFile(const fml::UniqueFD& file, size_t size);
74
75bool FileExists(const fml::UniqueFD& base_directory, const char* path);
76
77bool UnlinkDirectory(const char* path);
78
79bool UnlinkDirectory(const fml::UniqueFD& base_directory, const char* path);
80
81bool UnlinkFile(const char* path);
82
83bool UnlinkFile(const fml::UniqueFD& base_directory, const char* path);
84
85fml::UniqueFD CreateDirectory(const fml::UniqueFD& base_directory,
86 const std::vector<std::string>& components,
87 FilePermission permission);
88
89bool 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.
97using 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.
111bool 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.
124bool 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.
131bool 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.
137bool RemoveDirectoryRecursively(const fml::UniqueFD& parent,
138 const char* directory_name);
139
140class 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