Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
FileSystem.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Common/CompilerMacrosExport.h"
5#ifndef SC_EXPORT_LIBRARY_FILE_SYSTEM
6#define SC_EXPORT_LIBRARY_FILE_SYSTEM 0
7#endif
8#define SC_FILE_SYSTEM_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_FILE_SYSTEM)
9
10#include "../Common/IGrowableBufferSpan.h"
11#include "../Common/IGrowableBufferStringPath.h"
12#include "../Common/PrimitiveDefinitions.h"
13#include "../Common/Result.h"
14#include "FileSystemError.h"
15
16namespace SC
17{
20
23
25enum class FileSystemEntryType : uint8_t
26{
27 Unknown,
28 File,
29 Directory,
30 SymbolicLink,
31 Other,
32};
33
36{
37 FileSystemEntryType entryType = FileSystemEntryType::Unknown;
38
39 size_t fileSize = 0;
40 size_t hardLinkCount = 0;
41 TimeMs creationTime;
42 TimeMs accessedTime;
43 TimeMs modifiedTime;
44
45 struct
46 {
47 uint32_t mode = 0;
48 uint32_t uid = 0;
49 uint32_t gid = 0;
50 uint64_t inode = 0;
51 uint64_t device = 0;
52 uint64_t specialDevice = 0;
53 uint64_t blocks = 0;
54 uint64_t blockSize = 0;
55 } posix;
56
57 struct
58 {
59 uint32_t attributes = 0;
60 uint32_t reparseTag = 0;
61 uint32_t volumeSerialNumber = 0;
62 uint64_t fileIndex = 0;
63 } windows;
64};
65
67enum class FileSystemAccessMode : uint8_t
68{
69 Exists,
70 Read,
71 Write,
72 Execute,
73};
74
77{
79 {
80 overwrite = false;
82 }
83
88 {
89 overwrite = value;
90 return *this;
91 }
92
97 {
98 useCloneIfSupported = value;
99 return *this;
100 }
101
104};
105
112struct SC_FILE_SYSTEM_EXPORT FileSystem
113{
116
120 ResultFileSystem init(StringSpan initialDirectory);
121
125 ResultFileSystem changeDirectory(StringSpan newDirectory);
126
129
132 {
133 StringSpan source;
134 StringSpan destination;
136 };
137
144 ResultFileSystem copyFiles(Span<const CopyOperation> sourceDestination);
145
154 ResultFileSystem copyFile(StringSpan source, StringSpan destination, CopyFlags copyFlags = CopyFlags())
155 {
156 return copyFiles(CopyOperation{source, destination, copyFlags});
157 }
158
163 ResultFileSystem copyDirectories(Span<const CopyOperation> sourceDestination);
164
173 ResultFileSystem copyDirectory(StringSpan source, StringSpan destination, CopyFlags copyFlags = CopyFlags())
174 {
175 return copyDirectories(CopyOperation{source, destination, copyFlags});
176 }
177
186 ResultFileSystem rename(StringSpan path, StringSpan newPath);
187
191 ResultFileSystem removeFiles(Span<const StringSpan> files);
192
197 ResultFileSystem removeFile(StringSpan source) { return removeFiles({source}); }
198
203
208
213 ResultFileSystem removeDirectoriesRecursive(Span<const StringSpan> directories);
214
221 ResultFileSystem removeDirectoryRecursive(StringSpan directory) { return removeDirectoriesRecursive({directory}); }
222
227 ResultFileSystem removeEmptyDirectories(Span<const StringSpan> directories);
228
233 ResultFileSystem removeEmptyDirectory(StringSpan directory) { return removeEmptyDirectories({directory}); }
234
239 ResultFileSystem makeDirectories(Span<const StringSpan> directories);
240
245 ResultFileSystem makeDirectory(StringSpan directory) { return makeDirectories({directory}); }
246
250 ResultFileSystem makeDirectoriesIfNotExists(Span<const StringSpan> directories);
251
255 ResultFileSystem makeDirectoryIfNotExists(StringSpan directory) { return makeDirectoriesIfNotExists({directory}); }
256
261 ResultFileSystem makeDirectoriesRecursive(Span<const StringSpan> directories);
262
267 ResultFileSystem makeDirectoryRecursive(StringSpan directory) { return makeDirectoriesRecursive({directory}); }
268
273 ResultFileSystem createSymbolicLink(StringSpan sourceFileOrDirectory, StringSpan linkFile);
274
279 ResultFileSystem createHardLink(StringSpan sourceFile, StringSpan linkFile);
280
285 [[nodiscard]] bool exists(StringSpan fileOrDirectory);
287 ResultFileSystem exists(StringSpan fileOrDirectory, bool& doesExist);
288
292 [[nodiscard]] bool existsAndIsDirectory(StringSpan directory);
294 ResultFileSystem existsAndIsDirectory(StringSpan directory, bool& isDirectory);
295
302 [[nodiscard]] bool existsAndIsFile(StringSpan file);
304 ResultFileSystem existsAndIsFile(StringSpan file, bool& isFile);
305
309 [[nodiscard]] bool existsAndIsLink(StringSpan file);
311 ResultFileSystem existsAndIsLink(StringSpan file, bool& isLink);
312
317 [[nodiscard]] bool canAccess(StringSpan fileOrDirectory, AccessMode accessMode = AccessMode::Exists);
319 ResultFileSystem canAccess(StringSpan fileOrDirectory, AccessMode accessMode, bool& canAccessPath);
320
325 [[nodiscard]] ResultFileSystem moveDirectory(StringSpan sourceDirectory, StringSpan destinationDirectory);
326
334 ResultFileSystem write(StringSpan file, Span<const char> data);
335 ResultFileSystem write(StringSpan file, Span<const uint8_t> data);
336
342 ResultFileSystem writeString(StringSpan file, StringSpan text);
343
348 ResultFileSystem writeStringAppend(StringSpan file, StringSpan text);
349
355 template <typename T>
356 ResultFileSystem read(StringSpan file, T& data)
357 {
358 return read(file, GrowableBuffer<T>{data});
359 }
360
365 ResultFileSystem read(StringSpan file, IGrowableBuffer&& buffer);
366
369
374 ResultFileSystem stat(StringSpan file, FileStat& fileStat);
375
380 ResultFileSystem lstat(StringSpan file, FileStat& fileStat);
381
386 ResultFileSystem getFileStat(StringSpan file, FileStat& fileStat);
387
392 ResultFileSystem readSymbolicLink(StringSpan linkFile, StringPath& destination);
393
398 ResultFileSystem chmod(StringSpan path, uint32_t mode);
399
405 ResultFileSystem chown(StringSpan path, uint32_t uid, uint32_t gid);
406
412 ResultFileSystem lchown(StringSpan path, uint32_t uid, uint32_t gid);
413
418 ResultFileSystem lchmod(StringSpan path, uint32_t mode);
419
424 ResultFileSystem setLastModifiedTime(StringSpan file, TimeMs time);
425
428 struct SC_FILE_SYSTEM_EXPORT Operations
429 {
430 static bool access(StringSpan path, AccessMode accessMode);
431 static ResultFileSystem access(StringSpan path, AccessMode accessMode, bool& canAccessPath);
432 static ResultFileSystem createSymbolicLink(StringSpan sourceFileOrDirectory, StringSpan linkFile);
433 static ResultFileSystem createHardLink(StringSpan sourceFile, StringSpan linkFile);
434 static ResultFileSystem makeDirectory(StringSpan dir);
435 static bool exists(StringSpan path);
436 static ResultFileSystem exists(StringSpan path, bool& doesExist);
437 static bool existsAndIsDirectory(StringSpan path);
438 static ResultFileSystem existsAndIsDirectory(StringSpan path, bool& isDirectory);
439 static bool existsAndIsFile(StringSpan path);
440 static ResultFileSystem existsAndIsFile(StringSpan path, bool& isFile);
441 static bool existsAndIsLink(StringSpan path);
442 static ResultFileSystem existsAndIsLink(StringSpan path, bool& isLink);
443 static ResultFileSystem makeDirectoryRecursive(StringSpan path);
444 static ResultFileSystem removeEmptyDirectory(StringSpan path);
445 static ResultFileSystem moveDirectory(StringSpan source, StringSpan destination);
446 static ResultFileSystem removeFile(StringSpan path);
447 static ResultFileSystem copyFile(StringSpan srcPath, StringSpan destPath, FileSystemCopyFlags flags);
448 static ResultFileSystem rename(StringSpan path, StringSpan newPath);
449 static ResultFileSystem copyDirectory(StringSpan srcPath, StringSpan destPath, FileSystemCopyFlags flags);
450 static ResultFileSystem removeDirectoryRecursive(StringSpan directory);
451 static ResultFileSystem stat(StringSpan path, FileSystemStat& fileStat);
452 static ResultFileSystem lstat(StringSpan path, FileSystemStat& fileStat);
453 static ResultFileSystem getFileStat(StringSpan path, FileSystemStat& fileStat);
454 static ResultFileSystem readSymbolicLink(StringSpan path, StringPath& destination);
455 static ResultFileSystem chmod(StringSpan path, uint32_t mode);
456 static ResultFileSystem chown(StringSpan path, uint32_t uid, uint32_t gid);
457 static ResultFileSystem lchown(StringSpan path, uint32_t uid, uint32_t gid);
458 static ResultFileSystem lchmod(StringSpan path, uint32_t mode);
459 static ResultFileSystem setLastModifiedTime(StringSpan path, TimeMs time);
460
461 static StringSpan getExecutablePath(StringPath& executablePath);
462 static StringSpan getCurrentWorkingDirectory(StringPath& currentWorkingDirectory);
463 static StringSpan getApplicationRootDirectory(StringPath& applicationRootDirectory);
464
465 private:
466 struct Internal;
467 };
468
469 private:
470 static constexpr size_t WindowsPathTransportCapacity = StringPath::MaxPath + 6;
471
472 [[nodiscard]] ResultFileSystem convert(const StringSpan file, StringPath& destination,
473 StringNativeBuffer<WindowsPathTransportCapacity + 1>& transportPath,
474 StringSpan* encodedPath = nullptr);
475
476 StringPath fileFormatBuffer1;
477 StringPath fileFormatBuffer2;
478 StringPath currentDirectory;
479
480 StringNativeBuffer<WindowsPathTransportCapacity + 1> fileTransportBuffer1;
481 StringNativeBuffer<WindowsPathTransportCapacity + 1> fileTransportBuffer2;
482};
484} // namespace SC
FileSystemAccessMode
Access mode for path checks.
Definition FileSystem.h:68
FileSystemEntryType
A structure to describe file stats.
Definition FileSystem.h:26
@ Exists
Check if path exists.
@ Execute
Check if path is executable / traversable.
A structure to describe copy flags.
Definition FileSystem.h:77
FileSystemCopyFlags & setUseCloneIfSupported(bool value)
If true copy will use native filesystem clone os api.
Definition FileSystem.h:96
FileSystemCopyFlags & setOverwrite(bool value)
If true copy will overwrite existing files in the destination.
Definition FileSystem.h:87
bool useCloneIfSupported
If true copy will use native filesystem clone os api.
Definition FileSystem.h:103
bool overwrite
If true copy will overwrite existing files in the destination.
Definition FileSystem.h:102
A structure to describe file stats.
Definition FileSystem.h:36
uint32_t mode
POSIX st_mode.
Definition FileSystem.h:47
uint32_t reparseTag
Windows reparse tag.
Definition FileSystem.h:60
size_t hardLinkCount
Number of hard links to the entry.
Definition FileSystem.h:40
TimeMs accessedTime
Time when file was last accessed when available.
Definition FileSystem.h:42
TimeMs creationTime
Time when file was created when available.
Definition FileSystem.h:41
uint64_t blockSize
POSIX st_blksize.
Definition FileSystem.h:54
FileSystemEntryType entryType
Type of entry stored at path.
Definition FileSystem.h:37
size_t fileSize
Size of the file in bytes.
Definition FileSystem.h:39
uint64_t blocks
POSIX st_blocks.
Definition FileSystem.h:53
uint32_t gid
POSIX st_gid.
Definition FileSystem.h:49
uint64_t inode
POSIX st_ino.
Definition FileSystem.h:50
uint64_t fileIndex
Windows file index.
Definition FileSystem.h:62
uint64_t specialDevice
POSIX st_rdev.
Definition FileSystem.h:52
uint32_t uid
POSIX st_uid.
Definition FileSystem.h:48
TimeMs modifiedTime
Time when file was last modified.
Definition FileSystem.h:43
uint32_t volumeSerialNumber
Windows volume serial number.
Definition FileSystem.h:61
uint64_t device
POSIX st_dev.
Definition FileSystem.h:51
uint32_t attributes
Windows file attributes.
Definition FileSystem.h:59
Specify source, destination and flags for a copy operation.
Definition FileSystem.h:132
StringSpan destination
Copy operation sink (can be a {relative | absolute} {file | directory} path)
Definition FileSystem.h:134
CopyFlags copyFlags
Copy operation flags (overwrite, use clone api etc.)
Definition FileSystem.h:135
StringSpan source
Copy operation source (can be a {relative | absolute} {file | directory} path)
Definition FileSystem.h:133
Low level filesystem API, requiring paths in native encoding (UTF-16 on Windows, UTF-8 elsewhere)
Definition FileSystem.h:429
Execute fs operations { exists, copy, delete } for { files and directories }.
Definition FileSystem.h:113
ResultFileSystem existsAndIsDirectory(StringSpan directory, bool &isDirectory)
Detailed query: absence or another entry type is a successful false answer.
bool existsAndIsFile(StringSpan file)
Check if a file exists at given path.
ResultFileSystem rename(StringSpan path, StringSpan newPath)
Rename a file or directory.
ResultFileSystem canAccess(StringSpan fileOrDirectory, AccessMode accessMode, bool &canAccessPath)
Detailed query: denied access or absence is a successful false answer.
ResultFileSystem exists(StringSpan fileOrDirectory, bool &doesExist)
Detailed query: a missing entry is a successful false answer; validation and I/O failures are errors.
ResultFileSystem lchown(StringSpan path, uint32_t uid, uint32_t gid)
Change owner and group for a path without following symbolic links.
ResultFileSystem removeEmptyDirectories(Span< const StringSpan > directories)
Removes multiple empty directories.
ResultFileSystem chmod(StringSpan path, uint32_t mode)
Change file permission bits for a path, following symbolic links.
ResultFileSystem removeFile(StringSpan source)
Remove a single file.
Definition FileSystem.h:197
ResultFileSystem makeDirectoryIfNotExists(StringSpan directory)
Creates a new directory, if it doesn't already exists at the given path.
Definition FileSystem.h:255
ResultFileSystem readSymbolicLink(StringSpan linkFile, StringPath &destination)
Reads the target path stored by a symbolic link.
bool exists(StringSpan fileOrDirectory)
Check if a file or directory exists at a given path.
ResultFileSystem lchmod(StringSpan path, uint32_t mode)
Change file permission bits for a symbolic link without following it.
ResultFileSystem existsAndIsFile(StringSpan file, bool &isFile)
Detailed query: absence or another entry type is a successful false answer.
ResultFileSystem removeDirectoriesRecursive(Span< const StringSpan > directories)
Remove multiple directories with their entire content (like posix rm -rf)
bool existsAndIsDirectory(StringSpan directory)
Check if a directory exists at given path.
ResultFileSystem removeDirectoryRecursive(StringSpan directory)
Remove single directory with its entire content (like posix rm -rf)
Definition FileSystem.h:221
ResultFileSystem getFileStat(StringSpan file, FileStat &fileStat)
Legacy convenience alias for stat(StringSpan, FileStat&)
ResultFileSystem makeDirectory(StringSpan directory)
Creates a new directory that does not already exist.
Definition FileSystem.h:245
ResultFileSystem moveDirectory(StringSpan sourceDirectory, StringSpan destinationDirectory)
Moves a directory from source to destination.
ResultFileSystem write(StringSpan file, Span< const char > data)
Writes a block of memory to a file.
ResultFileSystem init(StringSpan initialDirectory)
Call init function when instantiating the class to set directory for all operations using relative pa...
ResultFileSystem writeStringAppend(StringSpan file, StringSpan text)
Appends a StringSpan to a file.
ResultFileSystem chown(StringSpan path, uint32_t uid, uint32_t gid)
Change owner and group for a path, following symbolic links.
ResultFileSystem makeDirectoriesRecursive(Span< const StringSpan > directories)
Create new directories, creating also intermediate non existing directories (like posix mkdir -p)
ResultFileSystem writeString(StringSpan file, StringSpan text)
Replace the entire content of a file with the provided StringSpan.
ResultFileSystem changeDirectory(StringSpan newDirectory)
Changes current directory.
ResultFileSystem setLastModifiedTime(StringSpan file, TimeMs time)
Change last modified time of a given file.
ResultFileSystem copyFiles(Span< const CopyOperation > sourceDestination)
Copies many files.
ResultFileSystem makeDirectories(Span< const StringSpan > directories)
Creates new directories that do not already exist.
ResultFileSystem removeFiles(Span< const StringSpan > files)
Remove multiple files.
ResultFileSystem read(StringSpan file, T &data)
Read contents of a file into a String or Buffer.
Definition FileSystem.h:356
ResultFileSystem removeLinkIfExists(StringSpan source)
Remove a single link, giving no error if it doesn't exist.
ResultFileSystem copyDirectories(Span< const CopyOperation > sourceDestination)
Copy many directories.
ResultFileSystem stat(StringSpan file, FileStat &fileStat)
Obtains richer metadata about a path, following symbolic links.
ResultFileSystem makeDirectoriesIfNotExists(Span< const StringSpan > directories)
Creates new directories, if they don't already exist at the given path.
bool canAccess(StringSpan fileOrDirectory, AccessMode accessMode=AccessMode::Exists)
Check whether the current process can access a path with the requested mode.
ResultFileSystem removeFileIfExists(StringSpan source)
Remove a single file, giving no error if it doesn't exist.
ResultFileSystem existsAndIsLink(StringSpan file, bool &isLink)
Detailed query: absence or another entry type is a successful false answer.
ResultFileSystem removeEmptyDirectory(StringSpan directory)
Removes an empty directory.
Definition FileSystem.h:233
ResultFileSystem read(StringSpan file, IGrowableBuffer &&buffer)
Read contents of a file into an IGrowableBuffer.
ResultFileSystem lstat(StringSpan file, FileStat &fileStat)
Obtains richer metadata about a path without following symbolic links.
ResultFileSystem copyDirectory(StringSpan source, StringSpan destination, CopyFlags copyFlags=CopyFlags())
Copy a single directory.
Definition FileSystem.h:173
ResultFileSystem makeDirectoryRecursive(StringSpan directory)
Create a new directory, creating also intermediate non existing directories (like posix mkdir -p)
Definition FileSystem.h:267
ResultFileSystem copyFile(StringSpan source, StringSpan destination, CopyFlags copyFlags=CopyFlags())
Copy a single file.
Definition FileSystem.h:154
bool existsAndIsLink(StringSpan file)
Check if a link exists at given path.
ResultFileSystem createSymbolicLink(StringSpan sourceFileOrDirectory, StringSpan linkFile)
Creates a symbolic link at location linkFile pointing at sourceFileOrDirectory.
ResultFileSystem createHardLink(StringSpan sourceFile, StringSpan linkFile)
Creates a hard link at location linkFile pointing at sourceFile.
FileSystem result retaining an operation detail and one scalar diagnostic context.
Definition FileSystemError.h:126