|
|
|
@@ -7924,7 +7924,7 @@ public: |
|
|
|
|
|
|
|
expect (tempFile.exists()); |
|
|
|
expect (tempFile.getSize() == 10); |
|
|
|
expect (std::abs (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds()) < 3000); |
|
|
|
expect (std::abs ((int64) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000); |
|
|
|
expect (tempFile.loadFileAsString() == "0123456789"); |
|
|
|
expect (! demoFolder.containsSubDirectories()); |
|
|
|
|
|
|
|
@@ -7945,7 +7945,7 @@ public: |
|
|
|
Time t (Time::getCurrentTime()); |
|
|
|
tempFile.setLastModificationTime (t); |
|
|
|
Time t2 = tempFile.getLastModificationTime(); |
|
|
|
expect (std::abs (t2.toMilliseconds() - t.toMilliseconds()) <= 1000); |
|
|
|
expect (std::abs ((int64) (t2.toMilliseconds() - t.toMilliseconds())) <= 1000); |
|
|
|
|
|
|
|
{ |
|
|
|
MemoryBlock mb; |
|
|
|
@@ -9511,55 +9511,62 @@ const StringPairArray& URL::getMimeTypesOfUploadFiles() const |
|
|
|
const String URL::removeEscapeChars (const String& s) |
|
|
|
{ |
|
|
|
String result (s.replaceCharacter ('+', ' ')); |
|
|
|
int nextPercent = 0; |
|
|
|
|
|
|
|
for (;;) |
|
|
|
{ |
|
|
|
nextPercent = result.indexOfChar (nextPercent, '%'); |
|
|
|
|
|
|
|
if (nextPercent < 0) |
|
|
|
break; |
|
|
|
if (! result.containsChar ('%')) |
|
|
|
return result; |
|
|
|
|
|
|
|
int hexDigit1 = 0, hexDigit2 = 0; |
|
|
|
// We need to operate on the string as raw UTF8 chars, and then recombine them into unicode |
|
|
|
// after all the replacements have been made, so that multi-byte chars are handled. |
|
|
|
Array<char> utf8 (result.toUTF8(), result.getNumBytesAsUTF8()); |
|
|
|
|
|
|
|
if ((hexDigit1 = CharacterFunctions::getHexDigitValue (result [nextPercent + 1])) >= 0 |
|
|
|
&& (hexDigit2 = CharacterFunctions::getHexDigitValue (result [nextPercent + 2])) >= 0) |
|
|
|
for (int i = 0; i < utf8.size(); ++i) |
|
|
|
{ |
|
|
|
if (utf8.getUnchecked(i) == '%') |
|
|
|
{ |
|
|
|
const juce_wchar replacementChar = (juce_wchar) ((hexDigit1 << 4) + hexDigit2); |
|
|
|
result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar)); |
|
|
|
} |
|
|
|
const int hexDigit1 = CharacterFunctions::getHexDigitValue (utf8 [i + 1]); |
|
|
|
const int hexDigit2 = CharacterFunctions::getHexDigitValue (utf8 [i + 2]); |
|
|
|
|
|
|
|
++nextPercent; |
|
|
|
if (hexDigit1 >= 0 && hexDigit2 >= 0) |
|
|
|
{ |
|
|
|
utf8.set (i, (char) ((hexDigit1 << 4) + hexDigit2)); |
|
|
|
utf8.removeRange (i + 1, 2); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); |
|
|
|
} |
|
|
|
|
|
|
|
const String URL::addEscapeChars (const String& s, const bool isParameter) |
|
|
|
{ |
|
|
|
String result; |
|
|
|
result.preallocateStorage (s.length() + 8); |
|
|
|
const char* utf8 = s.toUTF8(); |
|
|
|
const char* legalChars = isParameter ? "_-.*!'()" |
|
|
|
: "_-$.*!'(),"; |
|
|
|
const char* const legalChars = isParameter ? "_-.*!'()" |
|
|
|
: ",$_-.*!'()"; |
|
|
|
|
|
|
|
Array<char> utf8 (s.toUTF8(), s.getNumBytesAsUTF8()); |
|
|
|
|
|
|
|
while (*utf8 != 0) |
|
|
|
for (int i = 0; i < utf8.size(); ++i) |
|
|
|
{ |
|
|
|
const char c = *utf8++; |
|
|
|
const char c = utf8.getUnchecked(i); |
|
|
|
|
|
|
|
if (CharacterFunctions::isLetterOrDigit (c) |
|
|
|
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0) |
|
|
|
{ |
|
|
|
result << c; |
|
|
|
} |
|
|
|
else |
|
|
|
if (! (CharacterFunctions::isLetterOrDigit (c) |
|
|
|
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0)) |
|
|
|
{ |
|
|
|
const int v = (int) (uint8) c; |
|
|
|
result << (v < 0x10 ? "%0" : "%") << String::toHexString (v); |
|
|
|
if (c == ' ') |
|
|
|
{ |
|
|
|
utf8.set (i, '+'); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
static const char* const hexDigits = "0123456789abcdef"; |
|
|
|
|
|
|
|
utf8.set (i, '%'); |
|
|
|
utf8.insert (++i, hexDigits [((uint8) c) >> 4]); |
|
|
|
utf8.insert (++i, hexDigits [c & 15]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); |
|
|
|
} |
|
|
|
|
|
|
|
bool URL::launchInDefaultBrowser() const |
|
|
|
@@ -18934,24 +18941,42 @@ int JUCEApplication::shutdownApp() |
|
|
|
return getApplicationReturnValue(); |
|
|
|
} |
|
|
|
|
|
|
|
// This is called on the Mac and iOS where the OS doesn't allow the stack to unwind on shutdown.. |
|
|
|
void JUCEApplication::appWillTerminateByForce() |
|
|
|
{ |
|
|
|
{ |
|
|
|
const ScopedPointer<JUCEApplication> app (JUCEApplication::getInstance()); |
|
|
|
|
|
|
|
if (app != 0) |
|
|
|
app->shutdownApp(); |
|
|
|
} |
|
|
|
|
|
|
|
shutdownJuce_GUI(); |
|
|
|
} |
|
|
|
|
|
|
|
int JUCEApplication::main (const String& commandLine) |
|
|
|
{ |
|
|
|
ScopedJuceInitialiser_GUI libraryInitialiser; |
|
|
|
|
|
|
|
jassert (createInstance != 0); |
|
|
|
const ScopedPointer<JUCEApplication> app (createInstance()); |
|
|
|
int returnCode = 0; |
|
|
|
|
|
|
|
if (! app->initialiseApp (commandLine)) |
|
|
|
return 0; |
|
|
|
|
|
|
|
JUCE_TRY |
|
|
|
{ |
|
|
|
// loop until a quit message is received.. |
|
|
|
MessageManager::getInstance()->runDispatchLoop(); |
|
|
|
const ScopedPointer<JUCEApplication> app (createInstance()); |
|
|
|
|
|
|
|
if (! app->initialiseApp (commandLine)) |
|
|
|
return 0; |
|
|
|
|
|
|
|
JUCE_TRY |
|
|
|
{ |
|
|
|
// loop until a quit message is received.. |
|
|
|
MessageManager::getInstance()->runDispatchLoop(); |
|
|
|
} |
|
|
|
JUCE_CATCH_EXCEPTION |
|
|
|
|
|
|
|
returnCode = app->shutdownApp(); |
|
|
|
} |
|
|
|
JUCE_CATCH_EXCEPTION |
|
|
|
|
|
|
|
return app->shutdownApp(); |
|
|
|
return returnCode; |
|
|
|
} |
|
|
|
|
|
|
|
#if JUCE_IOS |
|
|
|
@@ -265723,11 +265748,7 @@ END_JUCE_NAMESPACE |
|
|
|
|
|
|
|
- (void) applicationWillTerminate: (UIApplication*) application |
|
|
|
{ |
|
|
|
jassert (JUCEApplication::getInstance() != 0); |
|
|
|
JUCEApplication::getInstance()->shutdownApp(); |
|
|
|
|
|
|
|
delete JUCEApplication::getInstance(); |
|
|
|
shutdownJuce_GUI(); |
|
|
|
JUCEApplication::appWillTerminateByForce(); |
|
|
|
} |
|
|
|
|
|
|
|
@end |
|
|
|
@@ -276679,21 +276700,18 @@ public: |
|
|
|
{ |
|
|
|
JUCEApplication::getInstance()->systemRequestedQuit(); |
|
|
|
|
|
|
|
if (MessageManager::getInstance()->hasStopMessageBeenSent()) |
|
|
|
{ |
|
|
|
[NSApp performSelectorOnMainThread: @selector (replyToApplicationShouldTerminate:) |
|
|
|
withObject: [NSNumber numberWithBool: YES] |
|
|
|
waitUntilDone: NO]; |
|
|
|
|
|
|
|
return NSTerminateLater; |
|
|
|
} |
|
|
|
|
|
|
|
return NSTerminateCancel; |
|
|
|
if (! MessageManager::getInstance()->hasStopMessageBeenSent()) |
|
|
|
return NSTerminateCancel; |
|
|
|
} |
|
|
|
|
|
|
|
return NSTerminateNow; |
|
|
|
} |
|
|
|
|
|
|
|
virtual void willTerminate() |
|
|
|
{ |
|
|
|
JUCEApplication::appWillTerminateByForce(); |
|
|
|
} |
|
|
|
|
|
|
|
virtual BOOL openFile (const NSString* filename) |
|
|
|
{ |
|
|
|
if (JUCEApplication::getInstance() != 0) |
|
|
|
@@ -276804,6 +276822,7 @@ using namespace JUCE_NAMESPACE; |
|
|
|
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename; |
|
|
|
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames; |
|
|
|
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app; |
|
|
|
- (void) applicationWillTerminate: (NSNotification*) aNotification; |
|
|
|
- (void) applicationDidBecomeActive: (NSNotification*) aNotification; |
|
|
|
- (void) applicationDidResignActive: (NSNotification*) aNotification; |
|
|
|
- (void) applicationWillUnhide: (NSNotification*) aNotification; |
|
|
|
@@ -276857,6 +276876,12 @@ using namespace JUCE_NAMESPACE; |
|
|
|
return redirector->shouldTerminate(); |
|
|
|
} |
|
|
|
|
|
|
|
- (void) applicationWillTerminate: (NSNotification*) aNotification |
|
|
|
{ |
|
|
|
(void) aNotification; |
|
|
|
redirector->willTerminate(); |
|
|
|
} |
|
|
|
|
|
|
|
- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename |
|
|
|
{ |
|
|
|
(void) app; |
|
|
|
|