[*] 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
* @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

View File

@ -30,8 +30,12 @@ namespace Aurora::IO::FS
* @return
* 1) a temporary pointer to an `StatEx` of the next file/dir in the directory
* 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 AuUInt32 GetErrorCount() = 0;
virtual AuList<AuString> GetErrorPaths() = 0;
};
}

View File

@ -18,6 +18,44 @@ namespace Aurora::IO::FS
AuString curPath;
AuString curSubDir;
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)
{
@ -35,6 +73,15 @@ namespace Aurora::IO::FS
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();
if (!this->nextLevel.size())
@ -86,6 +133,7 @@ namespace Aurora::IO::FS
if (!AuFS::Remove(pNext->path))
{
this->failedPaths.push_back(pNext->fileName);
this->uErrorCount++;
}
}
}
@ -105,6 +153,7 @@ namespace Aurora::IO::FS
if (!AuFS::Remove(dir))
{
this->failedPaths.push_back(itr->c_str());
this->uErrorCount++;
}
}
}
@ -117,19 +166,10 @@ namespace Aurora::IO::FS
try
{
if (!pObj->OpenDir(string))
if (!pObj->DoThing(string))
{
return {};
}
while (pObj->Next())
{
}
pObj->RemoveDirs();
AuFS::Remove(string);
}
catch (...)
{
@ -146,20 +186,11 @@ namespace Aurora::IO::FS
try
{
if (!pObj->OpenDir(string))
if (!pObj->DoThing(string))
{
return {};
}
while (pObj->Next())
{
}
pObj->RemoveDirs();
AuFS::Remove(string);
if (AuFS::DirExists(string))
{
for (const auto &str : pObj->failedPaths)

View File

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

View File

@ -61,6 +61,7 @@ namespace Aurora::IO::FS
StatEx stat;
AuString sPath;
bool bFast {};
AuUInt32 uErrorCount {};
~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
{
AU_DEBUG_MEMCRUNCH;
bool bTryAgain {};
if (this->bDead)
@ -81,9 +101,15 @@ namespace Aurora::IO::FS
do
{
errno = 0;
if (!(this->pDE = ::readdir(this->pDIR)))
{
this->bDead = true;
if (errno)
{
this->uErrorCount++;
}
return {};
}

View File

@ -16,6 +16,19 @@ namespace Aurora::IO::FS
AuList<AuString> nextLevel;
AuString curPath;
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)
{
@ -33,6 +46,15 @@ namespace Aurora::IO::FS
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();
if (!nextLevel.size())
@ -48,46 +70,58 @@ namespace Aurora::IO::FS
virtual StatEx *Next() override
{
AU_DEBUG_MEMCRUNCH;
StatEx *pNext {};
if (!this->pDir)
{
return {};
}
try
do
{
pNext = this->pDir->Next();
while (!pNext)
try
{
DoNext();
if (!this->pDir)
pNext = this->pDir->Next();
while (!pNext)
{
return {};
DoNext();
if (!this->pDir)
{
return {};
}
pNext = this->pDir->Next();
}
pNext = this->pDir->Next();
}
if (curSubDir.size())
{
pNext->fileName.insert(pNext->fileName.begin(), curSubDir.begin(), curSubDir.end());
}
if (curSubDir.size())
{
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 + "/");
}
}
catch (...)
{
nextLevel.push_back(pNext->fileName + "/");
SysPushErrorCatch();
}
}
catch (...)
{
SysPushErrorCatch();
}
while (false);
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>();
if (!pObj)
@ -96,6 +130,8 @@ namespace Aurora::IO::FS
return {};
}
pObj->bSymlinkTraversal = bTraverseSymlinks.ValueOr(true);
try
{
if (!pObj->OpenDir(string))