I think there's something you're missing. When you conclude that there are no matches and that you've reached a new directory, you are setting a new subIterator and returning next(...). On that call to next(), if subIterator->next() doesn't find any matches, that call to next() will start its own while loop, the same while loop that the previous call to next() was working on (same hierarchy), thus, sibliing folders do affect the depth of the stack.
The easiest way I found to fix it was to add a boolean value to the next() method called 'checkOnlySubIterator', if true, after exhausting the subIterator, the method will return to the previous call to continue the while loop of the parent folder.
So, the changes are as follows:
juce_DirectoryIterator.h:
bool next (bool* isDirectory,
bool* isHidden,
int64* fileSize,
Time* modTime,
Time* creationTime,
bool* isReadOnly,
bool checkOnlySubIterator);
juce_DirectoryIterator.cpp:
bool DirectoryIterator::next()
{
return next(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, false);
}
bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly, bool checkOnlySubIterator)
{
hasBeenAdvanced = true;
if (subIterator != nullptr)
{
if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly, false))
return true;
subIterator = nullptr;
if (checkOnlySubIterator)
{
return false;
}
}
String filename;
bool isDirectory, isHidden = false;
while (fileFinder.next (filename, &isDirectory,
(isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr,
fileSize, modTime, creationTime, isReadOnly))
{
++index;
if (! filename.containsOnly ("."))
{
bool matches = false;
if (isDirectory)
{
if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden))
subIterator = new DirectoryIterator (File::createFileWithoutCheckingPath (path + filename),
true, wildCard, whatToLookFor);
matches = (whatToLookFor & File::findDirectories) != 0;
}
else
{
matches = (whatToLookFor & File::findFiles) != 0;
}
// if we're not relying on the OS iterator to do the wildcard match, do it now..
if (matches && (isRecursive || wildCards.size() > 1))
matches = fileMatches (wildCards, filename);
if (matches && (whatToLookFor & File::ignoreHiddenFiles) != 0)
matches = ! isHidden;
if (matches)
{
currentFile = File::createFileWithoutCheckingPath (path + filename);
if (isHiddenResult != nullptr) *isHiddenResult = isHidden;
if (isDirResult != nullptr) *isDirResult = isDirectory;
return true;
}
if (subIterator != nullptr)
{
if (next(isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly, true))
{
return true;
}
}
}
}
return false;
}
juce_DirectoryContentsList:checkNextFile (side effect):
if (fileFindHandle->next (&fileFoundIsDir, &isHidden, &fileSize,
&modTime, &creationTime, &isReadOnly, false))
I hope this helps.