Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
FileSystemIterator.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_ITERATOR
6#define SC_EXPORT_LIBRARY_FILE_SYSTEM_ITERATOR 0
7#endif
8#define SC_FILE_SYSTEM_ITERATOR_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_FILE_SYSTEM_ITERATOR)
9
10#include "../Common/Assert.h"
11#include "../Common/IGrowableBufferStringPath.h"
12#include "FileSystemIteratorError.h"
13
14namespace SC
15{
16SC_DECLARE_ASSERT_PROVIDER(FileSystemIteratorAssert, SC_FILE_SYSTEM_ITERATOR_EXPORT);
17
18#define SC_FILE_SYSTEM_ITERATOR_ASSERT_RELEASE(e) SC_ASSERT_PROVIDER_RELEASE(SC::FileSystemIteratorAssert, e)
19#define SC_FILE_SYSTEM_ITERATOR_ASSERT_DEBUG(e) SC_ASSERT_PROVIDER_DEBUG(SC::FileSystemIteratorAssert, e)
20#define SC_FILE_SYSTEM_ITERATOR_TRUST_RESULT(expression) SC_FILE_SYSTEM_ITERATOR_ASSERT_RELEASE(expression)
21
24
27
46{
47 static_assert(StringPath::MaxPath <= 65535, "ResultFileSystemIterator depth must fit in uint16_t");
48
50 enum class Type
51 {
52 Directory,
53 File
54 };
55
58 {
59#if SC_PLATFORM_WINDOWS
60 void* fileDescriptor = (void*)(long long)-1;
61#else
62 int fileDescriptor = -1;
63 void* dirEnumerator = nullptr;
64#endif
65 size_t textLengthInBytes = 0;
66 bool gotDot1 = false;
67 bool gotDot2 = false;
68 };
69
71 struct Entry
72 {
73 StringSpan name;
74 StringSpan path;
75 uint32_t level = 0;
76 Type type = Type::File;
77
79 bool isDirectory() const { return type == Type::Directory; }
80
81#if SC_PLATFORM_WINDOWS
82 void* parentFileDescriptor = nullptr;
83#else
84 int parentFileDescriptor = 0;
85#endif
86 };
87
89 struct Options
90 {
91 bool recursive = false;
92 bool forwardSlashes = false;
93 };
94
96
99
102 const Entry& get() const { return currentEntry; }
103
106 ResultFileSystemIterator checkErrors() const { return errorResult; }
107
112 ResultFileSystemIterator init(StringSpan directory, Span<FolderState> recursiveEntries);
113
115
118 [[nodiscard]] bool enumerateNext();
119
123
124 private:
125 static constexpr auto MaxPath = StringPath::MaxPath;
126 struct Internal;
127 struct RecurseStack
128 {
129 Span<FolderState> recursiveEntries;
130
131 int currentEntry = -1;
132
133 FolderState& back();
134
135 void pop_back();
136 ResultFileSystemIterator push_back(const FolderState& other);
137 size_t size() const { return size_t(currentEntry + 1); }
138 bool isEmpty() const { return currentEntry == -1; }
139 };
140 RecurseStack recurseStack;
141
142 Entry currentEntry;
143 ResultFileSystemIterator errorResult = ResultFileSystemIterator(true);
144 bool initialized = false;
145 bool finished = false;
146 bool entryAvailable = false;
147
148#if SC_PLATFORM_WINDOWS
149 bool expectDotDirectories = true;
150 StringPath currentPath;
151 StringPath outputPath;
152 uint64_t dirEnumeratorBuffer[592 / sizeof(uint64_t)];
153#else
154 StringPath currentPath;
155#endif
156
157 ResultFileSystemIterator initInternal(StringSpan directory, Span<FolderState> recursiveEntries);
158 ResultFileSystemIterator enumerateNextInternal(Entry& entry, bool& hasEntry);
159 ResultFileSystemIterator recurseSubdirectoryInternal(Entry& entry);
160};
161
163} // namespace SC
Contains information on a file or directory.
Definition FileSystemIterator.h:72
bool isDirectory() const
Check if current entry is a directory.
Definition FileSystemIterator.h:79
uint32_t level
Current level of nesting from start of iteration.
Definition FileSystemIterator.h:75
StringSpan path
Absolute path of the current entry.
Definition FileSystemIterator.h:74
StringSpan name
Name of current entry (file with extension or directory)
Definition FileSystemIterator.h:73
Type type
Tells if it's a file or a directory.
Definition FileSystemIterator.h:76
Holds state of a folder when recursing into it to list its files.
Definition FileSystemIterator.h:58
Options when iterating (recursive and other options)
Definition FileSystemIterator.h:90
bool forwardSlashes
true will return paths forward slash / even on Windows
Definition FileSystemIterator.h:92
bool recursive
true will recurse automatically into subdirectories
Definition FileSystemIterator.h:91
Iterates files and directories inside a given path without allocating any memory.
Definition FileSystemIterator.h:46
bool enumerateNext()
Returned string is only valid until next enumerateNext call and/or another init call.
const Entry & get() const
Get current Entry being iterated.
Definition FileSystemIterator.h:102
ResultFileSystemIterator init(StringSpan directory, Span< FolderState > recursiveEntries)
Initializes the iterator on a given directory.
Options options
Options to control recursive behaviour and other options.
Definition FileSystemIterator.h:95
ResultFileSystemIterator checkErrors() const
Check if any error happened during iteration.
Definition FileSystemIterator.h:106
~FileSystemIterator()
Destroys the FileSystemIterator object.
Type
Entry type (File or Directory)
Definition FileSystemIterator.h:51
ResultFileSystemIterator recurseSubdirectory()
Recurse into current item (assuming Entry::isDirectory == true)
FileSystemIterator result retaining optional native, backend-stage, and directory-depth details.
Definition FileSystemIteratorError.h:48