roo_io
API Documentation for roo_io
Loading...
Searching...
No Matches
mount.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4
9#include "roo_io/fs/stat.h"
10
11namespace roo_io {
12
13// Represents a mounted filesystem.
14class Mount {
15 public:
16 // Creates a mount in a 'not mounted' state.
18
19 Mount(const Mount& other) = delete;
20 Mount& operator=(const Mount& other) = delete;
21
22 // Move constructor moves the original to the 'kNotMounted' state.
24 mount_ = other.mount_;
25 status_ = other.status_;
26 read_only_ = other.read_only_;
27 other.close();
28 }
29
31 mount_ = other.mount_;
32 status_ = other.status_;
33 read_only_ = other.read_only_;
34 other.close();
35 return *this;
36 }
37
38 // Returns the mount status, which can be:
39 // * kOk, if the mount is healthy,
40 // * kNotMounted, if the filesystem was never mounted, or if the mount was
41 // forcefully and explicitly closed by the application,
42 // * kNoMedia, if mount failed due to missing media (e.g. no SD card),
43 // * kOutOfMemory, if mount failed due to insufficient memory,
44 // * kAccessDenied, if mount failed due to insufficient permissions,
45 // * kGenericMountError, if mount failed for undetermined reasons.
46 Status status() const {
47 if (status_ == kOk && !mount_->active()) status_ = kNotMounted;
48 return status_;
49 }
50
51 // Returns true if the mount is healthy and can be used for filesystem
52 // operations.
53 bool ok() const { return status() == kOk; }
54
55 // A convenience shortcut for testing the existence of a specified file or
56 // directory. Equivalent to stat(path).exists().
57 bool exists(const char* path) const { return stat(path).exists(); }
58
59 // Tests whether the specified file or directory exists, and if so, determines
60 // its type, and, if it is a file, also its size.
61 //
62 // The returned Stat object may have the following status:
63 //
64 // * kOk, if the operation completed successfully and the object exists,
65 // * kInvalidPath, if the path is syntactically invalid,
66 // * kNotFound, if the destination path, or any of its components, does
67 // not exist,
68 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
69 // intermediate path components is not in fact a directory,
70 // * kAccessDenied, in case of insufficient permissions,
71 // * kOutOfMemory,
72 // * kTooManyFilesOpen,
73 // * kUnknownIOError,
74 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
75 // is not healhty.
76 Stat stat(const char* path) const {
77 return status_ != kOk ? Stat(status_) : mount_->stat(path);
78 }
79
80 // Removes the specified file.
81 //
82 // Returns:
83 // * kOk, if the file was successfully removed,
84 // * kInvalidPath, if the path is not syntactically valid,
85 // * kNotFound, if the destination path, or any of its components, does
86 // not exist,
87 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
88 // intermediate path components is not in fact a directory,
89 // * kAccessDenied, in case of insufficient permissions,
90 // * kReadOnlyFilesystem, if the mount is read-only,
91 // * kOutOfMemory,
92 // * kNoSpaceLeftOnDevice,
93 // * kUnknownIOError,
94 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
95 // is not healhty.
96 Status remove(const char* path) {
97 return status_ != kOk ? status_
98 : read_only_ ? kReadOnlyFilesystem
99 : mount_->remove(path);
100 }
101
102 // Renames or moves the specified file or directory.
103 //
104 // Returns:
105 // * kOk, if the source was successfully moved;
106 // * kInvalidPath, if either `pathFrom` or `pathTo` is not syntactically
107 // valid, or if `pathTo` is a descentant of `pathFrom`,
108 // * kNotFound, if `pathFrom`, or any of its components, does not exist, or if
109 // any of the intermediate components of `pathTo` does not exist,
110 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
111 // intermediate components of either `pathFrom` or `pathTo` is not in fact a
112 // directory,
113 // * kFileExists, if the destination `pathTo` exists and is a file,
114 // * kDirectoryExists, if the destination `pathTo` exists and is a directory,
115 // * kAccessDenied, in case of insufficient permissions,
116 // * kReadOnlyFilesystem, if the mount is read-only,
117 // * kOutOfMemory,
118 // * kNoSpaceLeftOnDevice,
119 // * kUnknownIOError,
120 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
121 // is not healhty.
122 Status rename(const char* pathFrom, const char* pathTo) {
123 return status_ != kOk ? status_
124 : read_only_ ? kReadOnlyFilesystem
125 : mount_->rename(pathFrom, pathTo);
126 }
127
128 // Creates the specified directory. The parent sub-directory must already
129 // exist.
130 //
131 // Returns:
132 // * kOk, if the directory was successfully created;
133 // * kInvalidPath, if the path is not syntactically valid;
134 // * kNotFound, if any of the intermediate path components does not exist,
135 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
136 // intermediate path components is not in fact a directory,
137 // * kFileExists, if the destination exists and is a file,
138 // * kDirectoryExists, if the destination exists and is a directory,
139 // * kAccessDenied, in case of insufficient permissions,
140 // * kReadOnlyFilesystem, if the mount is read-only,
141 // * kOutOfMemory,
142 // * kNoSpaceLeftOnDevice,
143 // * kUnknownIOError,
144 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
145 // is not healhty.
146 Status mkdir(const char* path) {
147 return status_ != kOk ? status_
148 : read_only_ ? kReadOnlyFilesystem
149 : mount_->mkdir(path);
150 }
151
152 // Removes the specified empty directory.
153 //
154 // Returns:
155 // * kOk, if the directory was successfully deleted;
156 // * kInvalidPath, if the path is not syntactically valid;
157 // * kNotFound, if the target, or any of its intermediate path components,
158 // does not exist,
159 // * kNotDirectory, if the target exists but is not in fact a directory,
160 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
161 // intermediate path components is not in fact a directory,
162 // * kDirectoryNotEmpty, if the target directory exists but it is not empty,
163 // * kAccessDenied, in case of insufficient permissions,
164 // * kReadOnlyFilesystem, if the mount is read-only,
165 // * kOutOfMemory,
166 // * kUnknownIOError,
167 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
168 // is not healhty.
169 Status rmdir(const char* path) {
170 return status_ != kOk ? status_
171 : read_only_ ? kReadOnlyFilesystem
172 : mount_->rmdir(path);
173 }
174
175 // Opens the specified directory for browsing.
176 //
177 // Returns a directory object in the one of the following states:
178 // * kOk, if the directory was successfully opened;
179 // * kInvalidPath, if the path is not syntactically valid;
180 // * kNotFound, if the target, or any of its intermediate path components,
181 // does not exist,
182 // * kNotDirectory, if the target exists but is not in fact a directory,
183 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
184 // intermediate path components is not in fact a directory,
185 // * kAccessDenied, in case of insufficient permissions,
186 // * kOutOfMemory,
187 // * kTooManyFilesOpen,
188 // * kUnknownIOError,
189 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
190 // is not healhty.
191 Directory opendir(const char* path) {
192 return status_ != kOk ? Directory(status_)
193 : Directory(mount_->opendir(mount_, path));
194 }
195
196 // Opens the specified file for reading.
197 //
198 // Returns s tream in one of the following states:
199 // * kOk, if the file was successfully opened;
200 // * kInvalidPath, if the path is not syntactically valid;
201 // * kNotFound, if the source, or any of its intermediate path components,
202 // does not exist,
203 // * kNotFile, if the source exists but is not in fact a file,
204 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
205 // intermediate path components is not in fact a directory,
206 // * kAccessDenied, in case of insufficient permissions,
207 // * kOutOfMemory,
208 // * kTooManyFilesOpen,
209 // * kUnknownIOError,
210 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
211 // is not healhty.
212 std::unique_ptr<MultipassInputStream> fopen(const char* path) {
213 return status_ != kOk ? InputError(status_) : mount_->fopen(mount_, path);
214 }
215
216 // Opens the specified file for writing or appending to.
217 //
218 // Always creates the file if it doesn't already exist. If the file does
219 // already exist, the behavior is dictated by the `update_policy`.
220 //
221 // Returns a stream in one of the following states:
222 // * kOk, if the file was successfully opened;
223 // * kInvalidPath, if the path is not syntactically valid;
224 // * kNotFound, if the file, or any of its intermediate path components,
225 // does not exist,
226 // * kNotFile, if the source exists but is not in fact a file,
227 // * possibly kNotDirectory, but permissibly kNotFound, if any of the
228 // intermediate path components is not in fact a directory,
229 // * kAccessDenied, in case of insufficient permissions,
230 // * kReadOnlyFilesystem, if the mount is read-only,
231 // * kOutOfMemory,
232 // * kTooManyFilesOpen,
233 // * kUnknownIOError,
234 // * a copy of mount.status() (e.g. kNotMounted, kNoMedia, etc.) if the mount
235 // is not healhty.
236 std::unique_ptr<OutputStream> fopenForWrite(const char* path,
238 return status_ != kOk ? OutputError(status_)
239 : read_only_ ? OutputError(kReadOnlyFilesystem)
240 : mount_->fopenForWrite(mount_, path, update_policy);
241 }
242
243 // Returns true if the mount is known to be read-only. (When returns false,
244 // there is no guarantee that the filesystem is in fact writable).
245 bool isReadOnly() const { return read_only_; }
246
247 // Closes this mount. Does not affect other mount objects for the same
248 // filesystem. Does not actually unmount the filesystem, unless this was the
249 // last healthy mount object.
250 void close() {
251 if (status_ == kOk) status_ = kNotMounted;
252 mount_ = nullptr;
253 }
254
255 private:
256 friend class Filesystem;
257
258 Mount(Status error) : mount_(nullptr), status_(error), read_only_(false) {}
259
260 Mount(std::shared_ptr<MountImpl> impl, bool read_only)
261 : mount_(impl), status_(kOk), read_only_(read_only) {}
262
263 std::shared_ptr<MountImpl> mount_;
264 mutable Status status_;
265 bool read_only_;
266};
267
268} // namespace roo_io
std::unique_ptr< OutputStream > fopenForWrite(const char *path, FileUpdatePolicy update_policy)
Definition mount.h:236
void close()
Definition mount.h:250
Mount(Mount &&other)
Definition mount.h:23
Status rmdir(const char *path)
Definition mount.h:169
Status mkdir(const char *path)
Definition mount.h:146
bool exists(const char *path) const
Definition mount.h:57
Mount & operator=(const Mount &other)=delete
bool ok() const
Definition mount.h:53
Status rename(const char *pathFrom, const char *pathTo)
Definition mount.h:122
Stat stat(const char *path) const
Definition mount.h:76
std::unique_ptr< MultipassInputStream > fopen(const char *path)
Definition mount.h:212
bool isReadOnly() const
Definition mount.h:245
Directory opendir(const char *path)
Definition mount.h:191
Mount(const Mount &other)=delete
Status status() const
Definition mount.h:46
Mount & operator=(Mount &&other)
Definition mount.h:30
Status remove(const char *path)
Definition mount.h:96
bool exists() const
Definition stat.h:18
Definition byte.h:6
roo::basic_string_view< CharT, Traits > basic_string_view
Definition string_view.h:8
Status
Definition status.h:7
@ kReadOnlyFilesystem
Definition status.h:21
@ kOk
Definition status.h:8
@ kNotMounted
Definition status.h:11
std::unique_ptr< OutputStream > OutputError(Status error)
std::unique_ptr< MultipassInputStream > InputError(Status error)