1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Files: Add RangedDirectoryIterator

This commit is contained in:
reuk 2020-03-06 13:34:19 +00:00
parent 5f348c3040
commit e7e1de78fa
59 changed files with 481 additions and 84 deletions

View file

@ -64,6 +64,9 @@ bool DirectoryIterator::next()
return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
}
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
bool DirectoryIterator::next (bool* isDirResult, bool* isHiddenResult, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly)
{
@ -134,6 +137,9 @@ bool DirectoryIterator::next (bool* isDirResult, bool* isHiddenResult, int64* fi
}
}
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
JUCE_END_IGNORE_WARNINGS_MSVC
const File& DirectoryIterator::getFile() const
{
if (subIterator != nullptr && subIterator->hasBeenAdvanced)

View file

@ -25,6 +25,8 @@ namespace juce
//==============================================================================
/**
This class is now deprecated in favour of RangedDirectoryIterator.
Searches through the files in a directory, returning each file that is found.
A DirectoryIterator will search through a directory and its subdirectories using
@ -42,12 +44,15 @@ namespace juce
It also provides an estimate of its progress, using a (highly inaccurate!) algorithm.
@tags{Core}
@see RangedDirectoryIterator
*/
class JUCE_API DirectoryIterator final
{
public:
//==============================================================================
/** Creates a DirectoryIterator for a given directory.
/** This class is now deprecated in favour of RangedDirectoryIterator.
Creates a DirectoryIterator for a given directory.
After creating one of these, call its next() method to get the
first file - e.g. @code
@ -68,11 +73,12 @@ public:
separated by a semi-colon or comma, e.g. "*.jpg;*.png"
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying
whether to look for files, directories, or both.
@see RangedDirectoryIterator
*/
DirectoryIterator (const File& directory,
bool isRecursive,
const String& wildCard = "*",
int whatToLookFor = File::findFiles);
JUCE_DEPRECATED (DirectoryIterator (const File& directory,
bool isRecursive,
const String& wildCard = "*",
int whatToLookFor = File::findFiles));
/** Destructor. */
~DirectoryIterator();

View file

@ -574,7 +574,7 @@ int File::findChildFiles (Array<File>& results, int whatToLookFor, bool searchRe
{
int total = 0;
for (DirectoryIterator di (*this, searchRecursively, wildcard, whatToLookFor); di.next();)
for (const auto& di : RangedDirectoryIterator (*this, searchRecursively, wildcard, whatToLookFor))
{
results.add (di.getFile());
++total;
@ -585,12 +585,10 @@ int File::findChildFiles (Array<File>& results, int whatToLookFor, bool searchRe
int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const
{
int total = 0;
for (DirectoryIterator di (*this, false, wildCardPattern, whatToLookFor); di.next();)
++total;
return total;
return std::accumulate (RangedDirectoryIterator (*this, false, wildCardPattern, whatToLookFor),
RangedDirectoryIterator(),
0,
[] (int acc, const DirectoryEntry&) { return acc + 1; });
}
bool File::containsSubDirectories() const
@ -598,8 +596,7 @@ bool File::containsSubDirectories() const
if (! isDirectory())
return false;
DirectoryIterator di (*this, false, "*", findDirectories);
return di.next();
return RangedDirectoryIterator (*this, false, "*", findDirectories) != RangedDirectoryIterator();
}
//==============================================================================

View file

@ -574,7 +574,7 @@ public:
@param wildCardPattern the filename pattern to search for, e.g. "*.txt"
@returns the set of files that were found
@see getNumberOfChildFiles, DirectoryIterator
@see getNumberOfChildFiles, RangedDirectoryIterator
*/
Array<File> findChildFiles (int whatToLookFor,
bool searchRecursively,
@ -602,7 +602,8 @@ public:
is also added to this value, hidden files won't be counted
@param wildCardPattern the filename pattern to search for, e.g. "*.txt"
@returns the number of matches found
@see findChildFiles, DirectoryIterator
@see findChildFiles, RangedDirectoryIterator
*/
int getNumberOfChildFiles (int whatToLookFor,
const String& wildCardPattern = "*") const;

View file

@ -0,0 +1,68 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
// We implement this in terms of the deprecated DirectoryIterator,
// but the old DirectoryIterator might go away in the future!
RangedDirectoryIterator::RangedDirectoryIterator (const File& directory,
bool isRecursive,
const String& wildCard,
int whatToLookFor)
: iterator (new DirectoryIterator (directory,
isRecursive,
wildCard,
whatToLookFor))
{
increment();
}
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
JUCE_END_IGNORE_WARNINGS_MSVC
bool RangedDirectoryIterator::next()
{
const auto result = iterator->next (&entry.directory,
&entry.hidden,
&entry.fileSize,
&entry.modTime,
&entry.creationTime,
&entry.readOnly);
if (result)
entry.file = iterator->getFile();
else
entry = {};
return result;
}
void RangedDirectoryIterator::increment()
{
if (iterator != nullptr && ! next())
iterator = nullptr;
}
} // namespace juce

View file

@ -0,0 +1,169 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/** Describes the attributes of a file or folder. */
class DirectoryEntry final
{
public:
/** The path to a file or folder. */
File getFile() const { return file; }
/** The time at which the item was last modified. */
Time getModificationTime() const { return modTime; }
/** The time at which the item was created. */
Time getCreationTime() const { return creationTime; }
/** The size of the item. */
int64 getFileSize() const { return fileSize; }
/** True if the item is a directory, false otherwise. */
bool isDirectory() const { return directory; }
/** True if the item is hidden, false otherwise. */
bool isHidden() const { return hidden; }
/** True if the item is read-only, false otherwise. */
bool isReadOnly() const { return readOnly; }
private:
File file;
Time modTime;
Time creationTime;
int64 fileSize = 0;
bool directory = false;
bool hidden = false;
bool readOnly = false;
friend class RangedDirectoryIterator;
};
/** A convenience operator so that the expression `*it++` works correctly when
`it` is an instance of RangedDirectoryIterator.
*/
inline const DirectoryEntry& operator* (const DirectoryEntry& e) noexcept { return e; }
//==============================================================================
/**
Allows iterating over files and folders using C++11 range-for syntax.
In the following example, we recursively find all hidden files in a
specific directory.
@code
std::vector<File> hiddenFiles;
for (DirectoryEntry entry : RangedDirectoryIterator (File ("/path/to/folder"), isRecursive))
if (entry.isHidden())
hiddenFiles.push_back (entry.getFile());
@endcode
*/
class RangedDirectoryIterator final
{
public:
using difference_type = std::ptrdiff_t;
using value_type = DirectoryEntry;
using reference = DirectoryEntry;
using pointer = void;
using iterator_category = std::input_iterator_tag;
/** The default-constructed iterator acts as the 'end' sentinel. */
RangedDirectoryIterator() = default;
/** Creates a RangedDirectoryIterator for a given directory.
The resulting iterator can be used directly in a 'range-for' expression.
@param directory the directory to search in
@param isRecursive whether all the subdirectories should also be searched
@param wildCard the file pattern to match. This may contain multiple patterns
separated by a semi-colon or comma, e.g. "*.jpg;*.png"
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying
whether to look for files, directories, or both.
*/
RangedDirectoryIterator (const File& directory,
bool isRecursive,
const String& wildCard = "*",
int whatToLookFor = File::findFiles);
/** Returns true if both iterators are in their end/sentinel state,
otherwise returns false.
*/
bool operator== (const RangedDirectoryIterator& other) const noexcept
{
return iterator == nullptr && other.iterator == nullptr;
}
/** Returns the inverse of operator== */
bool operator!= (const RangedDirectoryIterator& other) const noexcept
{
return ! operator== (other);
}
/** Return an object containing metadata about the file or folder to
which the iterator is currently pointing.
*/
const DirectoryEntry& operator* () const noexcept { return entry; }
const DirectoryEntry* operator->() const noexcept { return &entry; }
/** Moves the iterator along to the next file. */
RangedDirectoryIterator& operator++()
{
increment();
return *this;
}
/** Moves the iterator along to the next file.
@returns an object containing metadata about the file or folder to
to which the iterator was previously pointing.
*/
DirectoryEntry operator++ (int)
{
auto result = *(*this);
++(*this);
return result;
}
private:
bool next();
void increment();
std::shared_ptr<DirectoryIterator> iterator;
DirectoryEntry entry;
};
/** Returns the iterator that was passed in.
Provided for range-for compatibility.
*/
inline RangedDirectoryIterator begin (const RangedDirectoryIterator& it) { return it; }
/** Returns a default-constructed sentinel value.
Provided for range-for compatibility.
*/
inline RangedDirectoryIterator end (const RangedDirectoryIterator&) { return {}; }
} // namespace juce