[*] Update prototype: AuFS::ReadDirRecursive(const AuString &string, AuOptional<bool> bTraverseSymlinks)

[+] AuUInt32 AuFS::IReadDir::GetErrorCount()
[+] AuList<AuString> AuFS::IReadDir::GetErrorPaths()
This commit is contained in:
Reece Wilson 2024-03-19 18:08:54 +00:00
parent bd1283e146
commit d6ac05054e
6 changed files with 166 additions and 42 deletions

View File

@ -37,7 +37,7 @@ namespace Aurora::IO::FS
* @param string * @param string
* @return * @return
*/ */
AUKN_SYM AuSPtr<IReadDir> ReadDirRecursive(const AuString &string); AUKN_SYM AuSPtr<IReadDir> ReadDirRecursive(const AuString &string, AuOptional<bool> bTraverseSymlinks = { true });
/** /**
* @brief Recursively deletes any given path * @brief Recursively deletes any given path

View File

@ -30,8 +30,12 @@ namespace Aurora::IO::FS
* @return * @return
* 1) a temporary pointer to an `StatEx` of the next file/dir in the directory * 1) a temporary pointer to an `StatEx` of the next file/dir in the directory
* 1) nullptr to indicate end of listing * 1) nullptr to indicate end of listing
* 2) nullptr to indicate error; wont recover TODO (Reece): this sucks but it's still an acceptable ambiguation for end of iteration. * 2) nullptr to indicate error; wont recover
*/ */
virtual StatEx *Next() = 0; virtual StatEx *Next() = 0;
virtual AuUInt32 GetErrorCount() = 0;
virtual AuList<AuString> GetErrorPaths() = 0;
}; };
} }

View File

