[*] Update prototype: AuFS::ReadDirRecursive(const AuString &string, AuOptional<bool> bTraverseSymlinks)
[+] AuUInt32 AuFS::IReadDir::GetErrorCount() [+] AuList<AuString> AuFS::IReadDir::GetErrorPaths()
This commit is contained in:
parent
bd1283e146
commit
d6ac05054e
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -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)
|
||||||
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user