migrating to the latest JUCE version
This commit is contained in:
476
deps/juce/modules/juce_core/files/juce_AndroidDocument.h
vendored
Normal file
476
deps/juce/modules/juce_core/files/juce_AndroidDocument.h
vendored
Normal file
@ -0,0 +1,476 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Some information about a document.
|
||||
|
||||
Each instance represents some information about the document at the point when the instance
|
||||
was created.
|
||||
|
||||
Instance information is not updated automatically. If you think some file information may
|
||||
have changed, create a new instance.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class AndroidDocumentInfo
|
||||
{
|
||||
public:
|
||||
AndroidDocumentInfo() = default;
|
||||
|
||||
/** True if this file really exists. */
|
||||
bool exists() const { return isJuceFlagSet (flagExists); }
|
||||
|
||||
/** True if this is a directory rather than a file. */
|
||||
bool isDirectory() const;
|
||||
|
||||
/** True if this is a file rather than a directory. */
|
||||
bool isFile() const { return type.isNotEmpty() && ! isDirectory(); }
|
||||
|
||||
/** True if this process has permission to read this file.
|
||||
|
||||
If this returns true, and the AndroidDocument refers to a file rather than a directory,
|
||||
then AndroidDocument::createInputStream should work on this document.
|
||||
*/
|
||||
bool canRead() const { return isJuceFlagSet (flagHasReadPermission) && type.isNotEmpty(); }
|
||||
|
||||
/** True if this is a document that can be written, or a directory that can be modified.
|
||||
|
||||
If this returns true, and the AndroidDocument refers to a file rather than a directory,
|
||||
then AndroidDocument::createOutputStream should work on this document.
|
||||
*/
|
||||
bool canWrite() const
|
||||
{
|
||||
return isJuceFlagSet (flagHasWritePermission)
|
||||
&& type.isNotEmpty()
|
||||
&& (isNativeFlagSet (flagSupportsWrite)
|
||||
|| isNativeFlagSet (flagSupportsDelete)
|
||||
|| isNativeFlagSet (flagDirSupportsCreate));
|
||||
}
|
||||
|
||||
/** True if this document can be removed completely from the filesystem. */
|
||||
bool canDelete() const { return isNativeFlagSet (flagSupportsDelete); }
|
||||
|
||||
/** True if this is a directory and adding child documents is supported. */
|
||||
bool canCreateChildren() const { return isNativeFlagSet (flagDirSupportsCreate); }
|
||||
|
||||
/** True if this document can be renamed. */
|
||||
bool canRename() const { return isNativeFlagSet (flagSupportsRename); }
|
||||
|
||||
/** True if this document can be copied. */
|
||||
bool canCopy() const { return isNativeFlagSet (flagSupportsCopy); }
|
||||
|
||||
/** True if this document can be moved. */
|
||||
bool canMove() const { return isNativeFlagSet (flagSupportsMove); }
|
||||
|
||||
/** True if this document isn't a physical file on storage. */
|
||||
bool isVirtual() const { return isNativeFlagSet (flagVirtualDocument); }
|
||||
|
||||
/** The user-facing name.
|
||||
|
||||
This may or may not contain a file extension. For files identified by a URL, the MIME type
|
||||
is stored separately.
|
||||
*/
|
||||
String getName() const { return name; }
|
||||
|
||||
/** The MIME type of this document. */
|
||||
String getType() const { return isDirectory() ? String{} : type; }
|
||||
|
||||
/** Timestamp when a document was last modified, in milliseconds since January 1, 1970 00:00:00.0 UTC.
|
||||
|
||||
Use isLastModifiedValid() to determine whether or not the result of this
|
||||
function is valid.
|
||||
*/
|
||||
int64 getLastModified() const { return isJuceFlagSet (flagValidModified) ? lastModified : 0; }
|
||||
|
||||
/** True if the filesystem provided a modification time. */
|
||||
bool isLastModifiedValid() const { return isJuceFlagSet (flagValidModified); }
|
||||
|
||||
/** The size of the document in bytes, if known.
|
||||
|
||||
Use isSizeInBytesValid() to determine whether or not the result of this
|
||||
function is valid.
|
||||
*/
|
||||
int64 getSizeInBytes() const { return isJuceFlagSet (flagValidSize) ? sizeInBytes : 0; }
|
||||
|
||||
/** True if the filesystem provided a size in bytes. */
|
||||
bool isSizeInBytesValid() const { return isJuceFlagSet (flagValidSize); }
|
||||
|
||||
/** @internal */
|
||||
class Args;
|
||||
|
||||
private:
|
||||
explicit AndroidDocumentInfo (Args);
|
||||
|
||||
bool isNativeFlagSet (int flag) const { return (nativeFlags & flag) != 0; }
|
||||
bool isJuceFlagSet (int flag) const { return (juceFlags & flag) != 0; }
|
||||
|
||||
/* Native Android flags that might be set in the COLUMN_FLAGS for a particular document */
|
||||
enum
|
||||
{
|
||||
flagSupportsWrite = 0x0002,
|
||||
flagSupportsDelete = 0x0004,
|
||||
flagDirSupportsCreate = 0x0008,
|
||||
flagSupportsRename = 0x0040,
|
||||
flagSupportsCopy = 0x0080,
|
||||
flagSupportsMove = 0x0100,
|
||||
flagVirtualDocument = 0x0200,
|
||||
};
|
||||
|
||||
/* Flags for other binary properties that aren't exposed in COLUMN_FLAGS */
|
||||
enum
|
||||
{
|
||||
flagExists = 1 << 0,
|
||||
flagValidModified = 1 << 1,
|
||||
flagValidSize = 1 << 2,
|
||||
flagHasReadPermission = 1 << 3,
|
||||
flagHasWritePermission = 1 << 4,
|
||||
};
|
||||
|
||||
String name;
|
||||
String type;
|
||||
int64 lastModified = 0;
|
||||
int64 sizeInBytes = 0;
|
||||
int nativeFlags = 0, juceFlags = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a permission granted to an application to read and/or write to a particular document
|
||||
or tree.
|
||||
|
||||
This class also contains static methods to request, revoke, and query the permissions of your
|
||||
app. These functions are no-ops on all platforms other than Android.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class AndroidDocumentPermission
|
||||
{
|
||||
public:
|
||||
/** The url of the document with persisted permissions. */
|
||||
URL getUrl() const { return url; }
|
||||
|
||||
/** The time when the permissions were persisted, in milliseconds since January 1, 1970 00:00:00.0 UTC. */
|
||||
int64 getPersistedTime() const { return time; }
|
||||
|
||||
/** True if the permission allows read access. */
|
||||
bool isReadPermission() const { return read; }
|
||||
|
||||
/** True if the permission allows write access. */
|
||||
bool isWritePermission() const { return write; }
|
||||
|
||||
/** Gives your app access to a particular document or tree, even after the device is rebooted.
|
||||
|
||||
If you want to persist access to a folder selected through a native file chooser, make sure
|
||||
to pass the exact URL returned by the file picker. Do NOT call AndroidDocument::fromTree
|
||||
and then pass the result of getUrl to this function, as the resulting URL may differ from
|
||||
the result of the file picker.
|
||||
*/
|
||||
static void takePersistentReadWriteAccess (const URL&);
|
||||
|
||||
/** Revokes persistent access to a document or tree. */
|
||||
static void releasePersistentReadWriteAccess (const URL&);
|
||||
|
||||
/** Returns all of the permissions that have previously been granted to the app, via
|
||||
takePersistentReadWriteAccess();
|
||||
*/
|
||||
static std::vector<AndroidDocumentPermission> getPersistedPermissions();
|
||||
|
||||
private:
|
||||
URL url;
|
||||
int64 time = 0;
|
||||
bool read = false, write = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Provides access to a document on Android devices.
|
||||
|
||||
In this context, a 'document' may be a file or a directory.
|
||||
|
||||
The main purpose of this class is to provide access to files in shared storage on Android.
|
||||
On newer Android versions, such files cannot be accessed directly by a file path, and must
|
||||
instead be read and modified using a new URI-based DocumentsContract API.
|
||||
|
||||
Example use-cases:
|
||||
|
||||
- After showing the system open dialog to allow the user to open a file, pass the FileChooser's
|
||||
URL result to AndroidDocument::fromDocument. Then, you can use getInfo() to retrieve
|
||||
information about the file, and createInputStream to read from the file. Other functions allow
|
||||
moving, copying, and deleting the file.
|
||||
|
||||
- Similarly to the 'open' use-case, you may use createOutputStream to write to a file, normally
|
||||
located using the system save dialog.
|
||||
|
||||
- To allow reading or writing to a tree of files in shared storage, you can show the system
|
||||
open dialog in 'selects directories' mode, and pass the resulting URL to
|
||||
AndroidDocument::fromTree. Then, you can iterate the files in the directory, query them,
|
||||
and create new files. This is a good way to store multiple files that the user can access from
|
||||
other apps, and that will be persistent after uninstalling and reinstalling your app.
|
||||
|
||||
Note that you probably do *not* need this class if your app only needs to access files in its
|
||||
own internal sandbox. juce::File instances should work as expected in that case.
|
||||
|
||||
AndroidDocument is a bit like the DocumentFile class from the androidx extension library,
|
||||
in that it represents a single document, and is implemented using DocumentsContract functions.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class AndroidDocument
|
||||
{
|
||||
public:
|
||||
/** Create a null document. */
|
||||
AndroidDocument();
|
||||
|
||||
/** Create an AndroidDocument representing a file or directory at a particular path.
|
||||
|
||||
This is provided for use on older API versions (lower than 19), or on other platforms, so
|
||||
that the same AndroidDocument API can be used regardless of the runtime platform version.
|
||||
|
||||
If the runtime platform version is 19 or higher, and you wish to work with a URI obtained
|
||||
from a native file picker, use fromDocument() or fromTree() instead.
|
||||
|
||||
If this function fails, hasValue() will return false on the returned document.
|
||||
*/
|
||||
static AndroidDocument fromFile (const File& filePath);
|
||||
|
||||
/** Create an AndroidDocument representing a single document.
|
||||
|
||||
The argument should be a URL representing a document. Such URLs are returned by the system
|
||||
file-picker when it is not in folder-selection mode. If you pass a tree URL, this function
|
||||
will fail.
|
||||
|
||||
This function may fail on Android devices with API level 18 or lower, and on non-Android
|
||||
platforms. If this function fails, hasValue() will return false on the returned document.
|
||||
If calling this function fails, you may want to retry creating an AndroidDocument
|
||||
with fromFile(), passing the result of URL::getLocalFile().
|
||||
*/
|
||||
static AndroidDocument fromDocument (const URL& documentUrl);
|
||||
|
||||
/** Create an AndroidDocument representing the root of a tree of files.
|
||||
|
||||
The argument should be a URL representing a tree. Such URLs are returned by the system
|
||||
file-picker when it is in folder-selection mode. If you pass a URL referring to a document
|
||||
inside a tree, this will return a document referring to the root of the tree. If you pass
|
||||
a URL referring to a single file, this will fail.
|
||||
|
||||
When targeting platform version 30 or later, access to the filesystem via file paths is
|
||||
heavily restricted, and access to shared storage must use a new URI-based system instead.
|
||||
At time of writing, apps uploaded to the Play Store must target API 30 or higher.
|
||||
If you want read/write access to a shared folder, you must:
|
||||
|
||||
- Use a native FileChooser in canSelectDirectories mode, to allow the user to select a
|
||||
folder that your app can access. Your app will only have access to the contents of this
|
||||
directory; it cannot escape to the filesystem root. The system will not allow the user
|
||||
to grant access to certain locations, including filesystem roots and the Download folder.
|
||||
- Pass the URI that the user selected to fromTree(), and use the resulting AndroidDocument
|
||||
to read/write to the file system.
|
||||
|
||||
This function may fail on Android devices with API level 20 or lower, and on non-Android
|
||||
platforms. If this function fails, hasValue() will return false on the returned document.
|
||||
*/
|
||||
static AndroidDocument fromTree (const URL& treeUrl);
|
||||
|
||||
AndroidDocument (const AndroidDocument&);
|
||||
AndroidDocument (AndroidDocument&&) noexcept;
|
||||
|
||||
AndroidDocument& operator= (const AndroidDocument&);
|
||||
AndroidDocument& operator= (AndroidDocument&&) noexcept;
|
||||
|
||||
~AndroidDocument();
|
||||
|
||||
/** True if the URLs of the two documents match. */
|
||||
bool operator== (const AndroidDocument&) const;
|
||||
|
||||
/** False if the URLs of the two documents match. */
|
||||
bool operator!= (const AndroidDocument&) const;
|
||||
|
||||
/** Attempts to delete this document, and returns true on success. */
|
||||
bool deleteDocument() const;
|
||||
|
||||
/** Renames the document, and returns true on success.
|
||||
|
||||
This may cause the document's URI and metadata to change, so ensure to invalidate any
|
||||
cached information about the document (URLs, AndroidDocumentInfo instances) after calling
|
||||
this function.
|
||||
*/
|
||||
bool renameTo (const String& newDisplayName);
|
||||
|
||||
/** Attempts to create a new nested document with a particular type and name.
|
||||
|
||||
The type should be a standard MIME type string, e.g. "image/png", "text/plain".
|
||||
|
||||
The file name doesn't need to contain an extension, as this information is passed via the
|
||||
type argument. If this document is File-based rather than URL-based, then an appropriate
|
||||
file extension will be chosen based on the MIME type.
|
||||
|
||||
On failure, the returned AndroidDocument may be invalid, and will return false from hasValue().
|
||||
*/
|
||||
AndroidDocument createChildDocumentWithTypeAndName (const String& type, const String& name) const;
|
||||
|
||||
/** Attempts to create a new nested directory with a particular name.
|
||||
|
||||
On failure, the returned AndroidDocument may be invalid, and will return false from hasValue().
|
||||
*/
|
||||
AndroidDocument createChildDirectory (const String& name) const;
|
||||
|
||||
/** True if this object actually refers to a document.
|
||||
|
||||
If this function returns false, you *must not* call any function on this instance other
|
||||
than the special member functions to copy, move, and/or destruct the instance.
|
||||
*/
|
||||
bool hasValue() const { return pimpl != nullptr; }
|
||||
|
||||
/** Like hasValue(), but allows declaring AndroidDocument instances directly in 'if' statements. */
|
||||
explicit operator bool() const { return hasValue(); }
|
||||
|
||||
/** Creates a stream for reading from this document. */
|
||||
std::unique_ptr<InputStream> createInputStream() const;
|
||||
|
||||
/** Creates a stream for writing to this document. */
|
||||
std::unique_ptr<OutputStream> createOutputStream() const;
|
||||
|
||||
/** Returns the content URL describing this document. */
|
||||
URL getUrl() const;
|
||||
|
||||
/** Fetches information about this document. */
|
||||
AndroidDocumentInfo getInfo() const;
|
||||
|
||||
/** Experimental: Attempts to copy this document to a new parent, and returns an AndroidDocument
|
||||
representing the copy.
|
||||
|
||||
On failure, the returned AndroidDocument may be invalid, and will return false from hasValue().
|
||||
|
||||
This function may fail if the document doesn't allow copying, and when using URI-based
|
||||
documents on devices with API level 23 or lower. On failure, the returned AndroidDocument
|
||||
will return false from hasValue(). In testing, copying was not supported on the Android
|
||||
emulator for API 24, 30, or 31, so there's a good chance this function won't work on real
|
||||
devices.
|
||||
|
||||
@see AndroidDocumentInfo::canCopy
|
||||
*/
|
||||
AndroidDocument copyDocumentToParentDocument (const AndroidDocument& target) const;
|
||||
|
||||
/** Experimental: Attempts to move this document from one parent to another, and returns true on
|
||||
success.
|
||||
|
||||
This may cause the document's URI and metadata to change, so ensure to invalidate any
|
||||
cached information about the document (URLs, AndroidDocumentInfo instances) after calling
|
||||
this function.
|
||||
|
||||
This function may fail if the document doesn't allow moving, and when using URI-based
|
||||
documents on devices with API level 23 or lower.
|
||||
*/
|
||||
bool moveDocumentFromParentToParent (const AndroidDocument& currentParent,
|
||||
const AndroidDocument& newParent);
|
||||
|
||||
/** @internal */
|
||||
struct NativeInfo;
|
||||
|
||||
/** @internal */
|
||||
NativeInfo getNativeInfo() const;
|
||||
|
||||
private:
|
||||
struct Utils;
|
||||
class Pimpl;
|
||||
|
||||
explicit AndroidDocument (std::unique_ptr<Pimpl>);
|
||||
|
||||
void swap (AndroidDocument& other) noexcept { std::swap (other.pimpl, pimpl); }
|
||||
|
||||
std::unique_ptr<Pimpl> pimpl;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An iterator that visits child documents in a directory.
|
||||
|
||||
Instances of this iterator can be created by calling makeRecursive() or
|
||||
makeNonRecursive(). The results of these functions can additionally be used
|
||||
in standard algorithms, and in range-for loops:
|
||||
|
||||
@code
|
||||
AndroidDocument findFileWithName (const AndroidDocument& parent, const String& name)
|
||||
{
|
||||
for (const auto& child : AndroidDocumentIterator::makeNonRecursive (parent))
|
||||
if (child.getInfo().getName() == name)
|
||||
return child;
|
||||
|
||||
return AndroidDocument();
|
||||
}
|
||||
|
||||
std::vector<AndroidDocument> findAllChildrenRecursive (const AndroidDocument& parent)
|
||||
{
|
||||
std::vector<AndroidDocument> children;
|
||||
std::copy (AndroidDocumentIterator::makeRecursive (doc),
|
||||
AndroidDocumentIterator(),
|
||||
std::back_inserter (children));
|
||||
return children;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class AndroidDocumentIterator final
|
||||
{
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = void;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
/** Create an iterator that will visit each item in this directory. */
|
||||
static AndroidDocumentIterator makeNonRecursive (const AndroidDocument&);
|
||||
|
||||
/** Create an iterator that will visit each item in this directory, and all nested directories. */
|
||||
static AndroidDocumentIterator makeRecursive (const AndroidDocument&);
|
||||
|
||||
/** Creates an end/sentinel iterator. */
|
||||
AndroidDocumentIterator() = default;
|
||||
|
||||
bool operator== (const AndroidDocumentIterator& other) const noexcept { return pimpl == nullptr && other.pimpl == nullptr; }
|
||||
bool operator!= (const AndroidDocumentIterator& other) const noexcept { return ! operator== (other); }
|
||||
|
||||
/** Returns the document to which this iterator points. */
|
||||
AndroidDocument operator*() const;
|
||||
|
||||
/** Moves this iterator to the next position. */
|
||||
AndroidDocumentIterator& operator++();
|
||||
|
||||
/** Allows this iterator to be used directly in a range-for. */
|
||||
AndroidDocumentIterator begin() const { return *this; }
|
||||
|
||||
/** Allows this iterator to be used directly in a range-for. */
|
||||
AndroidDocumentIterator end() const { return AndroidDocumentIterator{}; }
|
||||
|
||||
private:
|
||||
struct Utils;
|
||||
struct Pimpl;
|
||||
|
||||
explicit AndroidDocumentIterator (std::unique_ptr<Pimpl>);
|
||||
|
||||
std::shared_ptr<Pimpl> pimpl;
|
||||
};
|
||||
|
||||
} // namespace juce
|
@ -1,150 +1,163 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
StringArray DirectoryIterator::parseWildcards (const String& pattern)
|
||||
{
|
||||
StringArray s;
|
||||
s.addTokens (pattern, ";,", "\"'");
|
||||
s.trim();
|
||||
s.removeEmptyStrings();
|
||||
return s;
|
||||
}
|
||||
|
||||
bool DirectoryIterator::fileMatches (const StringArray& wildcards, const String& filename)
|
||||
{
|
||||
for (auto& w : wildcards)
|
||||
if (filename.matchesWildcard (w, ! File::areFileNamesCaseSensitive()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
hasBeenAdvanced = true;
|
||||
|
||||
if (subIterator != nullptr)
|
||||
{
|
||||
if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly))
|
||||
return true;
|
||||
|
||||
subIterator.reset();
|
||||
}
|
||||
|
||||
String filename;
|
||||
bool isDirectory, isHidden = false, shouldContinue = 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.reset (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)
|
||||
{
|
||||
shouldContinue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! shouldContinue)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
const File& DirectoryIterator::getFile() const
|
||||
{
|
||||
if (subIterator != nullptr && subIterator->hasBeenAdvanced)
|
||||
return subIterator->getFile();
|
||||
|
||||
// You need to call DirectoryIterator::next() before asking it for the file that it found!
|
||||
jassert (hasBeenAdvanced);
|
||||
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
float DirectoryIterator::getEstimatedProgress() const
|
||||
{
|
||||
if (totalNumFiles < 0)
|
||||
totalNumFiles = File (path).getNumberOfChildFiles (File::findFilesAndDirectories);
|
||||
|
||||
if (totalNumFiles <= 0)
|
||||
return 0.0f;
|
||||
|
||||
auto detailedIndex = (subIterator != nullptr) ? (float) index + subIterator->getEstimatedProgress()
|
||||
: (float) index;
|
||||
|
||||
return jlimit (0.0f, 1.0f, detailedIndex / (float) totalNumFiles);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
StringArray DirectoryIterator::parseWildcards (const String& pattern)
|
||||
{
|
||||
StringArray s;
|
||||
s.addTokens (pattern, ";,", "\"'");
|
||||
s.trim();
|
||||
s.removeEmptyStrings();
|
||||
return s;
|
||||
}
|
||||
|
||||
bool DirectoryIterator::fileMatches (const StringArray& wildcards, const String& filename)
|
||||
{
|
||||
for (auto& w : wildcards)
|
||||
if (filename.matchesWildcard (w, ! File::areFileNamesCaseSensitive()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
hasBeenAdvanced = true;
|
||||
|
||||
if (subIterator != nullptr)
|
||||
{
|
||||
if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly))
|
||||
return true;
|
||||
|
||||
subIterator.reset();
|
||||
}
|
||||
|
||||
String filename;
|
||||
bool isDirectory, isHidden = false, shouldContinue = false;
|
||||
|
||||
while (fileFinder.next (filename, &isDirectory,
|
||||
(isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr,
|
||||
fileSize, modTime, creationTime, isReadOnly))
|
||||
{
|
||||
++index;
|
||||
|
||||
if (! filename.containsOnly ("."))
|
||||
{
|
||||
const auto fullPath = File::createFileWithoutCheckingPath (path + filename);
|
||||
bool matches = false;
|
||||
|
||||
if (isDirectory)
|
||||
{
|
||||
const auto mayRecurseIntoPossibleHiddenDir = [this, &isHidden]
|
||||
{
|
||||
return (whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden;
|
||||
};
|
||||
|
||||
const auto mayRecurseIntoPossibleSymlink = [this, &fullPath]
|
||||
{
|
||||
return followSymlinks == File::FollowSymlinks::yes
|
||||
|| ! fullPath.isSymbolicLink()
|
||||
|| (followSymlinks == File::FollowSymlinks::noCycles
|
||||
&& knownPaths->find (fullPath.getLinkedTarget()) == knownPaths->end());
|
||||
};
|
||||
|
||||
if (isRecursive && mayRecurseIntoPossibleHiddenDir() && mayRecurseIntoPossibleSymlink())
|
||||
subIterator.reset (new DirectoryIterator (fullPath, true, wildCard, whatToLookFor, followSymlinks, knownPaths));
|
||||
|
||||
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 = fullPath;
|
||||
if (isHiddenResult != nullptr) *isHiddenResult = isHidden;
|
||||
if (isDirResult != nullptr) *isDirResult = isDirectory;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subIterator != nullptr)
|
||||
{
|
||||
shouldContinue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! shouldContinue)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
const File& DirectoryIterator::getFile() const
|
||||
{
|
||||
if (subIterator != nullptr && subIterator->hasBeenAdvanced)
|
||||
return subIterator->getFile();
|
||||
|
||||
// You need to call DirectoryIterator::next() before asking it for the file that it found!
|
||||
jassert (hasBeenAdvanced);
|
||||
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
float DirectoryIterator::getEstimatedProgress() const
|
||||
{
|
||||
if (totalNumFiles < 0)
|
||||
totalNumFiles = File (path).getNumberOfChildFiles (File::findFilesAndDirectories);
|
||||
|
||||
if (totalNumFiles <= 0)
|
||||
return 0.0f;
|
||||
|
||||
auto detailedIndex = (subIterator != nullptr) ? (float) index + subIterator->getEstimatedProgress()
|
||||
: (float) index;
|
||||
|
||||
return jlimit (0.0f, 1.0f, detailedIndex / (float) totalNumFiles);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,164 +1,197 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
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
|
||||
a wildcard filepattern match.
|
||||
|
||||
If you may be scanning a large number of files, it's usually smarter to use this
|
||||
class than File::findChildFiles() because it allows you to stop at any time, rather
|
||||
than having to wait for the entire scan to finish before getting the results.
|
||||
|
||||
Please note that the order in which files are returned is completely undefined!
|
||||
They'll arrive in whatever order the underlying OS calls provide them, which will
|
||||
depend on the filesystem and other factors. If you need a sorted list, you'll need
|
||||
to manually sort them using your preferred comparator after collecting the list.
|
||||
|
||||
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.
|
||||
|
||||
After creating one of these, call its next() method to get the
|
||||
first file - e.g. @code
|
||||
|
||||
DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose");
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
File theFileItFound (iter.getFile());
|
||||
|
||||
... etc
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see RangedDirectoryIterator
|
||||
*/
|
||||
[[deprecated ("This class is now deprecated in favour of RangedDirectoryIterator.")]]
|
||||
DirectoryIterator (const File& directory,
|
||||
bool recursive,
|
||||
const String& pattern = "*",
|
||||
int type = File::findFiles)
|
||||
: wildCards (parseWildcards (pattern)),
|
||||
fileFinder (directory, (recursive || wildCards.size() > 1) ? "*" : pattern),
|
||||
wildCard (pattern),
|
||||
path (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
whatToLookFor (type),
|
||||
isRecursive (recursive)
|
||||
{
|
||||
// you have to specify the type of files you're looking for!
|
||||
jassert ((whatToLookFor & (File::findFiles | File::findDirectories)) != 0);
|
||||
jassert (whatToLookFor > 0 && whatToLookFor <= 7);
|
||||
}
|
||||
|
||||
/** Moves the iterator along to the next file.
|
||||
|
||||
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
||||
false if there are no more matching files.
|
||||
*/
|
||||
bool next();
|
||||
|
||||
/** Moves the iterator along to the next file, and returns various properties of that file.
|
||||
|
||||
If you need to find out details about the file, it's more efficient to call this method than
|
||||
to call the normal next() method and then find out the details afterwards.
|
||||
|
||||
All the parameters are optional, so pass null pointers for any items that you're not
|
||||
interested in.
|
||||
|
||||
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
||||
false if there are no more matching files. If it returns false, then none of the
|
||||
parameters will be filled-in.
|
||||
*/
|
||||
bool next (bool* isDirectory,
|
||||
bool* isHidden,
|
||||
int64* fileSize,
|
||||
Time* modTime,
|
||||
Time* creationTime,
|
||||
bool* isReadOnly);
|
||||
|
||||
/** Returns the file that the iterator is currently pointing at.
|
||||
|
||||
The result of this call is only valid after a call to next() has returned true.
|
||||
*/
|
||||
const File& getFile() const;
|
||||
|
||||
/** Returns a guess of how far through the search the iterator has got.
|
||||
|
||||
@returns a value 0.0 to 1.0 to show the progress, although this won't be
|
||||
very accurate.
|
||||
*/
|
||||
float getEstimatedProgress() const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct NativeIterator
|
||||
{
|
||||
NativeIterator (const File& directory, const String& wildCard);
|
||||
~NativeIterator();
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* isDirectory, bool* isHidden, int64* fileSize,
|
||||
Time* modTime, Time* creationTime, bool* isReadOnly);
|
||||
|
||||
class Pimpl;
|
||||
std::unique_ptr<Pimpl> pimpl;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeIterator)
|
||||
};
|
||||
|
||||
StringArray wildCards;
|
||||
NativeIterator fileFinder;
|
||||
String wildCard, path;
|
||||
int index = -1;
|
||||
mutable int totalNumFiles = -1;
|
||||
const int whatToLookFor;
|
||||
const bool isRecursive;
|
||||
bool hasBeenAdvanced = false;
|
||||
std::unique_ptr<DirectoryIterator> subIterator;
|
||||
File currentFile;
|
||||
|
||||
static StringArray parseWildcards (const String& pattern);
|
||||
static bool fileMatches (const StringArray& wildCards, const String& filename);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryIterator)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
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
|
||||
a wildcard filepattern match.
|
||||
|
||||
The iterator keeps track of directories that it has previously traversed, and will
|
||||
skip any previously-seen directories in the case of cycles caused by symbolic links.
|
||||
It is also possible to avoid following symbolic links altogether.
|
||||
|
||||
If you may be scanning a large number of files, it's usually smarter to use this
|
||||
class than File::findChildFiles() because it allows you to stop at any time, rather
|
||||
than having to wait for the entire scan to finish before getting the results.
|
||||
|
||||
Please note that the order in which files are returned is completely undefined!
|
||||
They'll arrive in whatever order the underlying OS calls provide them, which will
|
||||
depend on the filesystem and other factors. If you need a sorted list, you'll need
|
||||
to manually sort them using your preferred comparator after collecting the list.
|
||||
|
||||
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.
|
||||
|
||||
After creating one of these, call its next() method to get the
|
||||
first file - e.g. @code
|
||||
|
||||
DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose");
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
File theFileItFound (iter.getFile());
|
||||
|
||||
... etc
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see RangedDirectoryIterator
|
||||
*/
|
||||
[[deprecated ("This class is now deprecated in favour of RangedDirectoryIterator.")]]
|
||||
DirectoryIterator (const File& directory,
|
||||
bool recursive,
|
||||
const String& pattern = "*",
|
||||
int type = File::findFiles,
|
||||
File::FollowSymlinks follow = File::FollowSymlinks::yes)
|
||||
: DirectoryIterator (directory, recursive, pattern, type, follow, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/** Moves the iterator along to the next file.
|
||||
|
||||
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
||||
false if there are no more matching files.
|
||||
*/
|
||||
bool next();
|
||||
|
||||
/** Moves the iterator along to the next file, and returns various properties of that file.
|
||||
|
||||
If you need to find out details about the file, it's more efficient to call this method than
|
||||
to call the normal next() method and then find out the details afterwards.
|
||||
|
||||
All the parameters are optional, so pass null pointers for any items that you're not
|
||||
interested in.
|
||||
|
||||
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
||||
false if there are no more matching files. If it returns false, then none of the
|
||||
parameters will be filled-in.
|
||||
*/
|
||||
bool next (bool* isDirectory,
|
||||
bool* isHidden,
|
||||
int64* fileSize,
|
||||
Time* modTime,
|
||||
Time* creationTime,
|
||||
bool* isReadOnly);
|
||||
|
||||
/** Returns the file that the iterator is currently pointing at.
|
||||
|
||||
The result of this call is only valid after a call to next() has returned true.
|
||||
*/
|
||||
const File& getFile() const;
|
||||
|
||||
/** Returns a guess of how far through the search the iterator has got.
|
||||
|
||||
@returns a value 0.0 to 1.0 to show the progress, although this won't be
|
||||
very accurate.
|
||||
*/
|
||||
float getEstimatedProgress() const;
|
||||
|
||||
private:
|
||||
using KnownPaths = std::set<File>;
|
||||
|
||||
DirectoryIterator (const File& directory,
|
||||
bool recursive,
|
||||
const String& pattern,
|
||||
int type,
|
||||
File::FollowSymlinks follow,
|
||||
KnownPaths* seenPaths)
|
||||
: wildCards (parseWildcards (pattern)),
|
||||
fileFinder (directory, (recursive || wildCards.size() > 1) ? "*" : pattern),
|
||||
wildCard (pattern),
|
||||
path (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
whatToLookFor (type),
|
||||
isRecursive (recursive),
|
||||
followSymlinks (follow),
|
||||
knownPaths (seenPaths)
|
||||
{
|
||||
// you have to specify the type of files you're looking for!
|
||||
jassert ((whatToLookFor & (File::findFiles | File::findDirectories)) != 0);
|
||||
jassert (whatToLookFor > 0 && whatToLookFor <= 7);
|
||||
|
||||
if (followSymlinks == File::FollowSymlinks::noCycles)
|
||||
{
|
||||
if (knownPaths == nullptr)
|
||||
{
|
||||
heapKnownPaths = std::make_unique<KnownPaths>();
|
||||
knownPaths = heapKnownPaths.get();
|
||||
}
|
||||
|
||||
knownPaths->insert (directory);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct NativeIterator
|
||||
{
|
||||
NativeIterator (const File& directory, const String& wildCard);
|
||||
~NativeIterator();
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* isDirectory, bool* isHidden, int64* fileSize,
|
||||
Time* modTime, Time* creationTime, bool* isReadOnly);
|
||||
|
||||
class Pimpl;
|
||||
std::unique_ptr<Pimpl> pimpl;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeIterator)
|
||||
};
|
||||
|
||||
StringArray wildCards;
|
||||
NativeIterator fileFinder;
|
||||
String wildCard, path;
|
||||
int index = -1;
|
||||
mutable int totalNumFiles = -1;
|
||||
const int whatToLookFor;
|
||||
const bool isRecursive;
|
||||
bool hasBeenAdvanced = false;
|
||||
std::unique_ptr<DirectoryIterator> subIterator;
|
||||
File currentFile;
|
||||
File::FollowSymlinks followSymlinks = File::FollowSymlinks::yes;
|
||||
KnownPaths* knownPaths = nullptr;
|
||||
std::unique_ptr<KnownPaths> heapKnownPaths;
|
||||
|
||||
static StringArray parseWildcards (const String& pattern);
|
||||
static bool fileMatches (const StringArray& wildCards, const String& filename);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryIterator)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
2569
deps/juce/modules/juce_core/files/juce_File.cpp
vendored
2569
deps/juce/modules/juce_core/files/juce_File.cpp
vendored
File diff suppressed because it is too large
Load Diff
2301
deps/juce/modules/juce_core/files/juce_File.h
vendored
2301
deps/juce/modules/juce_core/files/juce_File.h
vendored
File diff suppressed because it is too large
Load Diff
@ -1,40 +1,40 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
FileFilter::FileFilter (const String& filterDescription)
|
||||
: description (filterDescription)
|
||||
{
|
||||
}
|
||||
|
||||
FileFilter::~FileFilter()
|
||||
{
|
||||
}
|
||||
|
||||
const String& FileFilter::getDescription() const noexcept
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
FileFilter::FileFilter (const String& filterDescription)
|
||||
: description (filterDescription)
|
||||
{
|
||||
}
|
||||
|
||||
FileFilter::~FileFilter()
|
||||
{
|
||||
}
|
||||
|
||||
const String& FileFilter::getDescription() const noexcept
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
142
deps/juce/modules/juce_core/files/juce_FileFilter.h
vendored
142
deps/juce/modules/juce_core/files/juce_FileFilter.h
vendored
@ -1,71 +1,71 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Interface for deciding which files are suitable for something.
|
||||
|
||||
For example, this is used by DirectoryContentsList to select which files
|
||||
go into the list.
|
||||
|
||||
@see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileFilter
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a filter with the given description.
|
||||
|
||||
The description can be returned later with the getDescription() method.
|
||||
*/
|
||||
FileFilter (const String& filterDescription);
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~FileFilter();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the description that the filter was created with. */
|
||||
const String& getDescription() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Should return true if this file is suitable for inclusion in whatever context
|
||||
the object is being used.
|
||||
*/
|
||||
virtual bool isFileSuitable (const File& file) const = 0;
|
||||
|
||||
/** Should return true if this directory is suitable for inclusion in whatever context
|
||||
the object is being used.
|
||||
*/
|
||||
virtual bool isDirectorySuitable (const File& file) const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
String description;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Interface for deciding which files are suitable for something.
|
||||
|
||||
For example, this is used by DirectoryContentsList to select which files
|
||||
go into the list.
|
||||
|
||||
@see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileFilter
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a filter with the given description.
|
||||
|
||||
The description can be returned later with the getDescription() method.
|
||||
*/
|
||||
FileFilter (const String& filterDescription);
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~FileFilter();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the description that the filter was created with. */
|
||||
const String& getDescription() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Should return true if this file is suitable for inclusion in whatever context
|
||||
the object is being used.
|
||||
*/
|
||||
virtual bool isFileSuitable (const File& file) const = 0;
|
||||
|
||||
/** Should return true if this directory is suitable for inclusion in whatever context
|
||||
the object is being used.
|
||||
*/
|
||||
virtual bool isDirectorySuitable (const File& file) const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
String description;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,177 +1,177 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
int64 juce_fileSetPosition (void* handle, int64 pos);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
FileInputStream::FileInputStream (const File& f) : file (f)
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
||||
int64 FileInputStream::getTotalLength()
|
||||
{
|
||||
// You should always check that a stream opened successfully before using it!
|
||||
jassert (openedOk());
|
||||
|
||||
return file.getSize();
|
||||
}
|
||||
|
||||
int FileInputStream::read (void* buffer, int bytesToRead)
|
||||
{
|
||||
// You should always check that a stream opened successfully before using it!
|
||||
jassert (openedOk());
|
||||
|
||||
// The buffer should never be null, and a negative size is probably a
|
||||
// sign that something is broken!
|
||||
jassert (buffer != nullptr && bytesToRead >= 0);
|
||||
|
||||
auto num = readInternal (buffer, (size_t) bytesToRead);
|
||||
currentPosition += (int64) num;
|
||||
|
||||
return (int) num;
|
||||
}
|
||||
|
||||
bool FileInputStream::isExhausted()
|
||||
{
|
||||
return currentPosition >= getTotalLength();
|
||||
}
|
||||
|
||||
int64 FileInputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileInputStream::setPosition (int64 pos)
|
||||
{
|
||||
// You should always check that a stream opened successfully before using it!
|
||||
jassert (openedOk());
|
||||
|
||||
if (pos != currentPosition)
|
||||
currentPosition = juce_fileSetPosition (fileHandle, pos);
|
||||
|
||||
return currentPosition == pos;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
struct FileInputStreamTests : public UnitTest
|
||||
{
|
||||
FileInputStreamTests()
|
||||
: UnitTest ("FileInputStream", UnitTestCategories::streams)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("Open stream non-existent file");
|
||||
{
|
||||
auto tempFile = File::createTempFile (".txt");
|
||||
expect (! tempFile.exists());
|
||||
|
||||
FileInputStream stream (tempFile);
|
||||
expect (stream.failedToOpen());
|
||||
}
|
||||
|
||||
beginTest ("Open stream existing file");
|
||||
{
|
||||
auto tempFile = File::createTempFile (".txt");
|
||||
tempFile.create();
|
||||
expect (tempFile.exists());
|
||||
|
||||
FileInputStream stream (tempFile);
|
||||
expect (stream.openedOk());
|
||||
}
|
||||
|
||||
const MemoryBlock data ("abcdefghijklmnopqrstuvwxyz", 26);
|
||||
File f (File::createTempFile (".txt"));
|
||||
f.appendData (data.getData(), data.getSize());
|
||||
FileInputStream stream (f);
|
||||
|
||||
beginTest ("Read");
|
||||
{
|
||||
expectEquals (stream.getPosition(), (int64) 0);
|
||||
expectEquals (stream.getTotalLength(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
|
||||
expect (! stream.isExhausted());
|
||||
|
||||
size_t numBytesRead = 0;
|
||||
MemoryBlock readBuffer (data.getSize());
|
||||
|
||||
while (numBytesRead < data.getSize())
|
||||
{
|
||||
numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) numBytesRead);
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
|
||||
expect (stream.isExhausted() == (numBytesRead == data.getSize()));
|
||||
}
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) 0);
|
||||
expect (stream.isExhausted());
|
||||
|
||||
expect (readBuffer == data);
|
||||
}
|
||||
|
||||
beginTest ("Skip");
|
||||
{
|
||||
stream.setPosition (0);
|
||||
expectEquals (stream.getPosition(), (int64) 0);
|
||||
expectEquals (stream.getTotalLength(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
|
||||
expect (! stream.isExhausted());
|
||||
|
||||
size_t numBytesRead = 0;
|
||||
const int numBytesToSkip = 5;
|
||||
|
||||
while (numBytesRead < data.getSize())
|
||||
{
|
||||
stream.skipNextBytes (numBytesToSkip);
|
||||
numBytesRead += numBytesToSkip;
|
||||
numBytesRead = std::min (numBytesRead, data.getSize());
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) numBytesRead);
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
|
||||
expect (stream.isExhausted() == (numBytesRead == data.getSize()));
|
||||
}
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) 0);
|
||||
expect (stream.isExhausted());
|
||||
|
||||
f.deleteFile();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static FileInputStreamTests fileInputStreamTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
int64 juce_fileSetPosition (void* handle, int64 pos);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
FileInputStream::FileInputStream (const File& f) : file (f)
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
||||
int64 FileInputStream::getTotalLength()
|
||||
{
|
||||
// You should always check that a stream opened successfully before using it!
|
||||
jassert (openedOk());
|
||||
|
||||
return file.getSize();
|
||||
}
|
||||
|
||||
int FileInputStream::read (void* buffer, int bytesToRead)
|
||||
{
|
||||
// You should always check that a stream opened successfully before using it!
|
||||
jassert (openedOk());
|
||||
|
||||
// The buffer should never be null, and a negative size is probably a
|
||||
// sign that something is broken!
|
||||
jassert (buffer != nullptr && bytesToRead >= 0);
|
||||
|
||||
auto num = readInternal (buffer, (size_t) bytesToRead);
|
||||
currentPosition += (int64) num;
|
||||
|
||||
return (int) num;
|
||||
}
|
||||
|
||||
bool FileInputStream::isExhausted()
|
||||
{
|
||||
return currentPosition >= getTotalLength();
|
||||
}
|
||||
|
||||
int64 FileInputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileInputStream::setPosition (int64 pos)
|
||||
{
|
||||
// You should always check that a stream opened successfully before using it!
|
||||
jassert (openedOk());
|
||||
|
||||
if (pos != currentPosition)
|
||||
currentPosition = juce_fileSetPosition (fileHandle, pos);
|
||||
|
||||
return currentPosition == pos;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
struct FileInputStreamTests : public UnitTest
|
||||
{
|
||||
FileInputStreamTests()
|
||||
: UnitTest ("FileInputStream", UnitTestCategories::streams)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("Open stream non-existent file");
|
||||
{
|
||||
auto tempFile = File::createTempFile (".txt");
|
||||
expect (! tempFile.exists());
|
||||
|
||||
FileInputStream stream (tempFile);
|
||||
expect (stream.failedToOpen());
|
||||
}
|
||||
|
||||
beginTest ("Open stream existing file");
|
||||
{
|
||||
auto tempFile = File::createTempFile (".txt");
|
||||
tempFile.create();
|
||||
expect (tempFile.exists());
|
||||
|
||||
FileInputStream stream (tempFile);
|
||||
expect (stream.openedOk());
|
||||
}
|
||||
|
||||
const MemoryBlock data ("abcdefghijklmnopqrstuvwxyz", 26);
|
||||
File f (File::createTempFile (".txt"));
|
||||
f.appendData (data.getData(), data.getSize());
|
||||
FileInputStream stream (f);
|
||||
|
||||
beginTest ("Read");
|
||||
{
|
||||
expectEquals (stream.getPosition(), (int64) 0);
|
||||
expectEquals (stream.getTotalLength(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
|
||||
expect (! stream.isExhausted());
|
||||
|
||||
size_t numBytesRead = 0;
|
||||
MemoryBlock readBuffer (data.getSize());
|
||||
|
||||
while (numBytesRead < data.getSize())
|
||||
{
|
||||
numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) numBytesRead);
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
|
||||
expect (stream.isExhausted() == (numBytesRead == data.getSize()));
|
||||
}
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) 0);
|
||||
expect (stream.isExhausted());
|
||||
|
||||
expect (readBuffer == data);
|
||||
}
|
||||
|
||||
beginTest ("Skip");
|
||||
{
|
||||
stream.setPosition (0);
|
||||
expectEquals (stream.getPosition(), (int64) 0);
|
||||
expectEquals (stream.getTotalLength(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
|
||||
expect (! stream.isExhausted());
|
||||
|
||||
size_t numBytesRead = 0;
|
||||
const int numBytesToSkip = 5;
|
||||
|
||||
while (numBytesRead < data.getSize())
|
||||
{
|
||||
stream.skipNextBytes (numBytesToSkip);
|
||||
numBytesRead += numBytesToSkip;
|
||||
numBytesRead = std::min (numBytesRead, data.getSize());
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) numBytesRead);
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
|
||||
expect (stream.isExhausted() == (numBytesRead == data.getSize()));
|
||||
}
|
||||
|
||||
expectEquals (stream.getPosition(), (int64) data.getSize());
|
||||
expectEquals (stream.getNumBytesRemaining(), (int64) 0);
|
||||
expect (stream.isExhausted());
|
||||
|
||||
f.deleteFile();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static FileInputStreamTests fileInputStreamTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,90 +1,90 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An input stream that reads from a local file.
|
||||
|
||||
@see InputStream, FileOutputStream, File::createInputStream
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileInputStream : public InputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FileInputStream to read from the given file.
|
||||
|
||||
After creating a FileInputStream, you should use openedOk() or failedToOpen()
|
||||
to make sure that it's OK before trying to read from it! If it failed, you
|
||||
can call getStatus() to get more error information.
|
||||
*/
|
||||
explicit FileInputStream (const File& fileToRead);
|
||||
|
||||
/** Destructor. */
|
||||
~FileInputStream() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file that this stream is reading from. */
|
||||
const File& getFile() const noexcept { return file; }
|
||||
|
||||
/** Returns the status of the file stream.
|
||||
The result will be ok if the file opened successfully. If an error occurs while
|
||||
opening or reading from the file, this will contain an error message.
|
||||
*/
|
||||
const Result& getStatus() const noexcept { return status; }
|
||||
|
||||
/** Returns true if the stream couldn't be opened for some reason.
|
||||
@see getResult()
|
||||
*/
|
||||
bool failedToOpen() const noexcept { return status.failed(); }
|
||||
|
||||
/** Returns true if the stream opened without problems.
|
||||
@see getResult()
|
||||
*/
|
||||
bool openedOk() const noexcept { return status.wasOk(); }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
int64 getTotalLength() override;
|
||||
int read (void*, int) override;
|
||||
bool isExhausted() override;
|
||||
int64 getPosition() override;
|
||||
bool setPosition (int64) override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
const File file;
|
||||
void* fileHandle = nullptr;
|
||||
int64 currentPosition = 0;
|
||||
Result status { Result::ok() };
|
||||
|
||||
void openHandle();
|
||||
size_t readInternal (void*, size_t);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileInputStream)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An input stream that reads from a local file.
|
||||
|
||||
@see InputStream, FileOutputStream, File::createInputStream
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileInputStream : public InputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FileInputStream to read from the given file.
|
||||
|
||||
After creating a FileInputStream, you should use openedOk() or failedToOpen()
|
||||
to make sure that it's OK before trying to read from it! If it failed, you
|
||||
can call getStatus() to get more error information.
|
||||
*/
|
||||
explicit FileInputStream (const File& fileToRead);
|
||||
|
||||
/** Destructor. */
|
||||
~FileInputStream() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file that this stream is reading from. */
|
||||
const File& getFile() const noexcept { return file; }
|
||||
|
||||
/** Returns the status of the file stream.
|
||||
The result will be ok if the file opened successfully. If an error occurs while
|
||||
opening or reading from the file, this will contain an error message.
|
||||
*/
|
||||
const Result& getStatus() const noexcept { return status; }
|
||||
|
||||
/** Returns true if the stream couldn't be opened for some reason.
|
||||
@see getResult()
|
||||
*/
|
||||
bool failedToOpen() const noexcept { return status.failed(); }
|
||||
|
||||
/** Returns true if the stream opened without problems.
|
||||
@see getResult()
|
||||
*/
|
||||
bool openedOk() const noexcept { return status.wasOk(); }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
int64 getTotalLength() override;
|
||||
int read (void*, int) override;
|
||||
bool isExhausted() override;
|
||||
int64 getPosition() override;
|
||||
bool setPosition (int64) override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
const File file;
|
||||
void* fileHandle = nullptr;
|
||||
int64 currentPosition = 0;
|
||||
Result status { Result::ok() };
|
||||
|
||||
void openHandle();
|
||||
size_t readInternal (void*, size_t);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileInputStream)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,130 +1,130 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse)
|
||||
: file (f),
|
||||
bufferSize (bufferSizeToUse),
|
||||
buffer (jmax (bufferSizeToUse, (size_t) 16))
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
||||
FileOutputStream::~FileOutputStream()
|
||||
{
|
||||
flushBuffer();
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
int64 FileOutputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::setPosition (int64 newPosition)
|
||||
{
|
||||
if (newPosition != currentPosition)
|
||||
{
|
||||
flushBuffer();
|
||||
currentPosition = juce_fileSetPosition (fileHandle, newPosition);
|
||||
}
|
||||
|
||||
return newPosition == currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::flushBuffer()
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
if (bytesInBuffer > 0)
|
||||
{
|
||||
ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer);
|
||||
bytesInBuffer = 0;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void FileOutputStream::flush()
|
||||
{
|
||||
flushBuffer();
|
||||
flushInternal();
|
||||
}
|
||||
|
||||
bool FileOutputStream::write (const void* const src, const size_t numBytes)
|
||||
{
|
||||
jassert (src != nullptr && ((ssize_t) numBytes) >= 0);
|
||||
|
||||
if (! openedOk())
|
||||
return false;
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
memcpy (buffer + bytesInBuffer, src, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += (int64) numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! flushBuffer())
|
||||
return false;
|
||||
|
||||
if (numBytes < bufferSize)
|
||||
{
|
||||
memcpy (buffer + bytesInBuffer, src, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += (int64) numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto bytesWritten = writeInternal (src, numBytes);
|
||||
|
||||
if (bytesWritten < 0)
|
||||
return false;
|
||||
|
||||
currentPosition += (int64) bytesWritten;
|
||||
return bytesWritten == (ssize_t) numBytes;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes)
|
||||
{
|
||||
jassert (((ssize_t) numBytes) >= 0);
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
memset (buffer + bytesInBuffer, byte, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += (int64) numBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
return OutputStream::writeRepeatedByte (byte, numBytes);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse)
|
||||
: file (f),
|
||||
bufferSize (bufferSizeToUse),
|
||||
buffer (jmax (bufferSizeToUse, (size_t) 16))
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
||||
FileOutputStream::~FileOutputStream()
|
||||
{
|
||||
flushBuffer();
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
int64 FileOutputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::setPosition (int64 newPosition)
|
||||
{
|
||||
if (newPosition != currentPosition)
|
||||
{
|
||||
flushBuffer();
|
||||
currentPosition = juce_fileSetPosition (fileHandle, newPosition);
|
||||
}
|
||||
|
||||
return newPosition == currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::flushBuffer()
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
if (bytesInBuffer > 0)
|
||||
{
|
||||
ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer);
|
||||
bytesInBuffer = 0;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void FileOutputStream::flush()
|
||||
{
|
||||
flushBuffer();
|
||||
flushInternal();
|
||||
}
|
||||
|
||||
bool FileOutputStream::write (const void* const src, const size_t numBytes)
|
||||
{
|
||||
jassert (src != nullptr && ((ssize_t) numBytes) >= 0);
|
||||
|
||||
if (! openedOk())
|
||||
return false;
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
memcpy (buffer + bytesInBuffer, src, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += (int64) numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! flushBuffer())
|
||||
return false;
|
||||
|
||||
if (numBytes < bufferSize)
|
||||
{
|
||||
memcpy (buffer + bytesInBuffer, src, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += (int64) numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto bytesWritten = writeInternal (src, numBytes);
|
||||
|
||||
if (bytesWritten < 0)
|
||||
return false;
|
||||
|
||||
currentPosition += (int64) bytesWritten;
|
||||
return bytesWritten == (ssize_t) numBytes;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes)
|
||||
{
|
||||
jassert (((ssize_t) numBytes) >= 0);
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
memset (buffer + bytesInBuffer, byte, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += (int64) numBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
return OutputStream::writeRepeatedByte (byte, numBytes);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,126 +1,126 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An output stream that writes into a local file.
|
||||
|
||||
@see OutputStream, FileInputStream, File::createOutputStream
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileOutputStream : public OutputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FileOutputStream.
|
||||
|
||||
If the file doesn't exist, it will first be created. If the file can't be
|
||||
created or opened (for example, because the parent directory of the file
|
||||
does not exist), the failedToOpen() method will return true.
|
||||
|
||||
If the file already exists when opened, the stream's write-position will
|
||||
be set to the end of the file. To overwrite an existing file, you can truncate
|
||||
it like this:
|
||||
|
||||
@code
|
||||
FileOutputStream stream (file);
|
||||
|
||||
if (stream.openedOk())
|
||||
{
|
||||
stream.setPosition (0);
|
||||
stream.truncate();
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
Destroying a FileOutputStream object does not force the operating system
|
||||
to write the buffered data to disk immediately. If this is required you
|
||||
should call flush() before triggering the destructor.
|
||||
|
||||
@see TemporaryFile
|
||||
*/
|
||||
FileOutputStream (const File& fileToWriteTo,
|
||||
size_t bufferSizeToUse = 16384);
|
||||
|
||||
/** Destructor. */
|
||||
~FileOutputStream() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file that this stream is writing to.
|
||||
*/
|
||||
const File& getFile() const { return file; }
|
||||
|
||||
/** Returns the status of the file stream.
|
||||
The result will be ok if the file opened successfully. If an error occurs while
|
||||
opening or writing to the file, this will contain an error message.
|
||||
*/
|
||||
const Result& getStatus() const noexcept { return status; }
|
||||
|
||||
/** Returns true if the stream couldn't be opened for some reason.
|
||||
@see getResult()
|
||||
*/
|
||||
bool failedToOpen() const noexcept { return status.failed(); }
|
||||
|
||||
/** Returns true if the stream opened without problems.
|
||||
@see getResult()
|
||||
*/
|
||||
bool openedOk() const noexcept { return status.wasOk(); }
|
||||
|
||||
/** Attempts to truncate the file to the current write position.
|
||||
To truncate a file to a specific size, first use setPosition() to seek to the
|
||||
appropriate location, and then call this method.
|
||||
*/
|
||||
Result truncate();
|
||||
|
||||
//==============================================================================
|
||||
void flush() override;
|
||||
int64 getPosition() override;
|
||||
bool setPosition (int64) override;
|
||||
bool write (const void*, size_t) override;
|
||||
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
File file;
|
||||
void* fileHandle = nullptr;
|
||||
Result status { Result::ok() };
|
||||
int64 currentPosition = 0;
|
||||
size_t bufferSize, bytesInBuffer = 0;
|
||||
HeapBlock<char> buffer;
|
||||
|
||||
void openHandle();
|
||||
void closeHandle();
|
||||
void flushInternal();
|
||||
bool flushBuffer();
|
||||
int64 setPositionInternal (int64);
|
||||
ssize_t writeInternal (const void*, size_t);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileOutputStream)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An output stream that writes into a local file.
|
||||
|
||||
@see OutputStream, FileInputStream, File::createOutputStream
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileOutputStream : public OutputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FileOutputStream.
|
||||
|
||||
If the file doesn't exist, it will first be created. If the file can't be
|
||||
created or opened (for example, because the parent directory of the file
|
||||
does not exist), the failedToOpen() method will return true.
|
||||
|
||||
If the file already exists when opened, the stream's write-position will
|
||||
be set to the end of the file. To overwrite an existing file, you can truncate
|
||||
it like this:
|
||||
|
||||
@code
|
||||
FileOutputStream stream (file);
|
||||
|
||||
if (stream.openedOk())
|
||||
{
|
||||
stream.setPosition (0);
|
||||
stream.truncate();
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
Destroying a FileOutputStream object does not force the operating system
|
||||
to write the buffered data to disk immediately. If this is required you
|
||||
should call flush() before triggering the destructor.
|
||||
|
||||
@see TemporaryFile
|
||||
*/
|
||||
FileOutputStream (const File& fileToWriteTo,
|
||||
size_t bufferSizeToUse = 16384);
|
||||
|
||||
/** Destructor. */
|
||||
~FileOutputStream() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file that this stream is writing to.
|
||||
*/
|
||||
const File& getFile() const { return file; }
|
||||
|
||||
/** Returns the status of the file stream.
|
||||
The result will be ok if the file opened successfully. If an error occurs while
|
||||
opening or writing to the file, this will contain an error message.
|
||||
*/
|
||||
const Result& getStatus() const noexcept { return status; }
|
||||
|
||||
/** Returns true if the stream couldn't be opened for some reason.
|
||||
@see getResult()
|
||||
*/
|
||||
bool failedToOpen() const noexcept { return status.failed(); }
|
||||
|
||||
/** Returns true if the stream opened without problems.
|
||||
@see getResult()
|
||||
*/
|
||||
bool openedOk() const noexcept { return status.wasOk(); }
|
||||
|
||||
/** Attempts to truncate the file to the current write position.
|
||||
To truncate a file to a specific size, first use setPosition() to seek to the
|
||||
appropriate location, and then call this method.
|
||||
*/
|
||||
Result truncate();
|
||||
|
||||
//==============================================================================
|
||||
void flush() override;
|
||||
int64 getPosition() override;
|
||||
bool setPosition (int64) override;
|
||||
bool write (const void*, size_t) override;
|
||||
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
File file;
|
||||
void* fileHandle = nullptr;
|
||||
Result status { Result::ok() };
|
||||
int64 currentPosition = 0;
|
||||
size_t bufferSize, bytesInBuffer = 0;
|
||||
HeapBlock<char> buffer;
|
||||
|
||||
void openHandle();
|
||||
void closeHandle();
|
||||
void flushInternal();
|
||||
bool flushBuffer();
|
||||
int64 setPositionInternal (int64);
|
||||
ssize_t writeInternal (const void*, size_t);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileOutputStream)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,173 +1,170 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
FileSearchPath::FileSearchPath() {}
|
||||
FileSearchPath::~FileSearchPath() {}
|
||||
|
||||
FileSearchPath::FileSearchPath (const String& path)
|
||||
{
|
||||
init (path);
|
||||
}
|
||||
|
||||
FileSearchPath::FileSearchPath (const FileSearchPath& other)
|
||||
: directories (other.directories)
|
||||
{
|
||||
}
|
||||
|
||||
FileSearchPath& FileSearchPath::operator= (const FileSearchPath& other)
|
||||
{
|
||||
directories = other.directories;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileSearchPath& FileSearchPath::operator= (const String& path)
|
||||
{
|
||||
init (path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void FileSearchPath::init (const String& path)
|
||||
{
|
||||
directories.clear();
|
||||
directories.addTokens (path, ";", "\"");
|
||||
directories.trim();
|
||||
directories.removeEmptyStrings();
|
||||
|
||||
for (auto& d : directories)
|
||||
d = d.unquoted();
|
||||
}
|
||||
|
||||
int FileSearchPath::getNumPaths() const
|
||||
{
|
||||
return directories.size();
|
||||
}
|
||||
|
||||
File FileSearchPath::operator[] (int index) const
|
||||
{
|
||||
return File (directories[index]);
|
||||
}
|
||||
|
||||
String FileSearchPath::toString() const
|
||||
{
|
||||
auto dirs = directories;
|
||||
|
||||
for (auto& d : dirs)
|
||||
if (d.containsChar (';'))
|
||||
d = d.quoted();
|
||||
|
||||
return dirs.joinIntoString (";");
|
||||
}
|
||||
|
||||
void FileSearchPath::add (const File& dir, int insertIndex)
|
||||
{
|
||||
directories.insert (insertIndex, dir.getFullPathName());
|
||||
}
|
||||
|
||||
bool FileSearchPath::addIfNotAlreadyThere (const File& dir)
|
||||
{
|
||||
for (auto& d : directories)
|
||||
if (File (d) == dir)
|
||||
return false;
|
||||
|
||||
add (dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSearchPath::remove (int index)
|
||||
{
|
||||
directories.remove (index);
|
||||
}
|
||||
|
||||
void FileSearchPath::addPath (const FileSearchPath& other)
|
||||
{
|
||||
for (int i = 0; i < other.getNumPaths(); ++i)
|
||||
addIfNotAlreadyThere (other[i]);
|
||||
}
|
||||
|
||||
void FileSearchPath::removeRedundantPaths()
|
||||
{
|
||||
for (int i = directories.size(); --i >= 0;)
|
||||
{
|
||||
const File d1 (directories[i]);
|
||||
|
||||
for (int j = directories.size(); --j >= 0;)
|
||||
{
|
||||
const File d2 (directories[j]);
|
||||
|
||||
if (i != j && (d1.isAChildOf (d2) || d1 == d2))
|
||||
{
|
||||
directories.remove (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSearchPath::removeNonExistentPaths()
|
||||
{
|
||||
for (int i = directories.size(); --i >= 0;)
|
||||
if (! File (directories[i]).isDirectory())
|
||||
directories.remove (i);
|
||||
}
|
||||
|
||||
Array<File> FileSearchPath::findChildFiles (int whatToLookFor, bool recurse, const String& wildcard) const
|
||||
{
|
||||
Array<File> results;
|
||||
findChildFiles (results, whatToLookFor, recurse, wildcard);
|
||||
return results;
|
||||
}
|
||||
|
||||
int FileSearchPath::findChildFiles (Array<File>& results, int whatToLookFor,
|
||||
bool recurse, const String& wildcard) const
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
for (auto& d : directories)
|
||||
total += File (d).findChildFiles (results, whatToLookFor, recurse, wildcard);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
bool FileSearchPath::isFileInPath (const File& fileToCheck,
|
||||
const bool checkRecursively) const
|
||||
{
|
||||
for (auto& d : directories)
|
||||
{
|
||||
if (checkRecursively)
|
||||
{
|
||||
if (fileToCheck.isAChildOf (File (d)))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fileToCheck.getParentDirectory() == File (d))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
FileSearchPath::FileSearchPath (const String& path)
|
||||
{
|
||||
init (path);
|
||||
}
|
||||
|
||||
FileSearchPath::FileSearchPath (const FileSearchPath& other)
|
||||
: directories (other.directories)
|
||||
{
|
||||
}
|
||||
|
||||
FileSearchPath& FileSearchPath::operator= (const FileSearchPath& other)
|
||||
{
|
||||
directories = other.directories;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileSearchPath& FileSearchPath::operator= (const String& path)
|
||||
{
|
||||
init (path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void FileSearchPath::init (const String& path)
|
||||
{
|
||||
directories.clear();
|
||||
directories.addTokens (path, ";", "\"");
|
||||
directories.trim();
|
||||
directories.removeEmptyStrings();
|
||||
|
||||
for (auto& d : directories)
|
||||
d = d.unquoted();
|
||||
}
|
||||
|
||||
int FileSearchPath::getNumPaths() const
|
||||
{
|
||||
return directories.size();
|
||||
}
|
||||
|
||||
File FileSearchPath::operator[] (int index) const
|
||||
{
|
||||
return File (directories[index]);
|
||||
}
|
||||
|
||||
String FileSearchPath::toString() const
|
||||
{
|
||||
auto dirs = directories;
|
||||
|
||||
for (auto& d : dirs)
|
||||
if (d.containsChar (';'))
|
||||
d = d.quoted();
|
||||
|
||||
return dirs.joinIntoString (";");
|
||||
}
|
||||
|
||||
void FileSearchPath::add (const File& dir, int insertIndex)
|
||||
{
|
||||
directories.insert (insertIndex, dir.getFullPathName());
|
||||
}
|
||||
|
||||
bool FileSearchPath::addIfNotAlreadyThere (const File& dir)
|
||||
{
|
||||
for (auto& d : directories)
|
||||
if (File (d) == dir)
|
||||
return false;
|
||||
|
||||
add (dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSearchPath::remove (int index)
|
||||
{
|
||||
directories.remove (index);
|
||||
}
|
||||
|
||||
void FileSearchPath::addPath (const FileSearchPath& other)
|
||||
{
|
||||
for (int i = 0; i < other.getNumPaths(); ++i)
|
||||
addIfNotAlreadyThere (other[i]);
|
||||
}
|
||||
|
||||
void FileSearchPath::removeRedundantPaths()
|
||||
{
|
||||
for (int i = directories.size(); --i >= 0;)
|
||||
{
|
||||
const File d1 (directories[i]);
|
||||
|
||||
for (int j = directories.size(); --j >= 0;)
|
||||
{
|
||||
const File d2 (directories[j]);
|
||||
|
||||
if (i != j && (d1.isAChildOf (d2) || d1 == d2))
|
||||
{
|
||||
directories.remove (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSearchPath::removeNonExistentPaths()
|
||||
{
|
||||
for (int i = directories.size(); --i >= 0;)
|
||||
if (! File (directories[i]).isDirectory())
|
||||
directories.remove (i);
|
||||
}
|
||||
|
||||
Array<File> FileSearchPath::findChildFiles (int whatToLookFor, bool recurse, const String& wildcard) const
|
||||
{
|
||||
Array<File> results;
|
||||
findChildFiles (results, whatToLookFor, recurse, wildcard);
|
||||
return results;
|
||||
}
|
||||
|
||||
int FileSearchPath::findChildFiles (Array<File>& results, int whatToLookFor,
|
||||
bool recurse, const String& wildcard) const
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
for (auto& d : directories)
|
||||
total += File (d).findChildFiles (results, whatToLookFor, recurse, wildcard);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
bool FileSearchPath::isFileInPath (const File& fileToCheck,
|
||||
const bool checkRecursively) const
|
||||
{
|
||||
for (auto& d : directories)
|
||||
{
|
||||
if (checkRecursively)
|
||||
{
|
||||
if (fileToCheck.isAChildOf (File (d)))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fileToCheck.getParentDirectory() == File (d))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,171 +1,171 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a set of folders that make up a search path.
|
||||
|
||||
@see File
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileSearchPath
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty search path. */
|
||||
FileSearchPath();
|
||||
|
||||
/** Creates a search path from a string of pathnames.
|
||||
|
||||
The path can be semicolon- or comma-separated, e.g.
|
||||
"/foo/bar;/foo/moose;/fish/moose"
|
||||
|
||||
The separate folders are tokenised and added to the search path.
|
||||
*/
|
||||
FileSearchPath (const String& path);
|
||||
|
||||
/** Creates a copy of another search path. */
|
||||
FileSearchPath (const FileSearchPath&);
|
||||
|
||||
/** Copies another search path. */
|
||||
FileSearchPath& operator= (const FileSearchPath&);
|
||||
|
||||
/** Destructor. */
|
||||
~FileSearchPath();
|
||||
|
||||
/** Uses a string containing a list of pathnames to re-initialise this list.
|
||||
|
||||
This search path is cleared and the semicolon- or comma-separated folders
|
||||
in this string are added instead. e.g. "/foo/bar;/foo/moose;/fish/moose"
|
||||
*/
|
||||
FileSearchPath& operator= (const String& path);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of folders in this search path.
|
||||
@see operator[]
|
||||
*/
|
||||
int getNumPaths() const;
|
||||
|
||||
/** Returns one of the folders in this search path.
|
||||
The file returned isn't guaranteed to actually be a valid directory.
|
||||
@see getNumPaths
|
||||
*/
|
||||
File operator[] (int index) const;
|
||||
|
||||
/** Returns the search path as a semicolon-separated list of directories. */
|
||||
String toString() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a new directory to the search path.
|
||||
|
||||
The new directory is added to the end of the list if the insertIndex parameter is
|
||||
less than zero, otherwise it is inserted at the given index.
|
||||
*/
|
||||
void add (const File& directoryToAdd,
|
||||
int insertIndex = -1);
|
||||
|
||||
/** Adds a new directory to the search path if it's not already in there.
|
||||
|
||||
@return true if the directory has been added, false otherwise.
|
||||
*/
|
||||
bool addIfNotAlreadyThere (const File& directoryToAdd);
|
||||
|
||||
/** Removes a directory from the search path. */
|
||||
void remove (int indexToRemove);
|
||||
|
||||
/** Merges another search path into this one.
|
||||
This will remove any duplicate directories.
|
||||
*/
|
||||
void addPath (const FileSearchPath&);
|
||||
|
||||
/** Removes any directories that are actually subdirectories of one of the other directories in the search path.
|
||||
|
||||
If the search is intended to be recursive, there's no point having nested folders in the search
|
||||
path, because they'll just get searched twice and you'll get duplicate results.
|
||||
|
||||
e.g. if the path is "c:\abc\de;c:\abc", this method will simplify it to "c:\abc"
|
||||
*/
|
||||
void removeRedundantPaths();
|
||||
|
||||
/** Removes any directories that don't actually exist. */
|
||||
void removeNonExistentPaths();
|
||||
|
||||
//==============================================================================
|
||||
/** Searches the path for a wildcard.
|
||||
|
||||
This will search all the directories in the search path in order and return
|
||||
an array of the files that were found.
|
||||
|
||||
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying whether to
|
||||
return files, directories, or both.
|
||||
@param searchRecursively whether to recursively search the subdirectories too
|
||||
@param wildCardPattern a pattern to match against the filenames
|
||||
@returns the number of files added to the array
|
||||
@see File::findChildFiles
|
||||
*/
|
||||
Array<File> findChildFiles (int whatToLookFor,
|
||||
bool searchRecursively,
|
||||
const String& wildCardPattern = "*") const;
|
||||
|
||||
/** Searches the path for a wildcard.
|
||||
Note that there's a newer, better version of this method which returns the results
|
||||
array, and in almost all cases, you should use that one instead! This one is kept around
|
||||
mainly for legacy code to use.
|
||||
*/
|
||||
int findChildFiles (Array<File>& results,
|
||||
int whatToLookFor,
|
||||
bool searchRecursively,
|
||||
const String& wildCardPattern = "*") const;
|
||||
|
||||
//==============================================================================
|
||||
/** Finds out whether a file is inside one of the path's directories.
|
||||
|
||||
This will return true if the specified file is a child of one of the
|
||||
directories specified by this path. Note that this doesn't actually do any
|
||||
searching or check that the files exist - it just looks at the pathnames
|
||||
to work out whether the file would be inside a directory.
|
||||
|
||||
@param fileToCheck the file to look for
|
||||
@param checkRecursively if true, then this will return true if the file is inside a
|
||||
subfolder of one of the path's directories (at any depth). If false
|
||||
it will only return true if the file is actually a direct child
|
||||
of one of the directories.
|
||||
@see File::isAChildOf
|
||||
|
||||
*/
|
||||
bool isFileInPath (const File& fileToCheck,
|
||||
bool checkRecursively) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
StringArray directories;
|
||||
|
||||
void init (const String&);
|
||||
|
||||
JUCE_LEAK_DETECTOR (FileSearchPath)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a set of folders that make up a search path.
|
||||
|
||||
@see File
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API FileSearchPath
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty search path. */
|
||||
FileSearchPath() = default;
|
||||
|
||||
/** Destructor. */
|
||||
~FileSearchPath() = default;
|
||||
|
||||
/** Creates a search path from a string of pathnames.
|
||||
|
||||
The path can be semicolon- or comma-separated, e.g.
|
||||
"/foo/bar;/foo/moose;/fish/moose"
|
||||
|
||||
The separate folders are tokenised and added to the search path.
|
||||
*/
|
||||
FileSearchPath (const String& path);
|
||||
|
||||
/** Creates a copy of another search path. */
|
||||
FileSearchPath (const FileSearchPath&);
|
||||
|
||||
/** Copies another search path. */
|
||||
FileSearchPath& operator= (const FileSearchPath&);
|
||||
|
||||
/** Uses a string containing a list of pathnames to re-initialise this list.
|
||||
|
||||
This search path is cleared and the semicolon- or comma-separated folders
|
||||
in this string are added instead. e.g. "/foo/bar;/foo/moose;/fish/moose"
|
||||
*/
|
||||
FileSearchPath& operator= (const String& path);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of folders in this search path.
|
||||
@see operator[]
|
||||
*/
|
||||
int getNumPaths() const;
|
||||
|
||||
/** Returns one of the folders in this search path.
|
||||
The file returned isn't guaranteed to actually be a valid directory.
|
||||
@see getNumPaths
|
||||
*/
|
||||
File operator[] (int index) const;
|
||||
|
||||
/** Returns the search path as a semicolon-separated list of directories. */
|
||||
String toString() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a new directory to the search path.
|
||||
|
||||
The new directory is added to the end of the list if the insertIndex parameter is
|
||||
less than zero, otherwise it is inserted at the given index.
|
||||
*/
|
||||
void add (const File& directoryToAdd,
|
||||
int insertIndex = -1);
|
||||
|
||||
/** Adds a new directory to the search path if it's not already in there.
|
||||
|
||||
@return true if the directory has been added, false otherwise.
|
||||
*/
|
||||
bool addIfNotAlreadyThere (const File& directoryToAdd);
|
||||
|
||||
/** Removes a directory from the search path. */
|
||||
void remove (int indexToRemove);
|
||||
|
||||
/** Merges another search path into this one.
|
||||
This will remove any duplicate directories.
|
||||
*/
|
||||
void addPath (const FileSearchPath&);
|
||||
|
||||
/** Removes any directories that are actually subdirectories of one of the other directories in the search path.
|
||||
|
||||
If the search is intended to be recursive, there's no point having nested folders in the search
|
||||
path, because they'll just get searched twice and you'll get duplicate results.
|
||||
|
||||
e.g. if the path is "c:\abc\de;c:\abc", this method will simplify it to "c:\abc"
|
||||
*/
|
||||
void removeRedundantPaths();
|
||||
|
||||
/** Removes any directories that don't actually exist. */
|
||||
void removeNonExistentPaths();
|
||||
|
||||
//==============================================================================
|
||||
/** Searches the path for a wildcard.
|
||||
|
||||
This will search all the directories in the search path in order and return
|
||||
an array of the files that were found.
|
||||
|
||||
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying whether to
|
||||
return files, directories, or both.
|
||||
@param searchRecursively whether to recursively search the subdirectories too
|
||||
@param wildCardPattern a pattern to match against the filenames
|
||||
@returns the number of files added to the array
|
||||
@see File::findChildFiles
|
||||
*/
|
||||
Array<File> findChildFiles (int whatToLookFor,
|
||||
bool searchRecursively,
|
||||
const String& wildCardPattern = "*") const;
|
||||
|
||||
/** Searches the path for a wildcard.
|
||||
Note that there's a newer, better version of this method which returns the results
|
||||
array, and in almost all cases, you should use that one instead! This one is kept around
|
||||
mainly for legacy code to use.
|
||||
*/
|
||||
int findChildFiles (Array<File>& results,
|
||||
int whatToLookFor,
|
||||
bool searchRecursively,
|
||||
const String& wildCardPattern = "*") const;
|
||||
|
||||
//==============================================================================
|
||||
/** Finds out whether a file is inside one of the path's directories.
|
||||
|
||||
This will return true if the specified file is a child of one of the
|
||||
directories specified by this path. Note that this doesn't actually do any
|
||||
searching or check that the files exist - it just looks at the pathnames
|
||||
to work out whether the file would be inside a directory.
|
||||
|
||||
@param fileToCheck the file to look for
|
||||
@param checkRecursively if true, then this will return true if the file is inside a
|
||||
subfolder of one of the path's directories (at any depth). If false
|
||||
it will only return true if the file is actually a direct child
|
||||
of one of the directories.
|
||||
@see File::isAChildOf
|
||||
|
||||
*/
|
||||
bool isFileInPath (const File& fileToCheck,
|
||||
bool checkRecursively) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
StringArray directories;
|
||||
|
||||
void init (const String&);
|
||||
|
||||
JUCE_LEAK_DETECTOR (FileSearchPath)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,115 +1,115 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Maps a file into virtual memory for easy reading and/or writing.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API MemoryMappedFile
|
||||
{
|
||||
public:
|
||||
/** The read/write flags used when opening a memory mapped file. */
|
||||
enum AccessMode
|
||||
{
|
||||
readOnly, /**< Indicates that the memory can only be read. */
|
||||
readWrite /**< Indicates that the memory can be read and written to - changes that are
|
||||
made will be flushed back to disk at the whim of the OS. */
|
||||
};
|
||||
|
||||
/** Opens a file and maps it to an area of virtual memory.
|
||||
|
||||
The file should already exist, and should already be the size that you want to work with
|
||||
when you call this. If the file is resized after being opened, the behaviour is undefined.
|
||||
|
||||
If the file exists and the operation succeeds, the getData() and getSize() methods will
|
||||
return the location and size of the data that can be read or written. Note that the entire
|
||||
file is not read into memory immediately - the OS simply creates a virtual mapping, which
|
||||
will lazily pull the data into memory when blocks are accessed.
|
||||
|
||||
If the file can't be opened for some reason, the getData() method will return a null pointer.
|
||||
|
||||
If exclusive is false then other apps can also open the same memory mapped file and use this
|
||||
mapping as an effective way of communicating. If exclusive is true then the mapped file will
|
||||
be opened exclusively - preventing other apps to access the file which may improve the
|
||||
performance of accessing the file.
|
||||
*/
|
||||
MemoryMappedFile (const File& file, AccessMode mode, bool exclusive = false);
|
||||
|
||||
/** Opens a section of a file and maps it to an area of virtual memory.
|
||||
|
||||
The file should already exist, and should already be the size that you want to work with
|
||||
when you call this. If the file is resized after being opened, the behaviour is undefined.
|
||||
|
||||
If the file exists and the operation succeeds, the getData() and getSize() methods will
|
||||
return the location and size of the data that can be read or written. Note that the entire
|
||||
file is not read into memory immediately - the OS simply creates a virtual mapping, which
|
||||
will lazily pull the data into memory when blocks are accessed.
|
||||
|
||||
If the file can't be opened for some reason, the getData() method will return a null pointer.
|
||||
|
||||
NOTE: The start of the actual range used may be rounded-down to a multiple of the OS's page-size,
|
||||
so do not assume that the mapped memory will begin at exactly the position you requested - always
|
||||
use getRange() to check the actual range that is being used.
|
||||
*/
|
||||
MemoryMappedFile (const File& file,
|
||||
const Range<int64>& fileRange,
|
||||
AccessMode mode,
|
||||
bool exclusive = false);
|
||||
|
||||
/** Destructor. */
|
||||
~MemoryMappedFile();
|
||||
|
||||
/** Returns the address at which this file has been mapped, or a null pointer if
|
||||
the file couldn't be successfully mapped.
|
||||
*/
|
||||
void* getData() const noexcept { return address; }
|
||||
|
||||
/** Returns the number of bytes of data that are available for reading or writing.
|
||||
This will normally be the size of the file.
|
||||
*/
|
||||
size_t getSize() const noexcept { return (size_t) range.getLength(); }
|
||||
|
||||
/** Returns the section of the file at which the mapped memory represents. */
|
||||
Range<int64> getRange() const noexcept { return range; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void* address = nullptr;
|
||||
Range<int64> range;
|
||||
|
||||
#if JUCE_WINDOWS
|
||||
void* fileHandle = nullptr;
|
||||
#else
|
||||
int fileHandle = 0;
|
||||
#endif
|
||||
|
||||
void openInternal (const File&, AccessMode, bool);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedFile)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Maps a file into virtual memory for easy reading and/or writing.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API MemoryMappedFile
|
||||
{
|
||||
public:
|
||||
/** The read/write flags used when opening a memory mapped file. */
|
||||
enum AccessMode
|
||||
{
|
||||
readOnly, /**< Indicates that the memory can only be read. */
|
||||
readWrite /**< Indicates that the memory can be read and written to - changes that are
|
||||
made will be flushed back to disk at the whim of the OS. */
|
||||
};
|
||||
|
||||
/** Opens a file and maps it to an area of virtual memory.
|
||||
|
||||
The file should already exist, and should already be the size that you want to work with
|
||||
when you call this. If the file is resized after being opened, the behaviour is undefined.
|
||||
|
||||
If the file exists and the operation succeeds, the getData() and getSize() methods will
|
||||
return the location and size of the data that can be read or written. Note that the entire
|
||||
file is not read into memory immediately - the OS simply creates a virtual mapping, which
|
||||
will lazily pull the data into memory when blocks are accessed.
|
||||
|
||||
If the file can't be opened for some reason, the getData() method will return a null pointer.
|
||||
|
||||
If exclusive is false then other apps can also open the same memory mapped file and use this
|
||||
mapping as an effective way of communicating. If exclusive is true then the mapped file will
|
||||
be opened exclusively - preventing other apps to access the file which may improve the
|
||||
performance of accessing the file.
|
||||
*/
|
||||
MemoryMappedFile (const File& file, AccessMode mode, bool exclusive = false);
|
||||
|
||||
/** Opens a section of a file and maps it to an area of virtual memory.
|
||||
|
||||
The file should already exist, and should already be the size that you want to work with
|
||||
when you call this. If the file is resized after being opened, the behaviour is undefined.
|
||||
|
||||
If the file exists and the operation succeeds, the getData() and getSize() methods will
|
||||
return the location and size of the data that can be read or written. Note that the entire
|
||||
file is not read into memory immediately - the OS simply creates a virtual mapping, which
|
||||
will lazily pull the data into memory when blocks are accessed.
|
||||
|
||||
If the file can't be opened for some reason, the getData() method will return a null pointer.
|
||||
|
||||
NOTE: The start of the actual range used may be rounded-down to a multiple of the OS's page-size,
|
||||
so do not assume that the mapped memory will begin at exactly the position you requested - always
|
||||
use getRange() to check the actual range that is being used.
|
||||
*/
|
||||
MemoryMappedFile (const File& file,
|
||||
const Range<int64>& fileRange,
|
||||
AccessMode mode,
|
||||
bool exclusive = false);
|
||||
|
||||
/** Destructor. */
|
||||
~MemoryMappedFile();
|
||||
|
||||
/** Returns the address at which this file has been mapped, or a null pointer if
|
||||
the file couldn't be successfully mapped.
|
||||
*/
|
||||
void* getData() const noexcept { return address; }
|
||||
|
||||
/** Returns the number of bytes of data that are available for reading or writing.
|
||||
This will normally be the size of the file.
|
||||
*/
|
||||
size_t getSize() const noexcept { return (size_t) range.getLength(); }
|
||||
|
||||
/** Returns the section of the file at which the mapped memory represents. */
|
||||
Range<int64> getRange() const noexcept { return range; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void* address = nullptr;
|
||||
Range<int64> range;
|
||||
|
||||
#if JUCE_WINDOWS
|
||||
void* fileHandle = nullptr;
|
||||
#else
|
||||
int fileHandle = 0;
|
||||
#endif
|
||||
|
||||
void openInternal (const File&, AccessMode, bool);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedFile)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,77 +1,79 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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)
|
||||
|
||||
float DirectoryEntry::getEstimatedProgress() const
|
||||
{
|
||||
if (auto it = iterator.lock())
|
||||
return it->getEstimatedProgress();
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// 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))
|
||||
{
|
||||
entry.iterator = iterator;
|
||||
increment();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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)
|
||||
|
||||
float DirectoryEntry::getEstimatedProgress() const
|
||||
{
|
||||
if (auto it = iterator.lock())
|
||||
return it->getEstimatedProgress();
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// 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,
|
||||
File::FollowSymlinks followSymlinks)
|
||||
: iterator (new DirectoryIterator (directory,
|
||||
isRecursive,
|
||||
wildCard,
|
||||
whatToLookFor,
|
||||
followSymlinks))
|
||||
{
|
||||
entry.iterator = iterator;
|
||||
increment();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,188 +1,190 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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)
|
||||
|
||||
/**
|
||||
Describes the attributes of a file or folder.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
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; }
|
||||
|
||||
/** The estimated proportion of the range that has been visited
|
||||
by the iterator, from 0.0 to 1.0.
|
||||
*/
|
||||
float getEstimatedProgress() const;
|
||||
|
||||
private:
|
||||
std::weak_ptr<DirectoryIterator> iterator;
|
||||
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
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
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 {}; }
|
||||
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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)
|
||||
|
||||
/**
|
||||
Describes the attributes of a file or folder.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
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; }
|
||||
|
||||
/** The estimated proportion of the range that has been visited
|
||||
by the iterator, from 0.0 to 1.0.
|
||||
*/
|
||||
float getEstimatedProgress() const;
|
||||
|
||||
private:
|
||||
std::weak_ptr<DirectoryIterator> iterator;
|
||||
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
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
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.
|
||||
@param followSymlinks the policy to use when symlinks are encountered
|
||||
*/
|
||||
RangedDirectoryIterator (const File& directory,
|
||||
bool isRecursive,
|
||||
const String& wildCard = "*",
|
||||
int whatToLookFor = File::findFiles,
|
||||
File::FollowSymlinks followSymlinks = File::FollowSymlinks::yes);
|
||||
|
||||
/** 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 {}; }
|
||||
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,117 +1,134 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
static File createTempFile (const File& parentDirectory, String name,
|
||||
const String& suffix, int optionFlags)
|
||||
{
|
||||
if ((optionFlags & TemporaryFile::useHiddenFile) != 0)
|
||||
name = "." + name;
|
||||
|
||||
return parentDirectory.getNonexistentChildFile (name, suffix, (optionFlags & TemporaryFile::putNumbersInBrackets) != 0);
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags)
|
||||
: temporaryFile (createTempFile (File::getSpecialLocation (File::tempDirectory),
|
||||
"temp_" + String::toHexString (Random::getSystemRandom().nextInt()),
|
||||
suffix, optionFlags)),
|
||||
targetFile()
|
||||
{
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile (const File& target, const int optionFlags)
|
||||
: temporaryFile (createTempFile (target.getParentDirectory(),
|
||||
target.getFileNameWithoutExtension()
|
||||
+ "_temp" + String::toHexString (Random::getSystemRandom().nextInt()),
|
||||
target.getFileExtension(), optionFlags)),
|
||||
targetFile (target)
|
||||
{
|
||||
// If you use this constructor, you need to give it a valid target file!
|
||||
jassert (targetFile != File());
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile (const File& target, const File& temporary)
|
||||
: temporaryFile (temporary), targetFile (target)
|
||||
{
|
||||
}
|
||||
|
||||
TemporaryFile::~TemporaryFile()
|
||||
{
|
||||
if (! deleteTemporaryFile())
|
||||
{
|
||||
/* Failed to delete our temporary file! The most likely reason for this would be
|
||||
that you've not closed an output stream that was being used to write to file.
|
||||
|
||||
If you find that something beyond your control is changing permissions on
|
||||
your temporary files and preventing them from being deleted, you may want to
|
||||
call TemporaryFile::deleteTemporaryFile() to detect those error cases and
|
||||
handle them appropriately.
|
||||
*/
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool TemporaryFile::overwriteTargetFileWithTemporary() const
|
||||
{
|
||||
// This method only works if you created this object with the constructor
|
||||
// that takes a target file!
|
||||
jassert (targetFile != File());
|
||||
|
||||
if (temporaryFile.exists())
|
||||
{
|
||||
// Have a few attempts at overwriting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (temporaryFile.replaceFileIn (targetFile))
|
||||
return true;
|
||||
|
||||
Thread::sleep (100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// There's no temporary file to use. If your write failed, you should
|
||||
// probably check, and not bother calling this method.
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TemporaryFile::deleteTemporaryFile() const
|
||||
{
|
||||
// Have a few attempts at deleting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (temporaryFile.deleteFile())
|
||||
return true;
|
||||
|
||||
Thread::sleep (50);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
// Using Random::getSystemRandom() can be a bit dangerous in multithreaded contexts!
|
||||
class LockedRandom
|
||||
{
|
||||
public:
|
||||
int nextInt()
|
||||
{
|
||||
const ScopedLock lock (mutex);
|
||||
return random.nextInt();
|
||||
}
|
||||
|
||||
private:
|
||||
CriticalSection mutex;
|
||||
Random random;
|
||||
};
|
||||
|
||||
static LockedRandom lockedRandom;
|
||||
|
||||
static File createTempFile (const File& parentDirectory, String name,
|
||||
const String& suffix, int optionFlags)
|
||||
{
|
||||
if ((optionFlags & TemporaryFile::useHiddenFile) != 0)
|
||||
name = "." + name;
|
||||
|
||||
return parentDirectory.getNonexistentChildFile (name, suffix, (optionFlags & TemporaryFile::putNumbersInBrackets) != 0);
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags)
|
||||
: temporaryFile (createTempFile (File::getSpecialLocation (File::tempDirectory),
|
||||
"temp_" + String::toHexString (lockedRandom.nextInt()),
|
||||
suffix, optionFlags)),
|
||||
targetFile()
|
||||
{
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile (const File& target, const int optionFlags)
|
||||
: temporaryFile (createTempFile (target.getParentDirectory(),
|
||||
target.getFileNameWithoutExtension()
|
||||
+ "_temp" + String::toHexString (lockedRandom.nextInt()),
|
||||
target.getFileExtension(), optionFlags)),
|
||||
targetFile (target)
|
||||
{
|
||||
// If you use this constructor, you need to give it a valid target file!
|
||||
jassert (targetFile != File());
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile (const File& target, const File& temporary)
|
||||
: temporaryFile (temporary), targetFile (target)
|
||||
{
|
||||
}
|
||||
|
||||
TemporaryFile::~TemporaryFile()
|
||||
{
|
||||
if (! deleteTemporaryFile())
|
||||
{
|
||||
/* Failed to delete our temporary file! The most likely reason for this would be
|
||||
that you've not closed an output stream that was being used to write to file.
|
||||
|
||||
If you find that something beyond your control is changing permissions on
|
||||
your temporary files and preventing them from being deleted, you may want to
|
||||
call TemporaryFile::deleteTemporaryFile() to detect those error cases and
|
||||
handle them appropriately.
|
||||
*/
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool TemporaryFile::overwriteTargetFileWithTemporary() const
|
||||
{
|
||||
// This method only works if you created this object with the constructor
|
||||
// that takes a target file!
|
||||
jassert (targetFile != File());
|
||||
|
||||
if (temporaryFile.exists())
|
||||
{
|
||||
// Have a few attempts at overwriting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (temporaryFile.replaceFileIn (targetFile))
|
||||
return true;
|
||||
|
||||
Thread::sleep (100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// There's no temporary file to use. If your write failed, you should
|
||||
// probably check, and not bother calling this method.
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TemporaryFile::deleteTemporaryFile() const
|
||||
{
|
||||
// Have a few attempts at deleting the file before giving up..
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (temporaryFile.isDirectory() ? temporaryFile.deleteRecursively() : temporaryFile.deleteFile())
|
||||
return true;
|
||||
|
||||
Thread::sleep (50);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,162 +1,162 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Manages a temporary file, which will be deleted when this object is deleted.
|
||||
|
||||
This object is intended to be used as a stack based object, using its scope
|
||||
to make sure the temporary file isn't left lying around.
|
||||
|
||||
For example:
|
||||
|
||||
@code
|
||||
{
|
||||
File myTargetFile ("~/myfile.txt");
|
||||
|
||||
// this will choose a file called something like "~/myfile_temp239348.txt"
|
||||
// which definitely doesn't exist at the time the constructor is called.
|
||||
TemporaryFile temp (myTargetFile);
|
||||
|
||||
// create a stream to the temporary file, and write some data to it...
|
||||
if (auto out = std::unique_ptr<FileOutputStream> (temp.getFile().createOutputStream()))
|
||||
{
|
||||
out->write ( ...etc )
|
||||
out.reset(); // (deletes the stream)
|
||||
|
||||
// ..now we've finished writing, this will rename the temp file to
|
||||
// make it replace the target file we specified above.
|
||||
bool succeeded = temp.overwriteTargetFileWithTemporary();
|
||||
}
|
||||
|
||||
// ..and even if something went wrong and our overwrite failed,
|
||||
// as the TemporaryFile object goes out of scope here, it'll make sure
|
||||
// that the temp file gets deleted.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see File, FileOutputStream
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API TemporaryFile
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
enum OptionFlags
|
||||
{
|
||||
useHiddenFile = 1, /**< Indicates that the temporary file should be hidden -
|
||||
i.e. its name should start with a dot. */
|
||||
putNumbersInBrackets = 2 /**< Indicates that when numbers are appended to make sure
|
||||
the file is unique, they should go in brackets rather
|
||||
than just being appended (see File::getNonexistentSibling() )*/
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a randomly-named temporary file in the default temp directory.
|
||||
|
||||
@param suffix a file suffix to use for the file
|
||||
@param optionFlags a combination of the values listed in the OptionFlags enum
|
||||
The file will not be created until you write to it. And remember that when
|
||||
this object is deleted, the file will also be deleted!
|
||||
*/
|
||||
TemporaryFile (const String& suffix = String(),
|
||||
int optionFlags = 0);
|
||||
|
||||
/** Creates a temporary file in the same directory as a specified file.
|
||||
|
||||
This is useful if you have a file that you want to overwrite, but don't
|
||||
want to harm the original file if the write operation fails. You can
|
||||
use this to create a temporary file next to the target file, then
|
||||
write to the temporary file, and finally use overwriteTargetFileWithTemporary()
|
||||
to replace the target file with the one you've just written.
|
||||
|
||||
This class won't create any files until you actually write to them. And remember
|
||||
that when this object is deleted, the temporary file will also be deleted!
|
||||
|
||||
@param targetFile the file that you intend to overwrite - the temporary
|
||||
file will be created in the same directory as this
|
||||
@param optionFlags a combination of the values listed in the OptionFlags enum
|
||||
*/
|
||||
TemporaryFile (const File& targetFile,
|
||||
int optionFlags = 0);
|
||||
|
||||
/** Creates a temporary file using an explicit filename.
|
||||
The other constructors are a better choice than this one, unless for some reason
|
||||
you need to explicitly specify the temporary file you want to use.
|
||||
|
||||
@param targetFile the file that you intend to overwrite
|
||||
@param temporaryFile the temporary file to be used
|
||||
*/
|
||||
TemporaryFile (const File& targetFile,
|
||||
const File& temporaryFile);
|
||||
|
||||
/** Destructor.
|
||||
|
||||
When this object is deleted it will make sure that its temporary file is
|
||||
also deleted! If the operation fails, it'll throw an assertion in debug
|
||||
mode.
|
||||
*/
|
||||
~TemporaryFile();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the temporary file. */
|
||||
const File& getFile() const noexcept { return temporaryFile; }
|
||||
|
||||
/** Returns the target file that was specified in the constructor. */
|
||||
const File& getTargetFile() const noexcept { return targetFile; }
|
||||
|
||||
/** Tries to move the temporary file to overwrite the target file that was
|
||||
specified in the constructor.
|
||||
|
||||
If you used the constructor that specified a target file, this will attempt
|
||||
to replace that file with the temporary one.
|
||||
|
||||
Before calling this, make sure:
|
||||
- that you've actually written to the temporary file
|
||||
- that you've closed any open streams that you were using to write to it
|
||||
- and that you don't have any streams open to the target file, which would
|
||||
prevent it being overwritten
|
||||
|
||||
If the file move succeeds, this returns true, and the temporary file will
|
||||
have disappeared. If it fails, the temporary file will probably still exist,
|
||||
but will be deleted when this object is destroyed.
|
||||
*/
|
||||
bool overwriteTargetFileWithTemporary() const;
|
||||
|
||||
/** Attempts to delete the temporary file, if it exists.
|
||||
@returns true if the file is successfully deleted (or if it didn't exist).
|
||||
*/
|
||||
bool deleteTemporaryFile() const;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
const File temporaryFile, targetFile;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemporaryFile)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Manages a temporary file, which will be deleted when this object is deleted.
|
||||
|
||||
This object is intended to be used as a stack based object, using its scope
|
||||
to make sure the temporary file isn't left lying around.
|
||||
|
||||
For example:
|
||||
|
||||
@code
|
||||
{
|
||||
File myTargetFile ("~/myfile.txt");
|
||||
|
||||
// this will choose a file called something like "~/myfile_temp239348.txt"
|
||||
// which definitely doesn't exist at the time the constructor is called.
|
||||
TemporaryFile temp (myTargetFile);
|
||||
|
||||
// create a stream to the temporary file, and write some data to it...
|
||||
if (auto out = std::unique_ptr<FileOutputStream> (temp.getFile().createOutputStream()))
|
||||
{
|
||||
out->write ( ...etc )
|
||||
out.reset(); // (deletes the stream)
|
||||
|
||||
// ..now we've finished writing, this will rename the temp file to
|
||||
// make it replace the target file we specified above.
|
||||
bool succeeded = temp.overwriteTargetFileWithTemporary();
|
||||
}
|
||||
|
||||
// ..and even if something went wrong and our overwrite failed,
|
||||
// as the TemporaryFile object goes out of scope here, it'll make sure
|
||||
// that the temp file gets deleted.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see File, FileOutputStream
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API TemporaryFile
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
enum OptionFlags
|
||||
{
|
||||
useHiddenFile = 1, /**< Indicates that the temporary file should be hidden -
|
||||
i.e. its name should start with a dot. */
|
||||
putNumbersInBrackets = 2 /**< Indicates that when numbers are appended to make sure
|
||||
the file is unique, they should go in brackets rather
|
||||
than just being appended (see File::getNonexistentSibling() )*/
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a randomly-named temporary file in the default temp directory.
|
||||
|
||||
@param suffix a file suffix to use for the file
|
||||
@param optionFlags a combination of the values listed in the OptionFlags enum
|
||||
The file will not be created until you write to it. And remember that when
|
||||
this object is deleted, the file will also be deleted!
|
||||
*/
|
||||
TemporaryFile (const String& suffix = String(),
|
||||
int optionFlags = 0);
|
||||
|
||||
/** Creates a temporary file in the same directory as a specified file.
|
||||
|
||||
This is useful if you have a file that you want to overwrite, but don't
|
||||
want to harm the original file if the write operation fails. You can
|
||||
use this to create a temporary file next to the target file, then
|
||||
write to the temporary file, and finally use overwriteTargetFileWithTemporary()
|
||||
to replace the target file with the one you've just written.
|
||||
|
||||
This class won't create any files until you actually write to them. And remember
|
||||
that when this object is deleted, the temporary file will also be deleted!
|
||||
|
||||
@param targetFile the file that you intend to overwrite - the temporary
|
||||
file will be created in the same directory as this
|
||||
@param optionFlags a combination of the values listed in the OptionFlags enum
|
||||
*/
|
||||
TemporaryFile (const File& targetFile,
|
||||
int optionFlags = 0);
|
||||
|
||||
/** Creates a temporary file using an explicit filename.
|
||||
The other constructors are a better choice than this one, unless for some reason
|
||||
you need to explicitly specify the temporary file you want to use.
|
||||
|
||||
@param targetFile the file that you intend to overwrite
|
||||
@param temporaryFile the temporary file to be used
|
||||
*/
|
||||
TemporaryFile (const File& targetFile,
|
||||
const File& temporaryFile);
|
||||
|
||||
/** Destructor.
|
||||
|
||||
When this object is deleted it will make sure that its temporary file is
|
||||
also deleted! If the operation fails, it'll throw an assertion in debug
|
||||
mode.
|
||||
*/
|
||||
~TemporaryFile();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the temporary file. */
|
||||
const File& getFile() const noexcept { return temporaryFile; }
|
||||
|
||||
/** Returns the target file that was specified in the constructor. */
|
||||
const File& getTargetFile() const noexcept { return targetFile; }
|
||||
|
||||
/** Tries to move the temporary file to overwrite the target file that was
|
||||
specified in the constructor.
|
||||
|
||||
If you used the constructor that specified a target file, this will attempt
|
||||
to replace that file with the temporary one.
|
||||
|
||||
Before calling this, make sure:
|
||||
- that you've actually written to the temporary file
|
||||
- that you've closed any open streams that you were using to write to it
|
||||
- and that you don't have any streams open to the target file, which would
|
||||
prevent it being overwritten
|
||||
|
||||
If the file move succeeds, this returns true, and the temporary file will
|
||||
have disappeared. If it fails, the temporary file will probably still exist,
|
||||
but will be deleted when this object is destroyed.
|
||||
*/
|
||||
bool overwriteTargetFileWithTemporary() const;
|
||||
|
||||
/** Attempts to delete the temporary file, if it exists.
|
||||
@returns true if the file is successfully deleted (or if it didn't exist).
|
||||
*/
|
||||
bool deleteTemporaryFile() const;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
const File temporaryFile, targetFile;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemporaryFile)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,74 +1,74 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
static void parseWildcard (const String& pattern, StringArray& result)
|
||||
{
|
||||
result.addTokens (pattern.toLowerCase(), ";,", "\"'");
|
||||
result.trim();
|
||||
result.removeEmptyStrings();
|
||||
|
||||
// special case for *.*, because people use it to mean "any file", but it
|
||||
// would actually ignore files with no extension.
|
||||
for (auto& r : result)
|
||||
if (r == "*.*")
|
||||
r = "*";
|
||||
}
|
||||
|
||||
static bool matchWildcard (const File& file, const StringArray& wildcards)
|
||||
{
|
||||
auto filename = file.getFileName();
|
||||
|
||||
for (auto& w : wildcards)
|
||||
if (filename.matchesWildcard (w, true))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
WildcardFileFilter::WildcardFileFilter (const String& fileWildcardPatterns,
|
||||
const String& directoryWildcardPatterns,
|
||||
const String& desc)
|
||||
: FileFilter (desc.isEmpty() ? fileWildcardPatterns
|
||||
: (desc + " (" + fileWildcardPatterns + ")"))
|
||||
{
|
||||
parseWildcard (fileWildcardPatterns, fileWildcards);
|
||||
parseWildcard (directoryWildcardPatterns, directoryWildcards);
|
||||
}
|
||||
|
||||
WildcardFileFilter::~WildcardFileFilter()
|
||||
{
|
||||
}
|
||||
|
||||
bool WildcardFileFilter::isFileSuitable (const File& file) const
|
||||
{
|
||||
return matchWildcard (file, fileWildcards);
|
||||
}
|
||||
|
||||
bool WildcardFileFilter::isDirectorySuitable (const File& file) const
|
||||
{
|
||||
return matchWildcard (file, directoryWildcards);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
static void parseWildcard (const String& pattern, StringArray& result)
|
||||
{
|
||||
result.addTokens (pattern.toLowerCase(), ";,", "\"'");
|
||||
result.trim();
|
||||
result.removeEmptyStrings();
|
||||
|
||||
// special case for *.*, because people use it to mean "any file", but it
|
||||
// would actually ignore files with no extension.
|
||||
for (auto& r : result)
|
||||
if (r == "*.*")
|
||||
r = "*";
|
||||
}
|
||||
|
||||
static bool matchWildcard (const File& file, const StringArray& wildcards)
|
||||
{
|
||||
auto filename = file.getFileName();
|
||||
|
||||
for (auto& w : wildcards)
|
||||
if (filename.matchesWildcard (w, true))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
WildcardFileFilter::WildcardFileFilter (const String& fileWildcardPatterns,
|
||||
const String& directoryWildcardPatterns,
|
||||
const String& desc)
|
||||
: FileFilter (desc.isEmpty() ? fileWildcardPatterns
|
||||
: (desc + " (" + fileWildcardPatterns + ")"))
|
||||
{
|
||||
parseWildcard (fileWildcardPatterns, fileWildcards);
|
||||
parseWildcard (directoryWildcardPatterns, directoryWildcards);
|
||||
}
|
||||
|
||||
WildcardFileFilter::~WildcardFileFilter()
|
||||
{
|
||||
}
|
||||
|
||||
bool WildcardFileFilter::isFileSuitable (const File& file) const
|
||||
{
|
||||
return matchWildcard (file, fileWildcards);
|
||||
}
|
||||
|
||||
bool WildcardFileFilter::isDirectorySuitable (const File& file) const
|
||||
{
|
||||
return matchWildcard (file, directoryWildcards);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,76 +1,76 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A type of FileFilter that works by wildcard pattern matching.
|
||||
|
||||
This filter only allows files that match one of the specified patterns, but
|
||||
allows all directories through.
|
||||
|
||||
@see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API WildcardFileFilter : public FileFilter
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates a wildcard filter for one or more patterns.
|
||||
|
||||
The wildcardPatterns parameter is a comma or semicolon-delimited set of
|
||||
patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav
|
||||
or .aiff.
|
||||
|
||||
Passing an empty string as a pattern will fail to match anything, so by leaving
|
||||
either the file or directory pattern parameter empty means you can control
|
||||
whether files or directories are found.
|
||||
|
||||
The description is a name to show the user in a list of possible patterns, so
|
||||
for the wav/aiff example, your description might be "audio files".
|
||||
*/
|
||||
WildcardFileFilter (const String& fileWildcardPatterns,
|
||||
const String& directoryWildcardPatterns,
|
||||
const String& filterDescription);
|
||||
|
||||
/** Destructor. */
|
||||
~WildcardFileFilter() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the filename matches one of the patterns specified. */
|
||||
bool isFileSuitable (const File& file) const override;
|
||||
|
||||
/** This always returns true. */
|
||||
bool isDirectorySuitable (const File& file) const override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
StringArray fileWildcards, directoryWildcards;
|
||||
|
||||
JUCE_LEAK_DETECTOR (WildcardFileFilter)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A type of FileFilter that works by wildcard pattern matching.
|
||||
|
||||
This filter only allows files that match one of the specified patterns, but
|
||||
allows all directories through.
|
||||
|
||||
@see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API WildcardFileFilter : public FileFilter
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates a wildcard filter for one or more patterns.
|
||||
|
||||
The wildcardPatterns parameter is a comma or semicolon-delimited set of
|
||||
patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav
|
||||
or .aiff.
|
||||
|
||||
Passing an empty string as a pattern will fail to match anything, so by leaving
|
||||
either the file or directory pattern parameter empty means you can control
|
||||
whether files or directories are found.
|
||||
|
||||
The description is a name to show the user in a list of possible patterns, so
|
||||
for the wav/aiff example, your description might be "audio files".
|
||||
*/
|
||||
WildcardFileFilter (const String& fileWildcardPatterns,
|
||||
const String& directoryWildcardPatterns,
|
||||
const String& filterDescription);
|
||||
|
||||
/** Destructor. */
|
||||
~WildcardFileFilter() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the filename matches one of the patterns specified. */
|
||||
bool isFileSuitable (const File& file) const override;
|
||||
|
||||
/** This always returns true. */
|
||||
bool isDirectorySuitable (const File& file) const override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
StringArray fileWildcards, directoryWildcards;
|
||||
|
||||
JUCE_LEAK_DETECTOR (WildcardFileFilter)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
710
deps/juce/modules/juce_core/files/juce_common_MimeTypes.cpp
vendored
Normal file
710
deps/juce/modules/juce_core/files/juce_common_MimeTypes.cpp
vendored
Normal file
@ -0,0 +1,710 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
struct MimeTypeTableEntry
|
||||
{
|
||||
const char* fileExtension, *mimeType;
|
||||
|
||||
static MimeTypeTableEntry table[641];
|
||||
};
|
||||
|
||||
static StringArray getMatches (const String& toMatch,
|
||||
const char* MimeTypeTableEntry::* matchField,
|
||||
const char* MimeTypeTableEntry::* returnField)
|
||||
{
|
||||
StringArray result;
|
||||
|
||||
for (auto type : MimeTypeTableEntry::table)
|
||||
if (toMatch == type.*matchField)
|
||||
result.add (type.*returnField);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace MimeTypeTable
|
||||
{
|
||||
|
||||
StringArray getMimeTypesForFileExtension (const String& fileExtension)
|
||||
{
|
||||
return getMatches (fileExtension, &MimeTypeTableEntry::fileExtension, &MimeTypeTableEntry::mimeType);
|
||||
}
|
||||
|
||||
StringArray getFileExtensionsForMimeType (const String& mimeType)
|
||||
{
|
||||
return getMatches (mimeType, &MimeTypeTableEntry::mimeType, &MimeTypeTableEntry::fileExtension);
|
||||
}
|
||||
|
||||
} // namespace MimeTypeTable
|
||||
|
||||
//==============================================================================
|
||||
MimeTypeTableEntry MimeTypeTableEntry::table[641] =
|
||||
{
|
||||
{"3dm", "x-world/x-3dmf"},
|
||||
{"3dmf", "x-world/x-3dmf"},
|
||||
{"a", "application/octet-stream"},
|
||||
{"aab", "application/x-authorware-bin"},
|
||||
{"aam", "application/x-authorware-map"},
|
||||
{"aas", "application/x-authorware-seg"},
|
||||
{"abc", "text/vnd.abc"},
|
||||
{"acgi", "text/html"},
|
||||
{"afl", "video/animaflex"},
|
||||
{"ai", "application/postscript"},
|
||||
{"aif", "audio/aiff"},
|
||||
{"aif", "audio/x-aiff"},
|
||||
{"aifc", "audio/aiff"},
|
||||
{"aifc", "audio/x-aiff"},
|
||||
{"aiff", "audio/aiff"},
|
||||
{"aiff", "audio/x-aiff"},
|
||||
{"aim", "application/x-aim"},
|
||||
{"aip", "text/x-audiosoft-intra"},
|
||||
{"ani", "application/x-navi-animation"},
|
||||
{"aos", "application/x-nokia-9000-communicator-add-on-software"},
|
||||
{"aps", "application/mime"},
|
||||
{"arc", "application/octet-stream"},
|
||||
{"arj", "application/arj"},
|
||||
{"arj", "application/octet-stream"},
|
||||
{"art", "image/x-jg"},
|
||||
{"asf", "video/x-ms-asf"},
|
||||
{"asm", "text/x-asm"},
|
||||
{"asp", "text/asp"},
|
||||
{"asx", "application/x-mplayer2"},
|
||||
{"asx", "video/x-ms-asf"},
|
||||
{"asx", "video/x-ms-asf-plugin"},
|
||||
{"au", "audio/basic"},
|
||||
{"au", "audio/x-au"},
|
||||
{"avi", "application/x-troff-msvideo"},
|
||||
{"avi", "video/avi"},
|
||||
{"avi", "video/msvideo"},
|
||||
{"avi", "video/x-msvideo"},
|
||||
{"avs", "video/avs-video"},
|
||||
{"bcpio", "application/x-bcpio"},
|
||||
{"bin", "application/mac-binary"},
|
||||
{"bin", "application/macbinary"},
|
||||
{"bin", "application/octet-stream"},
|
||||
{"bin", "application/x-binary"},
|
||||
{"bin", "application/x-macbinary"},
|
||||
{"bm", "image/bmp"},
|
||||
{"bmp", "image/bmp"},
|
||||
{"bmp", "image/x-windows-bmp"},
|
||||
{"boo", "application/book"},
|
||||
{"book", "application/book"},
|
||||
{"boz", "application/x-bzip2"},
|
||||
{"bsh", "application/x-bsh"},
|
||||
{"bz", "application/x-bzip"},
|
||||
{"bz2", "application/x-bzip2"},
|
||||
{"c", "text/plain"},
|
||||
{"c", "text/x-c"},
|
||||
{"c++", "text/plain"},
|
||||
{"cat", "application/vnd.ms-pki.seccat"},
|
||||
{"cc", "text/plain"},
|
||||
{"cc", "text/x-c"},
|
||||
{"ccad", "application/clariscad"},
|
||||
{"cco", "application/x-cocoa"},
|
||||
{"cdf", "application/cdf"},
|
||||
{"cdf", "application/x-cdf"},
|
||||
{"cdf", "application/x-netcdf"},
|
||||
{"cer", "application/pkix-cert"},
|
||||
{"cer", "application/x-x509-ca-cert"},
|
||||
{"cha", "application/x-chat"},
|
||||
{"chat", "application/x-chat"},
|
||||
{"class", "application/java"},
|
||||
{"class", "application/java-byte-code"},
|
||||
{"class", "application/x-java-class"},
|
||||
{"com", "application/octet-stream"},
|
||||
{"com", "text/plain"},
|
||||
{"conf", "text/plain"},
|
||||
{"cpio", "application/x-cpio"},
|
||||
{"cpp", "text/x-c"},
|
||||
{"cpt", "application/mac-compactpro"},
|
||||
{"cpt", "application/x-compactpro"},
|
||||
{"cpt", "application/x-cpt"},
|
||||
{"crl", "application/pkcs-crl"},
|
||||
{"crl", "application/pkix-crl"},
|
||||
{"crt", "application/pkix-cert"},
|
||||
{"crt", "application/x-x509-ca-cert"},
|
||||
{"crt", "application/x-x509-user-cert"},
|
||||
{"csh", "application/x-csh"},
|
||||
{"csh", "text/x-script.csh"},
|
||||
{"css", "application/x-pointplus"},
|
||||
{"css", "text/css"},
|
||||
{"cxx", "text/plain"},
|
||||
{"dcr", "application/x-director"},
|
||||
{"deepv", "application/x-deepv"},
|
||||
{"def", "text/plain"},
|
||||
{"der", "application/x-x509-ca-cert"},
|
||||
{"dif", "video/x-dv"},
|
||||
{"dir", "application/x-director"},
|
||||
{"dl", "video/dl"},
|
||||
{"dl", "video/x-dl"},
|
||||
{"doc", "application/msword"},
|
||||
{"dot", "application/msword"},
|
||||
{"dp", "application/commonground"},
|
||||
{"drw", "application/drafting"},
|
||||
{"dump", "application/octet-stream"},
|
||||
{"dv", "video/x-dv"},
|
||||
{"dvi", "application/x-dvi"},
|
||||
{"dwf", "drawing/x-dwf"},
|
||||
{"dwf", "model/vnd.dwf"},
|
||||
{"dwg", "application/acad"},
|
||||
{"dwg", "image/vnd.dwg"},
|
||||
{"dwg", "image/x-dwg"},
|
||||
{"dxf", "application/dxf"},
|
||||
{"dxf", "image/vnd.dwg"},
|
||||
{"dxf", "image/x-dwg"},
|
||||
{"dxr", "application/x-director"},
|
||||
{"el", "text/x-script.elisp"},
|
||||
{"elc", "application/x-bytecode.elisp"},
|
||||
{"elc", "application/x-elc"},
|
||||
{"env", "application/x-envoy"},
|
||||
{"eps", "application/postscript"},
|
||||
{"es", "application/x-esrehber"},
|
||||
{"etx", "text/x-setext"},
|
||||
{"evy", "application/envoy"},
|
||||
{"evy", "application/x-envoy"},
|
||||
{"exe", "application/octet-stream"},
|
||||
{"f", "text/plain"},
|
||||
{"f", "text/x-fortran"},
|
||||
{"f77", "text/x-fortran"},
|
||||
{"f90", "text/plain"},
|
||||
{"f90", "text/x-fortran"},
|
||||
{"fdf", "application/vnd.fdf"},
|
||||
{"fif", "application/fractals"},
|
||||
{"fif", "image/fif"},
|
||||
{"fli", "video/fli"},
|
||||
{"fli", "video/x-fli"},
|
||||
{"flo", "image/florian"},
|
||||
{"flx", "text/vnd.fmi.flexstor"},
|
||||
{"fmf", "video/x-atomic3d-feature"},
|
||||
{"for", "text/plain"},
|
||||
{"for", "text/x-fortran"},
|
||||
{"fpx", "image/vnd.fpx"},
|
||||
{"fpx", "image/vnd.net-fpx"},
|
||||
{"frl", "application/freeloader"},
|
||||
{"funk", "audio/make"},
|
||||
{"g", "text/plain"},
|
||||
{"g3", "image/g3fax"},
|
||||
{"gif", "image/gif"},
|
||||
{"gl", "video/gl"},
|
||||
{"gl", "video/x-gl"},
|
||||
{"gsd", "audio/x-gsm"},
|
||||
{"gsm", "audio/x-gsm"},
|
||||
{"gsp", "application/x-gsp"},
|
||||
{"gss", "application/x-gss"},
|
||||
{"gtar", "application/x-gtar"},
|
||||
{"gz", "application/x-compressed"},
|
||||
{"gz", "application/x-gzip"},
|
||||
{"gzip", "application/x-gzip"},
|
||||
{"gzip", "multipart/x-gzip"},
|
||||
{"h", "text/plain"},
|
||||
{"h", "text/x-h"},
|
||||
{"hdf", "application/x-hdf"},
|
||||
{"help", "application/x-helpfile"},
|
||||
{"hgl", "application/vnd.hp-hpgl"},
|
||||
{"hh", "text/plain"},
|
||||
{"hh", "text/x-h"},
|
||||
{"hlb", "text/x-script"},
|
||||
{"hlp", "application/hlp"},
|
||||
{"hlp", "application/x-helpfile"},
|
||||
{"hlp", "application/x-winhelp"},
|
||||
{"hpg", "application/vnd.hp-hpgl"},
|
||||
{"hpgl", "application/vnd.hp-hpgl"},
|
||||
{"hqx", "application/binhex"},
|
||||
{"hqx", "application/binhex4"},
|
||||
{"hqx", "application/mac-binhex"},
|
||||
{"hqx", "application/mac-binhex40"},
|
||||
{"hqx", "application/x-binhex40"},
|
||||
{"hqx", "application/x-mac-binhex40"},
|
||||
{"hta", "application/hta"},
|
||||
{"htc", "text/x-component"},
|
||||
{"htm", "text/html"},
|
||||
{"html", "text/html"},
|
||||
{"htmls", "text/html"},
|
||||
{"htt", "text/webviewhtml"},
|
||||
{"htx", "text/html"},
|
||||
{"ice", "x-conference/x-cooltalk"},
|
||||
{"ico", "image/x-icon"},
|
||||
{"idc", "text/plain"},
|
||||
{"ief", "image/ief"},
|
||||
{"iefs", "image/ief"},
|
||||
{"iges", "application/iges"},
|
||||
{"iges", "model/iges"},
|
||||
{"igs", "application/iges"},
|
||||
{"igs", "model/iges"},
|
||||
{"ima", "application/x-ima"},
|
||||
{"imap", "application/x-httpd-imap"},
|
||||
{"inf", "application/inf"},
|
||||
{"ins", "application/x-internett-signup"},
|
||||
{"ip", "application/x-ip2"},
|
||||
{"isu", "video/x-isvideo"},
|
||||
{"it", "audio/it"},
|
||||
{"iv", "application/x-inventor"},
|
||||
{"ivr", "i-world/i-vrml"},
|
||||
{"ivy", "application/x-livescreen"},
|
||||
{"jam", "audio/x-jam"},
|
||||
{"jav", "text/plain"},
|
||||
{"jav", "text/x-java-source"},
|
||||
{"java", "text/plain"},
|
||||
{"java", "text/x-java-source"},
|
||||
{"jcm", "application/x-java-commerce"},
|
||||
{"jfif", "image/jpeg"},
|
||||
{"jfif", "image/pjpeg"},
|
||||
{"jpe", "image/jpeg"},
|
||||
{"jpe", "image/pjpeg"},
|
||||
{"jpeg", "image/jpeg"},
|
||||
{"jpeg", "image/pjpeg"},
|
||||
{"jpg", "image/jpeg"},
|
||||
{"jpg", "image/pjpeg"},
|
||||
{"jps", "image/x-jps"},
|
||||
{"js", "application/x-javascript"},
|
||||
{"jut", "image/jutvision"},
|
||||
{"kar", "audio/midi"},
|
||||
{"kar", "music/x-karaoke"},
|
||||
{"ksh", "application/x-ksh"},
|
||||
{"ksh", "text/x-script.ksh"},
|
||||
{"la", "audio/nspaudio"},
|
||||
{"la", "audio/x-nspaudio"},
|
||||
{"lam", "audio/x-liveaudio"},
|
||||
{"latex", "application/x-latex"},
|
||||
{"lha", "application/lha"},
|
||||
{"lha", "application/octet-stream"},
|
||||
{"lha", "application/x-lha"},
|
||||
{"lhx", "application/octet-stream"},
|
||||
{"list", "text/plain"},
|
||||
{"lma", "audio/nspaudio"},
|
||||
{"lma", "audio/x-nspaudio"},
|
||||
{"log", "text/plain"},
|
||||
{"lsp", "application/x-lisp"},
|
||||
{"lsp", "text/x-script.lisp"},
|
||||
{"lst", "text/plain"},
|
||||
{"lsx", "text/x-la-asf"},
|
||||
{"ltx", "application/x-latex"},
|
||||
{"lzh", "application/octet-stream"},
|
||||
{"lzh", "application/x-lzh"},
|
||||
{"lzx", "application/lzx"},
|
||||
{"lzx", "application/octet-stream"},
|
||||
{"lzx", "application/x-lzx"},
|
||||
{"m", "text/plain"},
|
||||
{"m", "text/x-m"},
|
||||
{"m1v", "video/mpeg"},
|
||||
{"m2a", "audio/mpeg"},
|
||||
{"m2v", "video/mpeg"},
|
||||
{"m3u", "audio/x-mpequrl"},
|
||||
{"man", "application/x-troff-man"},
|
||||
{"map", "application/x-navimap"},
|
||||
{"mar", "text/plain"},
|
||||
{"mbd", "application/mbedlet"},
|
||||
{"mc$", "application/x-magic-cap-package-1.0"},
|
||||
{"mcd", "application/mcad"},
|
||||
{"mcd", "application/x-mathcad"},
|
||||
{"mcf", "image/vasa"},
|
||||
{"mcf", "text/mcf"},
|
||||
{"mcp", "application/netmc"},
|
||||
{"me", "application/x-troff-me"},
|
||||
{"mht", "message/rfc822"},
|
||||
{"mhtml", "message/rfc822"},
|
||||
{"mid", "application/x-midi"},
|
||||
{"mid", "audio/midi"},
|
||||
{"mid", "audio/x-mid"},
|
||||
{"mid", "audio/x-midi"},
|
||||
{"mid", "music/crescendo"},
|
||||
{"mid", "x-music/x-midi"},
|
||||
{"midi", "application/x-midi"},
|
||||
{"midi", "audio/midi"},
|
||||
{"midi", "audio/x-mid"},
|
||||
{"midi", "audio/x-midi"},
|
||||
{"midi", "music/crescendo"},
|
||||
{"midi", "x-music/x-midi"},
|
||||
{"mif", "application/x-frame"},
|
||||
{"mif", "application/x-mif"},
|
||||
{"mime", "message/rfc822"},
|
||||
{"mime", "www/mime"},
|
||||
{"mjf", "audio/x-vnd.audioexplosion.mjuicemediafile"},
|
||||
{"mjpg", "video/x-motion-jpeg"},
|
||||
{"mm", "application/base64"},
|
||||
{"mm", "application/x-meme"},
|
||||
{"mme", "application/base64"},
|
||||
{"mod", "audio/mod"},
|
||||
{"mod", "audio/x-mod"},
|
||||
{"moov", "video/quicktime"},
|
||||
{"mov", "video/quicktime"},
|
||||
{"movie", "video/x-sgi-movie"},
|
||||
{"mp2", "audio/mpeg"},
|
||||
{"mp2", "audio/x-mpeg"},
|
||||
{"mp2", "video/mpeg"},
|
||||
{"mp2", "video/x-mpeg"},
|
||||
{"mp2", "video/x-mpeq2a"},
|
||||
{"mp3", "audio/mpeg"},
|
||||
{"mp3", "audio/mpeg3"},
|
||||
{"mp3", "audio/x-mpeg-3"},
|
||||
{"mp3", "video/mpeg"},
|
||||
{"mp3", "video/x-mpeg"},
|
||||
{"mpa", "audio/mpeg"},
|
||||
{"mpa", "video/mpeg"},
|
||||
{"mpc", "application/x-project"},
|
||||
{"mpe", "video/mpeg"},
|
||||
{"mpeg", "video/mpeg"},
|
||||
{"mpg", "audio/mpeg"},
|
||||
{"mpg", "video/mpeg"},
|
||||
{"mpga", "audio/mpeg"},
|
||||
{"mpp", "application/vnd.ms-project"},
|
||||
{"mpt", "application/x-project"},
|
||||
{"mpv", "application/x-project"},
|
||||
{"mpx", "application/x-project"},
|
||||
{"mrc", "application/marc"},
|
||||
{"ms", "application/x-troff-ms"},
|
||||
{"mv", "video/x-sgi-movie"},
|
||||
{"my", "audio/make"},
|
||||
{"mzz", "application/x-vnd.audioexplosion.mzz"},
|
||||
{"nap", "image/naplps"},
|
||||
{"naplps", "image/naplps"},
|
||||
{"nc", "application/x-netcdf"},
|
||||
{"ncm", "application/vnd.nokia.configuration-message"},
|
||||
{"nif", "image/x-niff"},
|
||||
{"niff", "image/x-niff"},
|
||||
{"nix", "application/x-mix-transfer"},
|
||||
{"nsc", "application/x-conference"},
|
||||
{"nvd", "application/x-navidoc"},
|
||||
{"o", "application/octet-stream"},
|
||||
{"oda", "application/oda"},
|
||||
{"omc", "application/x-omc"},
|
||||
{"omcd", "application/x-omcdatamaker"},
|
||||
{"omcr", "application/x-omcregerator"},
|
||||
{"p", "text/x-pascal"},
|
||||
{"p10", "application/pkcs10"},
|
||||
{"p10", "application/x-pkcs10"},
|
||||
{"p12", "application/pkcs-12"},
|
||||
{"p12", "application/x-pkcs12"},
|
||||
{"p7a", "application/x-pkcs7-signature"},
|
||||
{"p7c", "application/pkcs7-mime"},
|
||||
{"p7c", "application/x-pkcs7-mime"},
|
||||
{"p7m", "application/pkcs7-mime"},
|
||||
{"p7m", "application/x-pkcs7-mime"},
|
||||
{"p7r", "application/x-pkcs7-certreqresp"},
|
||||
{"p7s", "application/pkcs7-signature"},
|
||||
{"part", "application/pro_eng"},
|
||||
{"pas", "text/pascal"},
|
||||
{"pbm", "image/x-portable-bitmap"},
|
||||
{"pcl", "application/vnd.hp-pcl"},
|
||||
{"pcl", "application/x-pcl"},
|
||||
{"pct", "image/x-pict"},
|
||||
{"pcx", "image/x-pcx"},
|
||||
{"pdb", "chemical/x-pdb"},
|
||||
{"pdf", "application/pdf"},
|
||||
{"pfunk", "audio/make"},
|
||||
{"pfunk", "audio/make.my.funk"},
|
||||
{"pgm", "image/x-portable-graymap"},
|
||||
{"pgm", "image/x-portable-greymap"},
|
||||
{"pic", "image/pict"},
|
||||
{"pict", "image/pict"},
|
||||
{"pkg", "application/x-newton-compatible-pkg"},
|
||||
{"pko", "application/vnd.ms-pki.pko"},
|
||||
{"pl", "text/plain"},
|
||||
{"pl", "text/x-script.perl"},
|
||||
{"plx", "application/x-pixclscript"},
|
||||
{"pm", "image/x-xpixmap"},
|
||||
{"pm", "text/x-script.perl-module"},
|
||||
{"pm4", "application/x-pagemaker"},
|
||||
{"pm5", "application/x-pagemaker"},
|
||||
{"png", "image/png"},
|
||||
{"pnm", "application/x-portable-anymap"},
|
||||
{"pnm", "image/x-portable-anymap"},
|
||||
{"pot", "application/mspowerpoint"},
|
||||
{"pot", "application/vnd.ms-powerpoint"},
|
||||
{"pov", "model/x-pov"},
|
||||
{"ppa", "application/vnd.ms-powerpoint"},
|
||||
{"ppm", "image/x-portable-pixmap"},
|
||||
{"pps", "application/mspowerpoint"},
|
||||
{"pps", "application/vnd.ms-powerpoint"},
|
||||
{"ppt", "application/mspowerpoint"},
|
||||
{"ppt", "application/powerpoint"},
|
||||
{"ppt", "application/vnd.ms-powerpoint"},
|
||||
{"ppt", "application/x-mspowerpoint"},
|
||||
{"ppz", "application/mspowerpoint"},
|
||||
{"pre", "application/x-freelance"},
|
||||
{"prt", "application/pro_eng"},
|
||||
{"ps", "application/postscript"},
|
||||
{"psd", "application/octet-stream"},
|
||||
{"pvu", "paleovu/x-pv"},
|
||||
{"pwz", "application/vnd.ms-powerpoint"},
|
||||
{"py", "text/x-script.python"},
|
||||
{"pyc", "application/x-bytecode.python"},
|
||||
{"qcp", "audio/vnd.qcelp"},
|
||||
{"qd3", "x-world/x-3dmf"},
|
||||
{"qd3d", "x-world/x-3dmf"},
|
||||
{"qif", "image/x-quicktime"},
|
||||
{"qt", "video/quicktime"},
|
||||
{"qtc", "video/x-qtc"},
|
||||
{"qti", "image/x-quicktime"},
|
||||
{"qtif", "image/x-quicktime"},
|
||||
{"ra", "audio/x-pn-realaudio"},
|
||||
{"ra", "audio/x-pn-realaudio-plugin"},
|
||||
{"ra", "audio/x-realaudio"},
|
||||
{"ram", "audio/x-pn-realaudio"},
|
||||
{"ras", "application/x-cmu-raster"},
|
||||
{"ras", "image/cmu-raster"},
|
||||
{"ras", "image/x-cmu-raster"},
|
||||
{"rast", "image/cmu-raster"},
|
||||
{"rexx", "text/x-script.rexx"},
|
||||
{"rf", "image/vnd.rn-realflash"},
|
||||
{"rgb", "image/x-rgb"},
|
||||
{"rm", "application/vnd.rn-realmedia"},
|
||||
{"rm", "audio/x-pn-realaudio"},
|
||||
{"rmi", "audio/mid"},
|
||||
{"rmm", "audio/x-pn-realaudio"},
|
||||
{"rmp", "audio/x-pn-realaudio"},
|
||||
{"rmp", "audio/x-pn-realaudio-plugin"},
|
||||
{"rng", "application/ringing-tones"},
|
||||
{"rng", "application/vnd.nokia.ringing-tone"},
|
||||
{"rnx", "application/vnd.rn-realplayer"},
|
||||
{"roff", "application/x-troff"},
|
||||
{"rp", "image/vnd.rn-realpix"},
|
||||
{"rpm", "audio/x-pn-realaudio-plugin"},
|
||||
{"rt", "text/richtext"},
|
||||
{"rt", "text/vnd.rn-realtext"},
|
||||
{"rtf", "application/rtf"},
|
||||
{"rtf", "application/x-rtf"},
|
||||
{"rtf", "text/richtext"},
|
||||
{"rtx", "application/rtf"},
|
||||
{"rtx", "text/richtext"},
|
||||
{"rv", "video/vnd.rn-realvideo"},
|
||||
{"s", "text/x-asm"},
|
||||
{"s3m", "audio/s3m"},
|
||||
{"saveme", "application/octet-stream"},
|
||||
{"sbk", "application/x-tbook"},
|
||||
{"scm", "application/x-lotusscreencam"},
|
||||
{"scm", "text/x-script.guile"},
|
||||
{"scm", "text/x-script.scheme"},
|
||||
{"scm", "video/x-scm"},
|
||||
{"sdml", "text/plain"},
|
||||
{"sdp", "application/sdp"},
|
||||
{"sdp", "application/x-sdp"},
|
||||
{"sdr", "application/sounder"},
|
||||
{"sea", "application/sea"},
|
||||
{"sea", "application/x-sea"},
|
||||
{"set", "application/set"},
|
||||
{"sgm", "text/sgml"},
|
||||
{"sgm", "text/x-sgml"},
|
||||
{"sgml", "text/sgml"},
|
||||
{"sgml", "text/x-sgml"},
|
||||
{"sh", "application/x-bsh"},
|
||||
{"sh", "application/x-sh"},
|
||||
{"sh", "application/x-shar"},
|
||||
{"sh", "text/x-script.sh"},
|
||||
{"shar", "application/x-bsh"},
|
||||
{"shar", "application/x-shar"},
|
||||
{"shtml", "text/html"},
|
||||
{"shtml", "text/x-server-parsed-html"},
|
||||
{"sid", "audio/x-psid"},
|
||||
{"sit", "application/x-sit"},
|
||||
{"sit", "application/x-stuffit"},
|
||||
{"skd", "application/x-koan"},
|
||||
{"skm", "application/x-koan"},
|
||||
{"skp", "application/x-koan"},
|
||||
{"skt", "application/x-koan"},
|
||||
{"sl", "application/x-seelogo"},
|
||||
{"smi", "application/smil"},
|
||||
{"smil", "application/smil"},
|
||||
{"snd", "audio/basic"},
|
||||
{"snd", "audio/x-adpcm"},
|
||||
{"sol", "application/solids"},
|
||||
{"spc", "application/x-pkcs7-certificates"},
|
||||
{"spc", "text/x-speech"},
|
||||
{"spl", "application/futuresplash"},
|
||||
{"spr", "application/x-sprite"},
|
||||
{"sprite", "application/x-sprite"},
|
||||
{"src", "application/x-wais-source"},
|
||||
{"ssi", "text/x-server-parsed-html"},
|
||||
{"ssm", "application/streamingmedia"},
|
||||
{"sst", "application/vnd.ms-pki.certstore"},
|
||||
{"step", "application/step"},
|
||||
{"stl", "application/sla"},
|
||||
{"stl", "application/vnd.ms-pki.stl"},
|
||||
{"stl", "application/x-navistyle"},
|
||||
{"stp", "application/step"},
|
||||
{"sv4cpio,", "application/x-sv4cpio"},
|
||||
{"sv4crc", "application/x-sv4crc"},
|
||||
{"svf", "image/vnd.dwg"},
|
||||
{"svf", "image/x-dwg"},
|
||||
{"svr", "application/x-world"},
|
||||
{"svr", "x-world/x-svr"},
|
||||
{"swf", "application/x-shockwave-flash"},
|
||||
{"t", "application/x-troff"},
|
||||
{"talk", "text/x-speech"},
|
||||
{"tar", "application/x-tar"},
|
||||
{"tbk", "application/toolbook"},
|
||||
{"tbk", "application/x-tbook"},
|
||||
{"tcl", "application/x-tcl"},
|
||||
{"tcl", "text/x-script.tcl"},
|
||||
{"tcsh", "text/x-script.tcsh"},
|
||||
{"tex", "application/x-tex"},
|
||||
{"texi", "application/x-texinfo"},
|
||||
{"texinfo,", "application/x-texinfo"},
|
||||
{"text", "application/plain"},
|
||||
{"text", "text/plain"},
|
||||
{"tgz", "application/gnutar"},
|
||||
{"tgz", "application/x-compressed"},
|
||||
{"tif", "image/tiff"},
|
||||
{"tif", "image/x-tiff"},
|
||||
{"tiff", "image/tiff"},
|
||||
{"tiff", "image/x-tiff"},
|
||||
{"tr", "application/x-troff"},
|
||||
{"tsi", "audio/tsp-audio"},
|
||||
{"tsp", "application/dsptype"},
|
||||
{"tsp", "audio/tsplayer"},
|
||||
{"tsv", "text/tab-separated-values"},
|
||||
{"turbot", "image/florian"},
|
||||
{"txt", "text/plain"},
|
||||
{"uil", "text/x-uil"},
|
||||
{"uni", "text/uri-list"},
|
||||
{"unis", "text/uri-list"},
|
||||
{"unv", "application/i-deas"},
|
||||
{"uri", "text/uri-list"},
|
||||
{"uris", "text/uri-list"},
|
||||
{"ustar", "application/x-ustar"},
|
||||
{"ustar", "multipart/x-ustar"},
|
||||
{"uu", "application/octet-stream"},
|
||||
{"uu", "text/x-uuencode"},
|
||||
{"uue", "text/x-uuencode"},
|
||||
{"vcd", "application/x-cdlink"},
|
||||
{"vcs", "text/x-vcalendar"},
|
||||
{"vda", "application/vda"},
|
||||
{"vdo", "video/vdo"},
|
||||
{"vew", "application/groupwise"},
|
||||
{"viv", "video/vivo"},
|
||||
{"viv", "video/vnd.vivo"},
|
||||
{"vivo", "video/vivo"},
|
||||
{"vivo", "video/vnd.vivo"},
|
||||
{"vmd", "application/vocaltec-media-desc"},
|
||||
{"vmf", "application/vocaltec-media-file"},
|
||||
{"voc", "audio/voc"},
|
||||
{"voc", "audio/x-voc"},
|
||||
{"vos", "video/vosaic"},
|
||||
{"vox", "audio/voxware"},
|
||||
{"vqe", "audio/x-twinvq-plugin"},
|
||||
{"vqf", "audio/x-twinvq"},
|
||||
{"vql", "audio/x-twinvq-plugin"},
|
||||
{"vrml", "application/x-vrml"},
|
||||
{"vrml", "model/vrml"},
|
||||
{"vrml", "x-world/x-vrml"},
|
||||
{"vrt", "x-world/x-vrt"},
|
||||
{"vsd", "application/x-visio"},
|
||||
{"vst", "application/x-visio"},
|
||||
{"vsw", "application/x-visio"},
|
||||
{"w60", "application/wordperfect6.0"},
|
||||
{"w61", "application/wordperfect6.1"},
|
||||
{"w6w", "application/msword"},
|
||||
{"wav", "audio/wav"},
|
||||
{"wav", "audio/x-wav"},
|
||||
{"wb1", "application/x-qpro"},
|
||||
{"wbmp", "image/vnd.wap.wbmp"},
|
||||
{"web", "application/vnd.xara"},
|
||||
{"wiz", "application/msword"},
|
||||
{"wk1", "application/x-123"},
|
||||
{"wmf", "windows/metafile"},
|
||||
{"wml", "text/vnd.wap.wml"},
|
||||
{"wmlc", "application/vnd.wap.wmlc"},
|
||||
{"wmls", "text/vnd.wap.wmlscript"},
|
||||
{"wmlsc", "application/vnd.wap.wmlscriptc"},
|
||||
{"word", "application/msword"},
|
||||
{"wp", "application/wordperfect"},
|
||||
{"wp5", "application/wordperfect"},
|
||||
{"wp5", "application/wordperfect6.0"},
|
||||
{"wp6", "application/wordperfect"},
|
||||
{"wpd", "application/wordperfect"},
|
||||
{"wpd", "application/x-wpwin"},
|
||||
{"wq1", "application/x-lotus"},
|
||||
{"wri", "application/mswrite"},
|
||||
{"wri", "application/x-wri"},
|
||||
{"wrl", "application/x-world"},
|
||||
{"wrl", "model/vrml"},
|
||||
{"wrl", "x-world/x-vrml"},
|
||||
{"wrz", "model/vrml"},
|
||||
{"wrz", "x-world/x-vrml"},
|
||||
{"wsc", "text/scriplet"},
|
||||
{"wsrc", "application/x-wais-source"},
|
||||
{"wtk", "application/x-wintalk"},
|
||||
{"xbm", "image/x-xbitmap"},
|
||||
{"xbm", "image/x-xbm"},
|
||||
{"xbm", "image/xbm"},
|
||||
{"xdr", "video/x-amt-demorun"},
|
||||
{"xgz", "xgl/drawing"},
|
||||
{"xif", "image/vnd.xiff"},
|
||||
{"xl", "application/excel"},
|
||||
{"xla", "application/excel"},
|
||||
{"xla", "application/x-excel"},
|
||||
{"xla", "application/x-msexcel"},
|
||||
{"xlb", "application/excel"},
|
||||
{"xlb", "application/vnd.ms-excel"},
|
||||
{"xlb", "application/x-excel"},
|
||||
{"xlc", "application/excel"},
|
||||
{"xlc", "application/vnd.ms-excel"},
|
||||
{"xlc", "application/x-excel"},
|
||||
{"xld", "application/excel"},
|
||||
{"xld", "application/x-excel"},
|
||||
{"xlk", "application/excel"},
|
||||
{"xlk", "application/x-excel"},
|
||||
{"xll", "application/excel"},
|
||||
{"xll", "application/vnd.ms-excel"},
|
||||
{"xll", "application/x-excel"},
|
||||
{"xlm", "application/excel"},
|
||||
{"xlm", "application/vnd.ms-excel"},
|
||||
{"xlm", "application/x-excel"},
|
||||
{"xls", "application/excel"},
|
||||
{"xls", "application/vnd.ms-excel"},
|
||||
{"xls", "application/x-excel"},
|
||||
{"xls", "application/x-msexcel"},
|
||||
{"xlt", "application/excel"},
|
||||
{"xlt", "application/x-excel"},
|
||||
{"xlv", "application/excel"},
|
||||
{"xlv", "application/x-excel"},
|
||||
{"xlw", "application/excel"},
|
||||
{"xlw", "application/vnd.ms-excel"},
|
||||
{"xlw", "application/x-excel"},
|
||||
{"xlw", "application/x-msexcel"},
|
||||
{"xm", "audio/xm"},
|
||||
{"xml", "application/xml"},
|
||||
{"xml", "text/xml"},
|
||||
{"xmz", "xgl/movie"},
|
||||
{"xpix", "application/x-vnd.ls-xpix"},
|
||||
{"xpm", "image/x-xpixmap"},
|
||||
{"xpm", "image/xpm"},
|
||||
{"x-png", "image/png"},
|
||||
{"xsr", "video/x-amt-showrun"},
|
||||
{"xwd", "image/x-xwd"},
|
||||
{"xwd", "image/x-xwindowdump"},
|
||||
{"xyz", "chemical/x-pdb"},
|
||||
{"z", "application/x-compress"},
|
||||
{"z", "application/x-compressed"},
|
||||
{"zip", "application/x-compressed"},
|
||||
{"zip", "application/x-zip-compressed"},
|
||||
{"zip", "application/zip"},
|
||||
{"zip", "multipart/x-zip"},
|
||||
{"zoo", "application/octet-stream"}
|
||||
};
|
||||
|
||||
} // namespace juce
|
42
deps/juce/modules/juce_core/files/juce_common_MimeTypes.h
vendored
Normal file
42
deps/juce/modules/juce_core/files/juce_common_MimeTypes.h
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
namespace MimeTypeTable
|
||||
{
|
||||
|
||||
/* @internal */
|
||||
StringArray getMimeTypesForFileExtension (const String& fileExtension);
|
||||
|
||||
/* @internal */
|
||||
StringArray getFileExtensionsForMimeType (const String& mimeType);
|
||||
|
||||
} // namespace MimeTypeTable
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user