OpenShot Library | libopenshot-audio
0.2.0
|
30 size_t bufferSizeToUse,
33 :
Thread (
"DownloadTask thread"),
34 fileStream (outputStreamToUse),
36 bufferSize (bufferSizeToUse),
38 listener (listenerToUse)
40 jassert (fileStream !=
nullptr);
41 jassert (stream !=
nullptr);
43 targetLocation = fileStream->getFile();
44 contentLength = stream->getTotalLength();
45 httpCode = stream->getStatusCode();
62 if (listener !=
nullptr)
63 listener->
progress (
this, downloaded, contentLength);
65 auto max = jmin ((
int) bufferSize, contentLength < 0 ? std::numeric_limits<int>::max()
66 :
static_cast<int> (contentLength - downloaded));
68 auto actual = stream->read (buffer.
get(), max);
73 if (! fileStream->write (buffer.
get(),
static_cast<size_t> (actual)))
81 if (downloaded == contentLength)
90 if (contentLength > 0 && downloaded < contentLength)
100 const std::unique_ptr<FileOutputStream> fileStream;
101 const std::unique_ptr<WebInputStream> stream;
102 const size_t bufferSize;
110 URL::DownloadTask::Listener::~Listener() {}
114 const File& targetFileToUse,
115 const String& extraHeadersToUse,
116 Listener* listenerToUse,
119 const size_t bufferSize = 0x8000;
122 if (
auto outputStream = std::unique_ptr<FileOutputStream> (targetFileToUse.
createOutputStream (bufferSize)))
124 std::unique_ptr<WebInputStream> stream (
new WebInputStream (urlToUse, usePostRequest));
125 stream->withExtraHeaders (extraHeadersToUse);
127 if (stream->connect (
nullptr))
128 return new FallbackDownloadTask (outputStream.release(), bufferSize, stream.release(), listenerToUse);
134 URL::DownloadTask::DownloadTask() {}
147 if (localFile ==
File())
154 while (! localFile.
isRoot())
175 url =
"file://" + url;
196 else if (nextAmp > 0 && equalsPos < nextAmp)
210 URL::URL (
const String& u,
int) : url (u) {}
213 : url (std::move (other.url)),
214 postData (std::move (other.postData)),
215 parameterNames (std::move (other.parameterNames)),
216 parameterValues (std::move (other.parameterValues)),
217 filesToUpload (std::move (other.filesToUpload))
219 , bookmark (std::move (other.bookmark))
224 URL& URL::operator= (URL&& other)
226 url = std::move (other.url);
227 postData = std::move (other.postData);
228 parameterNames = std::move (other.parameterNames);
229 parameterValues = std::move (other.parameterValues);
230 filesToUpload = std::move (other.filesToUpload);
232 bookmark = std::move (other.bookmark);
247 return url == other.url
248 && postData == other.postData
249 && parameterNames == other.parameterNames
250 && parameterValues == other.parameterValues
251 && filesToUpload == other.filesToUpload;
254 bool URL::operator!= (
const URL& other)
const
261 static String getMangledParameters (
const URL& url)
263 jassert (url.getParameterNames().size() == url.getParameterValues().size());
266 for (
int i = 0; i < url.getParameterNames().size(); ++i)
271 auto val = url.getParameterValues()[i];
275 if (val.isNotEmpty())
282 static int findEndOfScheme (
const String& url)
287 || url[i] ==
'+' || url[i] ==
'-' || url[i] ==
'.')
290 return url.substring (i).startsWith (
"://") ? i + 1 : 0;
293 static int findStartOfNetLocation (
const String& url)
295 int start = findEndOfScheme (url);
297 while (url[start] ==
'/')
303 static int findStartOfPath (
const String& url)
305 return url.indexOfChar (findStartOfNetLocation (url),
'/') + 1;
308 static void concatenatePaths (String& path,
const String& suffix)
310 if (! path.endsWithChar (
'/'))
313 if (suffix.startsWithChar (
'/'))
314 path += suffix.substring (1);
320 void URL::addParameter (
const String& name,
const String& value)
322 parameterNames.
add (name);
323 parameterValues.
add (value);
328 if (includeGetParameters && parameterNames.
size() > 0)
329 return url +
"?" + URLHelpers::getMangledParameters (*
this);
336 return url.isEmpty();
342 return url.isNotEmpty();
347 return getDomainInternal (
false);
352 auto startOfPath = URLHelpers::findStartOfPath (url);
354 return startOfPath <= 0 ?
String()
355 : url.substring (startOfPath);
360 return url.
substring (0, URLHelpers::findEndOfScheme (url) - 1);
371 return fileFromFileSchemeURL (*
this);
380 File URL::fileFromFileSchemeURL (
const URL& fileURL)
382 if (! fileURL.isLocalFile())
391 bool isUncPath = (! fileURL.url.startsWith (
"file:///"));
398 for (
auto urlElement : urlElements)
403 path =
"\\\\" + path;
411 auto colonPos = url.indexOfChar (URLHelpers::findStartOfNetLocation (url),
':');
413 return colonPos > 0 ? url.substring (colonPos + 1).getIntValue() : 0;
425 const int startOfPath = URLHelpers::findStartOfPath (url);
432 URLHelpers::concatenatePaths (u.url, newPath);
439 URLHelpers::concatenatePaths (u.url, subPath);
443 void URL::createHeadersAndPostData (
String& headers,
MemoryBlock& postDataToWrite)
const
447 if (filesToUpload.
size() > 0)
450 jassert (postData.
getSize() == 0);
454 headers <<
"Content-Type: multipart/form-data; boundary=" << boundary <<
"\r\n";
456 data <<
"--" << boundary;
458 for (
int i = 0; i < parameterNames.
size(); ++i)
460 data <<
"\r\nContent-Disposition: form-data; name=\"" << parameterNames[i]
461 <<
"\"\r\n\r\n" << parameterValues[i]
462 <<
"\r\n--" << boundary;
465 for (
auto* f : filesToUpload)
467 data <<
"\r\nContent-Disposition: form-data; name=\"" << f->parameterName
468 <<
"\"; filename=\"" << f->filename <<
"\"\r\n";
470 if (f->mimeType.isNotEmpty())
471 data <<
"Content-Type: " << f->mimeType <<
"\r\n";
473 data <<
"Content-Transfer-Encoding: binary\r\n\r\n";
475 if (f->data !=
nullptr)
480 data <<
"\r\n--" << boundary;
487 data << URLHelpers::getMangledParameters (*
this)
492 headers <<
"Content-Type: application/x-www-form-urlencoded\r\n";
494 headers <<
"Content-length: " << (int) data.getDataSize() <<
"\r\n";
501 static const char* validProtocols[] = {
"http:",
"ftp:",
"https:" };
503 for (
auto* protocol : validProtocols)
519 auto atSign = possibleEmailAddress.
indexOfChar (
'@');
526 String URL::getDomainInternal (
bool ignorePort)
const
528 auto start = URLHelpers::findStartOfNetLocation (url);
529 auto end1 = url.indexOfChar (start,
'/');
530 auto end2 = ignorePort ? -1 : url.indexOfChar (start,
':');
532 auto end = (end1 < 0 && end2 < 0) ? std::numeric_limits<int>::max()
533 : ((end1 < 0 || end2 < 0) ? jmax (end1, end2)
534 : jmin (end1, end2));
535 return url.substring (start, end);
539 URL::Bookmark::Bookmark (
void* bookmarkToUse)
540 : data (bookmarkToUse)
544 URL::Bookmark::~Bookmark()
546 [(NSData*) data release];
549 void setURLBookmark (URL& u,
void* bookmark)
551 u.bookmark =
new URL::Bookmark (bookmark);
554 void* getURLBookmark (URL& u)
556 if (u.bookmark.get() ==
nullptr)
559 return u.bookmark.get()->data;
565 template <
typename Stream>
570 : Stream (getLocalFileAccess (urlToUse)),
578 if (NSData* bookmark = (NSData*) getURLBookmark (url))
580 BOOL isBookmarkStale =
false;
581 NSError* error = nil;
583 auto nsURL = [NSURL URLByResolvingBookmarkData: bookmark
586 bookmarkDataIsStale: &isBookmarkStale
592 updateStaleBookmark (nsURL, url);
594 [nsURL stopAccessingSecurityScopedResource];
598 auto desc = [error localizedDescription];
607 bool securityAccessSucceeded =
false;
609 File getLocalFileAccess (
URL& urlToUse)
611 if (NSData* bookmark = (NSData*) getURLBookmark (urlToUse))
613 BOOL isBookmarkStale =
false;
614 NSError* error = nil;
616 auto nsURL = [NSURL URLByResolvingBookmarkData: bookmark
619 bookmarkDataIsStale: &isBookmarkStale
624 securityAccessSucceeded = [nsURL startAccessingSecurityScopedResource];
627 updateStaleBookmark (nsURL, urlToUse);
633 auto desc = [error localizedDescription];
642 void updateStaleBookmark (NSURL* nsURL,
URL& juceUrl)
644 NSError* error = nil;
646 NSData* bookmark = [nsURL bookmarkDataWithOptions: NSURLBookmarkCreationSuitableForBookmarkFile
647 includingResourceValuesForKeys: nil
652 setURLBookmark (juceUrl, (
void*) bookmark);
662 void* progressCallbackContext,
667 int numRedirectsToFollow,
668 String httpRequestCmd)
const
681 std::unique_ptr<WebInputStream> wi (
new WebInputStream (*
this, usePostCommand));
686 : callback (progressCallbackToUse), data (progressCallbackContextToUse)
689 bool postDataSendProgress (
WebInputStream&,
int bytesSent,
int totalBytes)
override
691 return callback (data, bytesSent, totalBytes);
698 ProgressCallbackCaller (
const ProgressCallbackCaller& o) : callback (o.callback), data (o.data) { jassertfalse; }
699 ProgressCallbackCaller& operator= (
const ProgressCallbackCaller&) { jassertfalse;
return *
this; }
702 std::unique_ptr<ProgressCallbackCaller> callbackCaller
703 (progressCallback !=
nullptr ?
new ProgressCallbackCaller (progressCallback, progressCallbackContext) :
nullptr);
706 wi->withExtraHeaders (headers);
709 wi->withConnectionTimeout (timeOutMs);
712 wi->withCustomRequestCommand (httpRequestCmd);
714 wi->withNumRedirectsToFollow (numRedirectsToFollow);
716 bool success = wi->connect (callbackCaller.get());
718 if (statusCode !=
nullptr)
719 *statusCode = wi->getStatusCode();
721 if (responseHeaders !=
nullptr)
722 *responseHeaders = wi->getResponseHeaders();
724 if (! success || wi->isError())
747 return juce_CreateContentURIOutputStream (*
this);
761 in->readIntoMemoryBlock (destData);
774 return in->readEntireStreamAsString();
786 const String& parameterValue)
const
789 u.addParameter (parameterName, parameterValue);
797 for (
int i = 0; i < parametersToAdd.
size(); ++i)
798 u.addParameter (parametersToAdd.
getAllKeys()[i],
812 u.postData = newPostData;
816 URL::Upload::Upload (
const String& param,
const String& name,
818 : parameterName (param), filename (name), mimeType (mime), file (f), data (mb)
820 jassert (mimeType.isNotEmpty());
823 URL URL::withUpload (Upload*
const f)
const
827 for (
int i = u.filesToUpload.size(); --i >= 0;)
828 if (u.filesToUpload.getObjectPointerUnchecked(i)->parameterName == f->parameterName)
829 u.filesToUpload.remove (i);
831 u.filesToUpload.add (f);
836 const String& mimeType)
const
838 return withUpload (
new Upload (parameterName, fileToUpload.
getFileName(),
839 mimeType, fileToUpload,
nullptr));
845 return withUpload (
new Upload (parameterName, filename, mimeType,
File(),
854 if (! result.containsChar (
'%'))
859 Array<char> utf8 (result.toRawUTF8(), (
int) result.getNumBytesAsUTF8());
861 for (
int i = 0; i < utf8.
size(); ++i)
868 if (hexDigit1 >= 0 && hexDigit2 >= 0)
870 utf8.
set (i, (
char) ((hexDigit1 << 4) + hexDigit2));
881 String legalChars (isParameter ?
"_-.~"
884 if (roundBracketsAreLegal)
889 for (
int i = 0; i < utf8.
size(); ++i)
897 utf8.
insert (++i,
"0123456789ABCDEF" [((uint8) c) >> 4]);
898 utf8.
insert (++i,
"0123456789ABCDEF" [c & 15]);
910 if (u.containsChar (
'@') && ! u.containsChar (
':'))
void startThread()
Starts the thread running.
int size() const noexcept
Returns the current number of objects in the array.
InputStream * createInputStream(bool doPostLikeRequest, OpenStreamProgressCallback *progressCallback=nullptr, void *progressCallbackContext=nullptr, String extraHeaders=String(), int connectionTimeOutMs=0, StringPairArray *responseHeaders=nullptr, int *statusCode=nullptr, int numRedirectsToFollow=5, String httpRequestCmd=String()) const
Attempts to open a stream that can read from this URL.
URL withFileToUpload(const String ¶meterName, const File &fileToUpload, const String &mimeType) const
Returns a copy of this URL, with a file-upload type parameter added to it.
const char * toRawUTF8() const
Returns a pointer to a UTF-8 version of this string.
String getFileName() const
Returns the last section of the pathname.
String getSubPath() const
Returns the path part of the URL.
static int getHexDigitValue(juce_wchar digit) noexcept
Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit.
bool containsChar(juce_wchar character) const noexcept
Tests whether the string contains a particular character.
bool containsIgnoreCase(StringRef text) const noexcept
Tests whether the string contains another substring.
int lastIndexOfChar(juce_wchar character) const noexcept
Searches for a character inside this string (working backwards from the end of the string).
File getParentDirectory() const
Returns the directory that contains this file or directory.
bool isRoot() const
Checks whether the path of this file represents the root of a file system, irrespective of its existe...
int getPort() const
Attempts to read a port number from the URL.
XmlElement * readEntireXmlStream(bool usePostCommand=false) const
Tries to download the entire contents of this URL and parse it as XML.
bool endsWithChar(juce_wchar character) const noexcept
Tests whether the string ends with a particular character.
FileOutputStream * createOutputStream(size_t bufferSize=0x8000) const
Creates a stream to write to this file.
static StringRef getSeparatorString()
The system-specific file separator character, as a string.
static bool isProbablyAnEmailAddress(const String &possibleEmailAddress)
Takes a guess as to whether a string might be a valid email address.
int size() const noexcept
Returns the current number of elements in the array.
Writes data to an internal memory buffer, which grows as required.
const String & getFullPathName() const noexcept
Returns the complete, absolute path of this file.
String getScheme() const
Returns the scheme of the URL.
size_t getNumBytesAsUTF8() const noexcept
Returns the number of bytes required to represent this string as UTF8.
Represents a URL and has a bunch of useful functions to manipulate it.
URL withDataToUpload(const String ¶meterName, const String &filename, const MemoryBlock &fileContentToUpload, const String &mimeType) const
Returns a copy of this URL, with a file-upload type parameter added to it.
virtual void finished(URL::DownloadTask *task, bool success)=0
Called when the download has finished.
bool threadShouldExit() const
Checks whether the thread has been told to stop running.
void removeRange(int startIndex, int numberToRemove)
Removes a range of elements from the array.
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Returns an array containing the tokens in a given string.
String toString(bool includeGetParameters) const
Returns a string version of the URL.
bool launchInDefaultBrowser() const
Tries to launch the system's default browser to open the URL.
Holds a resizable array of primitive or copy-by-value objects.
URL withParameter(const String ¶meterName, const String ¶meterValue) const
Returns a copy of this URL, with a GET or POST parameter added to the end.
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
bool startsWithIgnoreCase(StringRef text) const noexcept
Tests whether the string begins with another string.
const StringArray & getAllKeys() const noexcept
Returns a list of all keys in the array.
Used to receive callbacks for download progress.
virtual void flush()=0
If the stream is using a buffer, this will ensure it gets written out to the destination.
Used to build a tree of elements representing an XML document.
String getDomain() const
Returns just the domain part of the URL.
The base class for streams that write data to some kind of destination.
bool startsWith(StringRef text) const noexcept
Tests whether the string begins with another string.
String getFileName() const
Returns the file name.
size_t getSize() const noexcept
Returns the block's current allocated size, in bytes.
Represents a local file or directory.
void signalThreadShouldExit()
Sets a flag to tell the thread it should stop.
String replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const
Returns a string with all occurrences of a character replaced with a different one.
bool deleteFile() const
Deletes a file.
int size() const noexcept
Returns the number of strings in the array.
bool(void *context, int bytesSent, int totalBytes) OpenStreamProgressCallback
This callback function can be used by the createInputStream() method.
virtual ~DownloadTask()
Releases the resources of the download task, unregisters the listener and cancels the download if nec...
A container for holding a set of strings which are keyed by another string.
static String removeEscapeChars(const String &stringToRemoveEscapeCharsFrom)
Replaces any escape character sequences in a string with their original character codes.
String upToFirstOccurrenceOf(StringRef substringToEndWith, bool includeSubStringInResult, bool ignoreCase) const
Returns the start of this string, up to the first occurrence of a substring.
virtual void progress(URL::DownloadTask *task, int64 bytesDownloaded, int64 totalLength)
Called periodically by the OS to indicate download progress.
URL withPOSTData(const String &postData) const
Returns a copy of this URL, with a block of data to send as the POST data.
File getLocalFile() const
Returns the file path of the local file to which this URL refers to.
ElementType getUnchecked(int index) const
Returns one of the elements in the array, without checking the index passed in.
static String addEscapeChars(const String &stringToAddEscapeCharsTo, bool isParameter, bool roundBracketsAreLegal=true)
Adds escape sequences to a string to encode any characters that aren't legal in a URL.
bool isEmpty() const noexcept
Returns true if the URL is an empty string.
static URL createWithoutParsing(const String &url)
Returns a URL without attempting to remove any embedded parameters from the string.
OutputStream * createOutputStream() const
Attempts to open an output stream to a URL for writing.
int length() const noexcept
Returns the number of characters in the string.
FileInputStream * createInputStream() const
Creates a stream to read from this file.
static bool isLetterOrDigit(char character) noexcept
Checks whether a character is alphabetic or numeric.
bool isWellFormed() const
True if it seems to be valid.
static Random & getSystemRandom() noexcept
The overhead of creating a new Random object is fairly small, but if you want to avoid it,...
URL withNewSubPath(const String &newPath) const
Returns a new version of this URL with a different sub-path.
bool operator==(const URL &) const
Compares two URLs.
String readEntireTextStream(bool usePostCommand=false) const
Tries to download the entire contents of this URL as a string.
bool isNotEmpty() const noexcept
Returns true if the string contains at least one character.
ElementType * getRawDataPointer() noexcept
Returns a pointer to the actual array data.
bool readEntireBinaryStream(MemoryBlock &destData, bool usePostCommand=false) const
Tries to download the entire contents of this URL into a binary data block.
static XmlElement * parse(const File &file)
A handy static method that parses a file.
ElementType * get() const noexcept
Returns a raw pointer to the allocated data.
String substring(int startIndex, int endIndex) const
Returns a subsection of the string.
bool waitForThreadToExit(int timeOutMilliseconds) const
Waits for the thread to stop.
URL() noexcept
Creates an empty URL.
Thread(const String &threadName, size_t threadStackSize=0)
Creates a thread.
Represents a download task.
void add(String stringToAdd)
Appends a string at the end of the array.
void run() override
Must be implemented to perform the thread's actual code.
void set(int indexToChange, ParameterType newValue)
Replaces an element with a new value.
URL getChildURL(const String &subPath) const
Returns a new URL that refers to a sub-path relative to this one.
static bool JUCE_CALLTYPE openDocument(const String &documentURL, const String ¶meters)
Tries to launch the OS's default reader application for a given file or URL.
bool startsWithChar(juce_wchar character) const noexcept
Tests whether the string begins with a particular character.
String replace(StringRef stringToReplace, StringRef stringToInsertInstead, bool ignoreCase=false) const
Replaces all occurrences of a substring with another string.
bool isLocalFile() const
Returns true if this URL refers to a local file.
String fromFirstOccurrenceOf(StringRef substringToStartFrom, bool includeSubStringInResult, bool ignoreCase) const
Returns a section of the string starting from a given substring.
An output stream that writes into a local file.
int size() const noexcept
Returns the number of strings in the array.
const StringArray & getAllValues() const noexcept
Returns a list of all values in the array.
URL withParameters(const StringPairArray ¶metersToAdd) const
Returns a copy of this URL, with a set of GET or POST parameters added.
int indexOfChar(juce_wchar characterToLookFor) const noexcept
Searches for a character inside this string.
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Creates a String from a UTF-8 encoded buffer.
URL withNewDomainAndPath(const String &newFullPath) const
Returns a new version of this URL with a different domain and path.
void insert(int indexToInsertAt, ParameterType newElement)
Inserts a new element into the array at a given position.
static bool isProbablyAWebsiteURL(const String &possibleURL)
Takes a guess as to whether a string might be a valid website address.
String fromLastOccurrenceOf(StringRef substringToFind, bool includeSubStringInResult, bool ignoreCase) const
Returns a section of the string starting from the last occurrence of a given substring.
A class to hold a resizable block of raw data.