@ -18,6 +18,44 @@ namespace Aurora::IO::FS
AuString curPath; AuString curPath;
AuString curSubDir; AuString curSubDir;
AuList<AuString> failedPaths; AuList<AuString> failedPaths;
AuUInt32 uErrorCount {};
virtual AuUInt32 GetErrorCount() override
{
return this->uErrorCount;
}
virtual AuList<AuString> GetErrorPaths() override
{
if (this->uErrorCount || this->failedPaths.size())
{
return this->failedPaths;
}
else
{
return {};
}
}
bool DoThing(const AuString &string)
{
AU_DEBUG_MEMCRUNCH;
if (!this->OpenDir(string))
{
return {};
}
while (this->Next())
{
}
this->RemoveDirs();
AuFS::Remove(string);
return true;
}
bool OpenDir(const AuString &str) bool OpenDir(const AuString &str)
{ {
@ -35,6 +73,15 @@ namespace Aurora::IO::FS
void DoNext() void DoNext()
{ {
if (this->pDir)
{
if (auto uCount = this->pDir->GetErrorCount())
{
this->failedPaths.push_back(this->curPath + AuString(1, AuFS::kPathSplitter) + this->curSubDir);
this->uErrorCount += uCount;
}
}
this->pDir.reset(); this->pDir.reset();
if (!this->nextLevel.size()) if (!this->nextLevel.size())
@ -86,6 +133,7 @@ namespace Aurora::IO::FS
if (!AuFS::Remove(pNext->path)) if (!AuFS::Remove(pNext->path))
{ {
this->failedPaths.push_back(pNext->fileName); this->failedPaths.push_back(pNext->fileName);
this->uErrorCount++;
} }
} }
} }
@ -105,6 +153,7 @@ namespace Aurora::IO::FS
if (!AuFS::Remove(dir)) if (!AuFS::Remove(dir))
{ {
this->failedPaths.push_back(itr->c_str()); this->failedPaths.push_back(itr->c_str());
this->uErrorCount++;
} }
} }
} }
@ -117,19 +166,10 @@ namespace Aurora::IO::FS
try try
{ {
if (!pObj->OpenDir(string)) if (!pObj->DoThing(string))
{ {
return {}; return {};
} }
while (pObj->Next())
{
}
pObj->RemoveDirs();
AuFS::Remove(string);
} }
catch (...) catch (...)
{ {
@ -146,20 +186,11 @@ namespace Aurora::IO::FS
try try
{ {
if (!pObj->OpenDir(string)) if (!pObj->DoThing(string))
{ {
return {}; return {};
} }
while (pObj->Next())
{
}
pObj->RemoveDirs();
AuFS::Remove(string);
if (AuFS::DirExists(string)) if (AuFS::DirExists(string))
{ {
for (const auto &str : pObj->failedPaths) for (const auto &str : pObj->failedPaths)

View File

@ -28,18 +28,43 @@ namespace Aurora::IO::FS
bool bDead {false}; bool bDead {false};
StatEx stat; StatEx stat;
AuString sPath; AuString sPath;
AuUInt32 uErrorCount {};
AuList<AuString> errorPaths;
~ReadDirStructure() ~ReadDirStructure()
{ {
::FindClose(this->hFind); ::FindClose(this->hFind);
} }
virtual AuUInt32 GetErrorCount() override
{
return this->uErrorCount;
}
virtual AuList<AuString> GetErrorPaths() override
{
if (this->uErrorCount)
{
return { this->sPath };
}
else
{
return {};
}
}
virtual StatEx *Next() override virtual StatEx *Next() override
{ {
AU_DEBUG_MEMCRUNCH;
if (!AuExchange(this->bFirstTick, false)) if (!AuExchange(this->bFirstTick, false))
{ {
if (::FindNextFileW(this->hFind, &this->ffd) == 0) if (::FindNextFileW(this->hFind, &this->ffd) == 0)
{ {
if (GetLastError() != ERROR_NO_MORE_FILES)
{
this->uErrorCount++;
}
return {}; return {};
} }
} }
@ -61,6 +86,7 @@ namespace Aurora::IO::FS
if (stat.fileName.empty()) if (stat.fileName.empty())
{ {
this->bDead = true; this->bDead = true;
this->uErrorCount++;
return {}; return {};
} }
@ -68,6 +94,7 @@ namespace Aurora::IO::FS
if (stat.path.empty()) if (stat.path.empty())
{ {
this->bDead = true; this->bDead = true;
this->uErrorCount++;
return {}; return {};
} }

View File

@ -61,6 +61,7 @@ namespace Aurora::IO::FS
StatEx stat; StatEx stat;
AuString sPath; AuString sPath;
bool bFast {}; bool bFast {};
AuUInt32 uErrorCount {};
~ReadDirStructure() ~ReadDirStructure()
{ {
@ -70,8 +71,27 @@ namespace Aurora::IO::FS
} }
} }
virtual AuUInt32 GetErrorCount() override
{
return this->uErrorCount;
}
virtual AuList<AuString> GetErrorPaths() override
{
if (this->uErrorCount)
{
return { this->sPath };
}
else
{
return {};
}
}
virtual StatEx *Next() override virtual StatEx *Next() override
{ {
AU_DEBUG_MEMCRUNCH;
bool bTryAgain {}; bool bTryAgain {};
if (this->bDead) if (this->bDead)
@ -81,9 +101,15 @@ namespace Aurora::IO::FS
do do
{ {
errno = 0;
if (!(this->pDE = ::readdir(this->pDIR))) if (!(this->pDE = ::readdir(this->pDIR)))
{ {
this->bDead = true; this->bDead = true;
if (errno)
{
this->uErrorCount++;
}
return {}; return {};
} }

View File

@ -16,6 +16,19 @@ namespace Aurora::IO::FS
AuList<AuString> nextLevel; AuList<AuString> nextLevel;
AuString curPath; AuString curPath;
AuString curSubDir; AuString curSubDir;
bool bSymlinkTraversal { true };
AuUInt32 uErrorCount {};
AuList<AuString> failedPaths;
virtual AuUInt32 GetErrorCount() override
{
return this->uErrorCount;
}
virtual AuList<AuString> GetErrorPaths() override
{
return this->failedPaths;
}
bool OpenDir(const AuString &str) bool OpenDir(const AuString &str)
{ {
@ -33,6 +46,15 @@ namespace Aurora::IO::FS
void DoNext() void DoNext()
{ {
if (this->pDir)
{
if (auto uCount = this->pDir->GetErrorCount())
{
this->failedPaths.push_back(this->curPath + AuString(1, AuFS::kPathSplitter) + this->curSubDir);
this->uErrorCount += uCount;
}
}
this->pDir.reset(); this->pDir.reset();
if (!nextLevel.size()) if (!nextLevel.size())
@ -48,15 +70,20 @@ namespace Aurora::IO::FS
virtual StatEx *Next() override virtual StatEx *Next() override
{ {
AU_DEBUG_MEMCRUNCH;
StatEx *pNext {}; StatEx *pNext {};
if (!this->pDir) if (!this->pDir)
{ {
return {}; return {};
} }
do
{
try try
{ {
pNext = this->pDir->Next(); pNext = this->pDir->Next();
while (!pNext) while (!pNext)
{ {
DoNext(); DoNext();
@ -73,6 +100,11 @@ namespace Aurora::IO::FS
pNext->fileName.insert(pNext->fileName.begin(), curSubDir.begin(), curSubDir.end()); pNext->fileName.insert(pNext->fileName.begin(), curSubDir.begin(), curSubDir.end());
} }
if (!this->bSymlinkTraversal && pNext->bSymLink)
{
continue;
}
if (pNext->bExistsDirectory) if (pNext->bExistsDirectory)
{ {
nextLevel.push_back(pNext->fileName + "/"); nextLevel.push_back(pNext->fileName + "/");
@ -82,12 +114,14 @@ namespace Aurora::IO::FS
{ {
SysPushErrorCatch(); SysPushErrorCatch();
} }
}
while (false);
return pNext; return pNext;
} }
}; };
AUKN_SYM AuSPtr<IReadDir> ReadDirRecursive(const AuString &string) AUKN_SYM AuSPtr<IReadDir> ReadDirRecursive(const AuString &string, AuOptional<bool> bTraverseSymlinks)
{ {
auto pObj = AuMakeShared<RecursiveDirIterator>(); auto pObj = AuMakeShared<RecursiveDirIterator>();
if (!pObj) if (!pObj)
@ -96,6 +130,8 @@ namespace Aurora::IO::FS
return {}; return {};
} }
pObj->bSymlinkTraversal = bTraverseSymlinks.ValueOr(true);
try try
{ {
if (!pObj->OpenDir(string)) if (!pObj->OpenDir(string))