| @@ -7882,24 +7882,21 @@ END_JUCE_NAMESPACE | |||
| /*** Start of inlined file: juce_FileInputStream.cpp ***/ | |||
| BEGIN_JUCE_NAMESPACE | |||
| void* juce_fileOpen (const File& file, bool forWriting); | |||
| void juce_fileClose (void* handle); | |||
| int juce_fileRead (void* handle, void* buffer, int size); | |||
| int64 juce_fileSetPosition (void* handle, int64 pos); | |||
| FileInputStream::FileInputStream (const File& f) | |||
| : file (f), | |||
| fileHandle (0), | |||
| currentPosition (0), | |||
| totalSize (0), | |||
| needToSeek (true) | |||
| { | |||
| totalSize = f.getSize(); | |||
| fileHandle = juce_fileOpen (f, false); | |||
| openHandle(); | |||
| } | |||
| FileInputStream::~FileInputStream() | |||
| { | |||
| juce_fileClose (fileHandle); | |||
| closeHandle(); | |||
| } | |||
| int64 FileInputStream::getTotalLength() | |||
| @@ -7919,7 +7916,7 @@ int FileInputStream::read (void* buffer, int bytesToRead) | |||
| needToSeek = false; | |||
| } | |||
| num = juce_fileRead (fileHandle, buffer, bytesToRead); | |||
| num = readInternal (buffer, bytesToRead); | |||
| currentPosition += num; | |||
| return num; | |||
| @@ -7952,39 +7949,23 @@ END_JUCE_NAMESPACE | |||
| /*** Start of inlined file: juce_FileOutputStream.cpp ***/ | |||
| BEGIN_JUCE_NAMESPACE | |||
| void* juce_fileOpen (const File& file, bool forWriting); | |||
| void juce_fileClose (void* handle); | |||
| int juce_fileWrite (void* handle, const void* buffer, int size); | |||
| int64 juce_fileSetPosition (void* handle, int64 pos); | |||
| FileOutputStream::FileOutputStream (const File& f, | |||
| const int bufferSize_) | |||
| FileOutputStream::FileOutputStream (const File& f, const int bufferSize_) | |||
| : file (f), | |||
| fileHandle (0), | |||
| currentPosition (0), | |||
| bufferSize (bufferSize_), | |||
| bytesInBuffer (0) | |||
| bytesInBuffer (0), | |||
| buffer (jmax (bufferSize_, 16)) | |||
| { | |||
| fileHandle = juce_fileOpen (f, true); | |||
| if (fileHandle != 0) | |||
| { | |||
| currentPosition = getPositionInternal(); | |||
| if (currentPosition < 0) | |||
| { | |||
| jassertfalse; | |||
| juce_fileClose (fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| buffer.malloc (jmax (bufferSize_, 16)); | |||
| openHandle(); | |||
| } | |||
| FileOutputStream::~FileOutputStream() | |||
| { | |||
| flush(); | |||
| juce_fileClose (fileHandle); | |||
| closeHandle(); | |||
| } | |||
| int64 FileOutputStream::getPosition() | |||
| @@ -8007,7 +7988,7 @@ void FileOutputStream::flush() | |||
| { | |||
| if (bytesInBuffer > 0) | |||
| { | |||
| juce_fileWrite (fileHandle, buffer, bytesInBuffer); | |||
| writeInternal (buffer, bytesInBuffer); | |||
| bytesInBuffer = 0; | |||
| } | |||
| @@ -8027,7 +8008,7 @@ bool FileOutputStream::write (const void* const src, const int numBytes) | |||
| if (bytesInBuffer > 0) | |||
| { | |||
| // flush the reservoir | |||
| const bool wroteOk = (juce_fileWrite (fileHandle, buffer, bytesInBuffer) == bytesInBuffer); | |||
| const bool wroteOk = (writeInternal (buffer, bytesInBuffer) == bytesInBuffer); | |||
| bytesInBuffer = 0; | |||
| if (! wroteOk) | |||
| @@ -8042,9 +8023,12 @@ bool FileOutputStream::write (const void* const src, const int numBytes) | |||
| } | |||
| else | |||
| { | |||
| const int bytesWritten = juce_fileWrite (fileHandle, src, numBytes); | |||
| currentPosition += bytesWritten; | |||
| const int bytesWritten = writeInternal (src, numBytes); | |||
| if (bytesWritten < 0) | |||
| return false; | |||
| currentPosition += bytesWritten; | |||
| return bytesWritten == numBytes; | |||
| } | |||
| } | |||
| @@ -9433,8 +9417,15 @@ const String URL::removeEscapeChars (const String& s) | |||
| if (nextPercent < 0) | |||
| break; | |||
| juce_wchar replacementChar = (juce_wchar) result.substring (nextPercent + 1, nextPercent + 3).getHexValue32(); | |||
| result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar)); | |||
| int hexDigit1 = 0, hexDigit2 = 0; | |||
| if ((hexDigit1 = CharacterFunctions::getHexDigitValue (result [nextPercent + 1])) >= 0 | |||
| && (hexDigit2 = CharacterFunctions::getHexDigitValue (result [nextPercent + 2])) >= 0) | |||
| { | |||
| const juce_wchar replacementChar = (juce_wchar) ((hexDigit1 << 16) + hexDigit2); | |||
| result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar)); | |||
| } | |||
| ++nextPercent; | |||
| } | |||
| @@ -18900,10 +18891,11 @@ BEGIN_JUCE_NAMESPACE | |||
| juce_ImplementSingleton (ApplicationProperties) | |||
| ApplicationProperties::ApplicationProperties() throw() | |||
| ApplicationProperties::ApplicationProperties() | |||
| : msBeforeSaving (3000), | |||
| options (PropertiesFile::storeAsBinary), | |||
| commonSettingsAreReadOnly (0) | |||
| commonSettingsAreReadOnly (0), | |||
| processLock (0) | |||
| { | |||
| } | |||
| @@ -18917,13 +18909,15 @@ void ApplicationProperties::setStorageParameters (const String& applicationName, | |||
| const String& fileNameSuffix, | |||
| const String& folderName_, | |||
| const int millisecondsBeforeSaving, | |||
| const int propertiesFileOptions) throw() | |||
| const int propertiesFileOptions, | |||
| InterProcessLock* processLock_) | |||
| { | |||
| appName = applicationName; | |||
| fileSuffix = fileNameSuffix; | |||
| folderName = folderName_; | |||
| msBeforeSaving = millisecondsBeforeSaving; | |||
| options = propertiesFileOptions; | |||
| processLock = processLock_; | |||
| } | |||
| bool ApplicationProperties::testWriteAccess (const bool testUserSettings, | |||
| @@ -18959,7 +18953,7 @@ bool ApplicationProperties::testWriteAccess (const bool testUserSettings, | |||
| return true; | |||
| } | |||
| void ApplicationProperties::openFiles() throw() | |||
| void ApplicationProperties::openFiles() | |||
| { | |||
| // You need to call setStorageParameters() before trying to get hold of the | |||
| // properties! | |||
| @@ -18969,17 +18963,17 @@ void ApplicationProperties::openFiles() throw() | |||
| { | |||
| if (userProps == 0) | |||
| userProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName, | |||
| false, msBeforeSaving, options); | |||
| false, msBeforeSaving, options, processLock); | |||
| if (commonProps == 0) | |||
| commonProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName, | |||
| true, msBeforeSaving, options); | |||
| true, msBeforeSaving, options, processLock); | |||
| userProps->setFallbackPropertySet (commonProps); | |||
| } | |||
| } | |||
| PropertiesFile* ApplicationProperties::getUserSettings() throw() | |||
| PropertiesFile* ApplicationProperties::getUserSettings() | |||
| { | |||
| if (userProps == 0) | |||
| openFiles(); | |||
| @@ -18987,7 +18981,7 @@ PropertiesFile* ApplicationProperties::getUserSettings() throw() | |||
| return userProps; | |||
| } | |||
| PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) throw() | |||
| PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) | |||
| { | |||
| if (commonProps == 0) | |||
| openFiles(); | |||
| @@ -238256,69 +238250,76 @@ void File::createDirectoryInternal (const String& fileName) const | |||
| CreateDirectory (fileName, 0); | |||
| } | |||
| // return 0 if not possible | |||
| void* juce_fileOpen (const File& file, bool forWriting) | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| { | |||
| HANDLE h; | |||
| if (forWriting) | |||
| { | |||
| h = CreateFile (file.getFullPathName(), GENERIC_WRITE, FILE_SHARE_READ, 0, | |||
| OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = pos; | |||
| li.LowPart = SetFilePointer ((HANDLE) handle, li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails) | |||
| return li.QuadPart; | |||
| } | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| SetFilePointer (h, 0, 0, FILE_END); | |||
| else | |||
| h = 0; | |||
| } | |||
| else | |||
| { | |||
| h = CreateFile (file.getFullPathName(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, | |||
| OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | |||
| void FileInputStream::openHandle() | |||
| { | |||
| totalSize = file.getSize(); | |||
| if (h == INVALID_HANDLE_VALUE) | |||
| h = 0; | |||
| } | |||
| HANDLE h = CreateFile (file.getFullPathName(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, | |||
| OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | |||
| return h; | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| fileHandle = (void*) h; | |||
| } | |||
| void juce_fileClose (void* handle) | |||
| void FileInputStream::closeHandle() | |||
| { | |||
| CloseHandle (handle); | |||
| CloseHandle ((HANDLE) fileHandle); | |||
| } | |||
| int juce_fileRead (void* handle, void* buffer, int size) | |||
| size_t FileInputStream::readInternal (void* buffer, size_t numBytes) | |||
| { | |||
| DWORD num = 0; | |||
| ReadFile ((HANDLE) handle, buffer, size, &num, 0); | |||
| return (int) num; | |||
| if (fileHandle != 0) | |||
| { | |||
| DWORD actualNum = 0; | |||
| ReadFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| return (size_t) actualNum; | |||
| } | |||
| return 0; | |||
| } | |||
| int juce_fileWrite (void* handle, const void* buffer, int size) | |||
| void FileOutputStream::openHandle() | |||
| { | |||
| DWORD num; | |||
| WriteFile ((HANDLE) handle, buffer, size, &num, 0); | |||
| return (int) num; | |||
| HANDLE h = CreateFile (file.getFullPathName(), GENERIC_WRITE, FILE_SHARE_READ, 0, | |||
| OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| { | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = 0; | |||
| li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_END); | |||
| if (li.LowPart != INVALID_SET_FILE_POINTER) | |||
| { | |||
| fileHandle = (void*) h; | |||
| currentPosition = li.QuadPart; | |||
| } | |||
| } | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| void FileOutputStream::closeHandle() | |||
| { | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = pos; | |||
| li.LowPart = SetFilePointer ((HANDLE) handle, li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails) | |||
| return li.QuadPart; | |||
| CloseHandle ((HANDLE) fileHandle); | |||
| } | |||
| int64 FileOutputStream::getPositionInternal() const | |||
| int FileOutputStream::writeInternal (const void* buffer, int numBytes) | |||
| { | |||
| if (fileHandle == 0) | |||
| return -1; | |||
| if (fileHandle != 0) | |||
| { | |||
| DWORD actualNum = 0; | |||
| WriteFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| return (int) actualNum; | |||
| } | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = 0; | |||
| li.LowPart = SetFilePointer ((HANDLE) fileHandle, 0, &li.HighPart, FILE_CURRENT); // (returns -1 if it fails) | |||
| return jmax ((int64) 0, li.QuadPart); | |||
| return 0; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| @@ -238367,22 +238368,23 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int | |||
| bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const | |||
| { | |||
| void* const h = juce_fileOpen (fullPath, true); | |||
| bool ok = false; | |||
| HANDLE h = CreateFile (fullPath, GENERIC_WRITE, FILE_SHARE_READ, 0, | |||
| OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||
| if (h != 0) | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| { | |||
| FILETIME m, a, c; | |||
| timeToFileTime (modificationTime, &m); | |||
| timeToFileTime (accessTime, &a); | |||
| timeToFileTime (creationTime, &c); | |||
| ok = SetFileTime ((HANDLE) h, | |||
| ok = SetFileTime (h, | |||
| creationTime > 0 ? &c : 0, | |||
| accessTime > 0 ? &a : 0, | |||
| modificationTime > 0 ? &m : 0) != 0; | |||
| juce_fileClose (h); | |||
| CloseHandle (h); | |||
| } | |||
| return ok; | |||
| @@ -253737,66 +253739,81 @@ void File::createDirectoryInternal (const String& fileName) const | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| } | |||
| void* juce_fileOpen (const File& file, bool forWriting) | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| { | |||
| int flags = O_RDONLY; | |||
| if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) | |||
| return pos; | |||
| if (forWriting) | |||
| { | |||
| if (file.exists()) | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||
| return -1; | |||
| } | |||
| if (f != -1) | |||
| lseek (f, 0, SEEK_END); | |||
| void FileInputStream::openHandle() | |||
| { | |||
| totalSize = file.getSize(); | |||
| return (void*) f; | |||
| } | |||
| else | |||
| { | |||
| flags = O_RDWR + O_CREAT; | |||
| } | |||
| } | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644); | |||
| return (void*) open (file.getFullPathName().toUTF8(), flags, 00644); | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| } | |||
| void juce_fileClose (void* handle) | |||
| void FileInputStream::closeHandle() | |||
| { | |||
| if (handle != 0) | |||
| close ((int) (pointer_sized_int) handle); | |||
| if (fileHandle != 0) | |||
| { | |||
| close ((int) (pointer_sized_int) fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| int juce_fileRead (void* handle, void* buffer, int size) | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| if (handle != 0) | |||
| return jmax (0, (int) read ((int) (pointer_sized_int) handle, buffer, size)); | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| return 0; | |||
| } | |||
| int juce_fileWrite (void* handle, const void* buffer, int size) | |||
| void FileOutputStream::openHandle() | |||
| { | |||
| if (handle != 0) | |||
| return (int) write ((int) (pointer_sized_int) handle, buffer, size); | |||
| if (file.exists()) | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||
| return 0; | |||
| if (f != -1) | |||
| { | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| fileHandle = (void*) f; | |||
| else | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644); | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| } | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| void FileOutputStream::closeHandle() | |||
| { | |||
| if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) | |||
| return pos; | |||
| return -1; | |||
| if (fileHandle != 0) | |||
| { | |||
| close ((int) (pointer_sized_int) fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| int64 FileOutputStream::getPositionInternal() const | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| if (fileHandle != 0) | |||
| return lseek ((int) (pointer_sized_int) fileHandle, 0, SEEK_CUR); | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return -1; | |||
| return 0; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| @@ -263477,66 +263494,81 @@ void File::createDirectoryInternal (const String& fileName) const | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| } | |||
| void* juce_fileOpen (const File& file, bool forWriting) | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| { | |||
| int flags = O_RDONLY; | |||
| if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) | |||
| return pos; | |||
| if (forWriting) | |||
| { | |||
| if (file.exists()) | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||
| return -1; | |||
| } | |||
| if (f != -1) | |||
| lseek (f, 0, SEEK_END); | |||
| void FileInputStream::openHandle() | |||
| { | |||
| totalSize = file.getSize(); | |||
| return (void*) f; | |||
| } | |||
| else | |||
| { | |||
| flags = O_RDWR + O_CREAT; | |||
| } | |||
| } | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644); | |||
| return (void*) open (file.getFullPathName().toUTF8(), flags, 00644); | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| } | |||
| void juce_fileClose (void* handle) | |||
| void FileInputStream::closeHandle() | |||
| { | |||
| if (handle != 0) | |||
| close ((int) (pointer_sized_int) handle); | |||
| if (fileHandle != 0) | |||
| { | |||
| close ((int) (pointer_sized_int) fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| int juce_fileRead (void* handle, void* buffer, int size) | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| if (handle != 0) | |||
| return jmax (0, (int) read ((int) (pointer_sized_int) handle, buffer, size)); | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| return 0; | |||
| } | |||
| int juce_fileWrite (void* handle, const void* buffer, int size) | |||
| void FileOutputStream::openHandle() | |||
| { | |||
| if (handle != 0) | |||
| return (int) write ((int) (pointer_sized_int) handle, buffer, size); | |||
| if (file.exists()) | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||
| return 0; | |||
| if (f != -1) | |||
| { | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| fileHandle = (void*) f; | |||
| else | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644); | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| } | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| void FileOutputStream::closeHandle() | |||
| { | |||
| if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) | |||
| return pos; | |||
| return -1; | |||
| if (fileHandle != 0) | |||
| { | |||
| close ((int) (pointer_sized_int) fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| int64 FileOutputStream::getPositionInternal() const | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| if (fileHandle != 0) | |||
| return lseek ((int) (pointer_sized_int) fileHandle, 0, SEEK_CUR); | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return -1; | |||
| return 0; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| @@ -263937,20 +263969,25 @@ bool File::isOnRemovableDrive() const | |||
| static bool juce_isHiddenFile (const String& path) | |||
| { | |||
| #if JUCE_IOS | |||
| return File (path).getFileName().startsWithChar ('.'); | |||
| #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 | |||
| const ScopedAutoReleasePool pool; | |||
| NSNumber* hidden = nil; | |||
| NSError* err = nil; | |||
| return [[NSURL fileURLWithPath: juceStringToNS (path)] | |||
| getResourceValue: &hidden forKey: NSURLIsHiddenKey error: &err] | |||
| && [hidden boolValue]; | |||
| #else | |||
| #if JUCE_IOS | |||
| return File (path).getFileName().startsWithChar ('.'); | |||
| #else | |||
| FSRef ref; | |||
| if (! PlatformUtilities::makeFSRefFromPath (&ref, path)) | |||
| return false; | |||
| FSCatalogInfo info; | |||
| FSGetCatalogInfo (&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &info, 0, 0, 0); | |||
| if ((info.nodeFlags & kFSNodeIsDirectoryBit) != 0) | |||
| return (((FolderInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; | |||
| LSItemInfoRecord info; | |||
| return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; | |||
| return FSPathMakeRefWithOptions ((const UInt8*) path.toUTF8(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr | |||
| && LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr | |||
| && (info.flags & kLSItemInfoIsInvisible) != 0; | |||
| #endif | |||
| #endif | |||
| } | |||
| @@ -264115,7 +264152,7 @@ public: | |||
| wildCard (wildCard_), | |||
| enumerator (0) | |||
| { | |||
| ScopedAutoReleasePool pool; | |||
| const ScopedAutoReleasePool pool; | |||
| enumerator = [[[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory.getFullPathName())] retain]; | |||
| @@ -264131,7 +264168,7 @@ public: | |||
| bool* const isDir, bool* const isHidden, int64* const fileSize, | |||
| Time* const modTime, Time* const creationTime, bool* const isReadOnly) | |||
| { | |||
| ScopedAutoReleasePool pool; | |||
| const ScopedAutoReleasePool pool; | |||
| for (;;) | |||
| { | |||
| @@ -264229,28 +264266,24 @@ bool PlatformUtilities::openDocument (const String& fileName, const String& para | |||
| bool ok = false; | |||
| FSRef ref; | |||
| if (PlatformUtilities::makeFSRefFromPath (&ref, fileName)) | |||
| if (PlatformUtilities::isBundle (fileName)) | |||
| { | |||
| if (PlatformUtilities::isBundle (fileName)) | |||
| { | |||
| NSMutableArray* urls = [NSMutableArray array]; | |||
| NSMutableArray* urls = [NSMutableArray array]; | |||
| StringArray docs; | |||
| docs.addTokens (parameters, true); | |||
| for (int i = 0; i < docs.size(); ++i) | |||
| [urls addObject: juceStringToNS (docs[i])]; | |||
| StringArray docs; | |||
| docs.addTokens (parameters, true); | |||
| for (int i = 0; i < docs.size(); ++i) | |||
| [urls addObject: juceStringToNS (docs[i])]; | |||
| ok = [[NSWorkspace sharedWorkspace] openURLs: urls | |||
| withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] | |||
| options: 0 | |||
| additionalEventParamDescriptor: nil | |||
| launchIdentifiers: nil]; | |||
| } | |||
| else | |||
| { | |||
| ok = juce_launchExecutable ("\"" + fileName + "\" " + parameters); | |||
| } | |||
| ok = [[NSWorkspace sharedWorkspace] openURLs: urls | |||
| withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] | |||
| options: 0 | |||
| additionalEventParamDescriptor: nil | |||
| launchIdentifiers: nil]; | |||
| } | |||
| else if (File (fileName).exists()) | |||
| { | |||
| ok = juce_launchExecutable ("\"" + fileName + "\" " + parameters); | |||
| } | |||
| return ok; | |||
| @@ -264294,7 +264327,7 @@ OSType PlatformUtilities::getTypeOfFile (const String& filename) | |||
| #else | |||
| NSDictionary* fileDict = [[NSFileManager defaultManager] fileAttributesAtPath: juceStringToNS (filename) traverseLink: NO]; | |||
| #endif | |||
| //return (OSType) [fileDict objectForKey: NSFileHFSTypeCode]; | |||
| return [fileDict fileHFSTypeCode]; | |||
| } | |||
| @@ -64,7 +64,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 52 | |||
| #define JUCE_BUILDNUMBER 53 | |||
| /** Current Juce version number. | |||
| @@ -15470,6 +15470,10 @@ private: | |||
| int64 currentPosition, totalSize; | |||
| bool needToSeek; | |||
| void openHandle(); | |||
| void closeHandle(); | |||
| size_t readInternal (void* buffer, size_t numBytes); | |||
| FileInputStream (const FileInputStream&); | |||
| FileInputStream& operator= (const FileInputStream&); | |||
| }; | |||
| @@ -15538,8 +15542,11 @@ private: | |||
| int bufferSize, bytesInBuffer; | |||
| HeapBlock <char> buffer; | |||
| void openHandle(); | |||
| void closeHandle(); | |||
| void flushInternal(); | |||
| int64 getPositionInternal() const; | |||
| int64 setPositionInternal (int64 newPosition); | |||
| int writeInternal (const void* data, int numBytes); | |||
| FileOutputStream (const FileOutputStream&); | |||
| FileOutputStream& operator= (const FileOutputStream&); | |||
| @@ -29300,10 +29307,9 @@ public: | |||
| Before using it, you must call setStorageParameters() to give it the info | |||
| it needs to create the property files. | |||
| */ | |||
| ApplicationProperties() throw(); | |||
| ApplicationProperties(); | |||
| /** Destructor. | |||
| */ | |||
| /** Destructor. */ | |||
| ~ApplicationProperties(); | |||
| juce_DeclareSingleton (ApplicationProperties, false) | |||
| @@ -29317,7 +29323,8 @@ public: | |||
| const String& fileNameSuffix, | |||
| const String& folderName, | |||
| int millisecondsBeforeSaving, | |||
| int propertiesFileOptions) throw(); | |||
| int propertiesFileOptions, | |||
| InterProcessLock* processLock = 0); | |||
| /** Tests whether the files can be successfully written to, and can show | |||
| an error message if not. | |||
| @@ -29344,7 +29351,7 @@ public: | |||
| @see getCommonSettings | |||
| */ | |||
| PropertiesFile* getUserSettings() throw(); | |||
| PropertiesFile* getUserSettings(); | |||
| /** Returns the common settings file. | |||
| @@ -29360,7 +29367,7 @@ public: | |||
| the common settings, even if any changes to them can't be saved. | |||
| @see getUserSettings | |||
| */ | |||
| PropertiesFile* getCommonSettings (bool returnUserPropsIfReadOnly) throw(); | |||
| PropertiesFile* getCommonSettings (bool returnUserPropsIfReadOnly); | |||
| /** Saves both files if they need to be saved. | |||
| @@ -29385,11 +29392,12 @@ private: | |||
| String appName, fileSuffix, folderName; | |||
| int msBeforeSaving, options; | |||
| int commonSettingsAreReadOnly; | |||
| InterProcessLock* processLock; | |||
| ApplicationProperties (const ApplicationProperties&); | |||
| ApplicationProperties& operator= (const ApplicationProperties&); | |||
| void openFiles() throw(); | |||
| void openFiles(); | |||
| }; | |||
| #endif // __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__ | |||
| @@ -37,10 +37,11 @@ juce_ImplementSingleton (ApplicationProperties) | |||
| //============================================================================== | |||
| ApplicationProperties::ApplicationProperties() throw() | |||
| ApplicationProperties::ApplicationProperties() | |||
| : msBeforeSaving (3000), | |||
| options (PropertiesFile::storeAsBinary), | |||
| commonSettingsAreReadOnly (0) | |||
| commonSettingsAreReadOnly (0), | |||
| processLock (0) | |||
| { | |||
| } | |||
| @@ -55,13 +56,15 @@ void ApplicationProperties::setStorageParameters (const String& applicationName, | |||
| const String& fileNameSuffix, | |||
| const String& folderName_, | |||
| const int millisecondsBeforeSaving, | |||
| const int propertiesFileOptions) throw() | |||
| const int propertiesFileOptions, | |||
| InterProcessLock* processLock_) | |||
| { | |||
| appName = applicationName; | |||
| fileSuffix = fileNameSuffix; | |||
| folderName = folderName_; | |||
| msBeforeSaving = millisecondsBeforeSaving; | |||
| options = propertiesFileOptions; | |||
| processLock = processLock_; | |||
| } | |||
| bool ApplicationProperties::testWriteAccess (const bool testUserSettings, | |||
| @@ -98,7 +101,7 @@ bool ApplicationProperties::testWriteAccess (const bool testUserSettings, | |||
| } | |||
| //============================================================================== | |||
| void ApplicationProperties::openFiles() throw() | |||
| void ApplicationProperties::openFiles() | |||
| { | |||
| // You need to call setStorageParameters() before trying to get hold of the | |||
| // properties! | |||
| @@ -108,17 +111,17 @@ void ApplicationProperties::openFiles() throw() | |||
| { | |||
| if (userProps == 0) | |||
| userProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName, | |||
| false, msBeforeSaving, options); | |||
| false, msBeforeSaving, options, processLock); | |||
| if (commonProps == 0) | |||
| commonProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName, | |||
| true, msBeforeSaving, options); | |||
| true, msBeforeSaving, options, processLock); | |||
| userProps->setFallbackPropertySet (commonProps); | |||
| } | |||
| } | |||
| PropertiesFile* ApplicationProperties::getUserSettings() throw() | |||
| PropertiesFile* ApplicationProperties::getUserSettings() | |||
| { | |||
| if (userProps == 0) | |||
| openFiles(); | |||
| @@ -126,7 +129,7 @@ PropertiesFile* ApplicationProperties::getUserSettings() throw() | |||
| return userProps; | |||
| } | |||
| PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) throw() | |||
| PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) | |||
| { | |||
| if (commonProps == 0) | |||
| openFiles(); | |||
| @@ -63,10 +63,9 @@ public: | |||
| Before using it, you must call setStorageParameters() to give it the info | |||
| it needs to create the property files. | |||
| */ | |||
| ApplicationProperties() throw(); | |||
| ApplicationProperties(); | |||
| /** Destructor. | |||
| */ | |||
| /** Destructor. */ | |||
| ~ApplicationProperties(); | |||
| //============================================================================== | |||
| @@ -82,7 +81,8 @@ public: | |||
| const String& fileNameSuffix, | |||
| const String& folderName, | |||
| int millisecondsBeforeSaving, | |||
| int propertiesFileOptions) throw(); | |||
| int propertiesFileOptions, | |||
| InterProcessLock* processLock = 0); | |||
| /** Tests whether the files can be successfully written to, and can show | |||
| an error message if not. | |||
| @@ -110,7 +110,7 @@ public: | |||
| @see getCommonSettings | |||
| */ | |||
| PropertiesFile* getUserSettings() throw(); | |||
| PropertiesFile* getUserSettings(); | |||
| /** Returns the common settings file. | |||
| @@ -126,7 +126,7 @@ public: | |||
| the common settings, even if any changes to them can't be saved. | |||
| @see getUserSettings | |||
| */ | |||
| PropertiesFile* getCommonSettings (bool returnUserPropsIfReadOnly) throw(); | |||
| PropertiesFile* getCommonSettings (bool returnUserPropsIfReadOnly); | |||
| //============================================================================== | |||
| /** Saves both files if they need to be saved. | |||
| @@ -154,11 +154,12 @@ private: | |||
| String appName, fileSuffix, folderName; | |||
| int msBeforeSaving, options; | |||
| int commonSettingsAreReadOnly; | |||
| InterProcessLock* processLock; | |||
| ApplicationProperties (const ApplicationProperties&); | |||
| ApplicationProperties& operator= (const ApplicationProperties&); | |||
| void openFiles() throw(); | |||
| void openFiles(); | |||
| }; | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 52 | |||
| #define JUCE_BUILDNUMBER 53 | |||
| /** Current Juce version number. | |||
| @@ -31,26 +31,23 @@ BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| void* juce_fileOpen (const File& file, bool forWriting); | |||
| void juce_fileClose (void* handle); | |||
| int juce_fileRead (void* handle, void* buffer, int size); | |||
| int64 juce_fileSetPosition (void* handle, int64 pos); | |||
| //============================================================================== | |||
| FileInputStream::FileInputStream (const File& f) | |||
| : file (f), | |||
| fileHandle (0), | |||
| currentPosition (0), | |||
| totalSize (0), | |||
| needToSeek (true) | |||
| { | |||
| totalSize = f.getSize(); | |||
| fileHandle = juce_fileOpen (f, false); | |||
| openHandle(); | |||
| } | |||
| FileInputStream::~FileInputStream() | |||
| { | |||
| juce_fileClose (fileHandle); | |||
| closeHandle(); | |||
| } | |||
| //============================================================================== | |||
| @@ -71,7 +68,7 @@ int FileInputStream::read (void* buffer, int bytesToRead) | |||
| needToSeek = false; | |||
| } | |||
| num = juce_fileRead (fileHandle, buffer, bytesToRead); | |||
| num = readInternal (buffer, bytesToRead); | |||
| currentPosition += num; | |||
| return num; | |||
| @@ -70,6 +70,10 @@ private: | |||
| int64 currentPosition, totalSize; | |||
| bool needToSeek; | |||
| void openHandle(); | |||
| void closeHandle(); | |||
| size_t readInternal (void* buffer, size_t numBytes); | |||
| FileInputStream (const FileInputStream&); | |||
| FileInputStream& operator= (const FileInputStream&); | |||
| }; | |||
| @@ -29,41 +29,25 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "juce_FileOutputStream.h" | |||
| void* juce_fileOpen (const File& file, bool forWriting); | |||
| void juce_fileClose (void* handle); | |||
| int juce_fileWrite (void* handle, const void* buffer, int size); | |||
| int64 juce_fileSetPosition (void* handle, int64 pos); | |||
| //============================================================================== | |||
| FileOutputStream::FileOutputStream (const File& f, | |||
| const int bufferSize_) | |||
| FileOutputStream::FileOutputStream (const File& f, const int bufferSize_) | |||
| : file (f), | |||
| fileHandle (0), | |||
| currentPosition (0), | |||
| bufferSize (bufferSize_), | |||
| bytesInBuffer (0) | |||
| bytesInBuffer (0), | |||
| buffer (jmax (bufferSize_, 16)) | |||
| { | |||
| fileHandle = juce_fileOpen (f, true); | |||
| if (fileHandle != 0) | |||
| { | |||
| currentPosition = getPositionInternal(); | |||
| if (currentPosition < 0) | |||
| { | |||
| jassertfalse; | |||
| juce_fileClose (fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| buffer.malloc (jmax (bufferSize_, 16)); | |||
| openHandle(); | |||
| } | |||
| FileOutputStream::~FileOutputStream() | |||
| { | |||
| flush(); | |||
| juce_fileClose (fileHandle); | |||
| closeHandle(); | |||
| } | |||
| int64 FileOutputStream::getPosition() | |||
| @@ -86,7 +70,7 @@ void FileOutputStream::flush() | |||
| { | |||
| if (bytesInBuffer > 0) | |||
| { | |||
| juce_fileWrite (fileHandle, buffer, bytesInBuffer); | |||
| writeInternal (buffer, bytesInBuffer); | |||
| bytesInBuffer = 0; | |||
| } | |||
| @@ -106,7 +90,7 @@ bool FileOutputStream::write (const void* const src, const int numBytes) | |||
| if (bytesInBuffer > 0) | |||
| { | |||
| // flush the reservoir | |||
| const bool wroteOk = (juce_fileWrite (fileHandle, buffer, bytesInBuffer) == bytesInBuffer); | |||
| const bool wroteOk = (writeInternal (buffer, bytesInBuffer) == bytesInBuffer); | |||
| bytesInBuffer = 0; | |||
| if (! wroteOk) | |||
| @@ -121,9 +105,12 @@ bool FileOutputStream::write (const void* const src, const int numBytes) | |||
| } | |||
| else | |||
| { | |||
| const int bytesWritten = juce_fileWrite (fileHandle, src, numBytes); | |||
| currentPosition += bytesWritten; | |||
| const int bytesWritten = writeInternal (src, numBytes); | |||
| if (bytesWritten < 0) | |||
| return false; | |||
| currentPosition += bytesWritten; | |||
| return bytesWritten == numBytes; | |||
| } | |||
| } | |||
| @@ -88,8 +88,11 @@ private: | |||
| int bufferSize, bytesInBuffer; | |||
| HeapBlock <char> buffer; | |||
| void openHandle(); | |||
| void closeHandle(); | |||
| void flushInternal(); | |||
| int64 getPositionInternal() const; | |||
| int64 setPositionInternal (int64 newPosition); | |||
| int writeInternal (const void* data, int numBytes); | |||
| FileOutputStream (const FileOutputStream&); | |||
| FileOutputStream& operator= (const FileOutputStream&); | |||
| @@ -523,8 +523,15 @@ const String URL::removeEscapeChars (const String& s) | |||
| if (nextPercent < 0) | |||
| break; | |||
| juce_wchar replacementChar = (juce_wchar) result.substring (nextPercent + 1, nextPercent + 3).getHexValue32(); | |||
| result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar)); | |||
| int hexDigit1 = 0, hexDigit2 = 0; | |||
| if ((hexDigit1 = CharacterFunctions::getHexDigitValue (result [nextPercent + 1])) >= 0 | |||
| && (hexDigit2 = CharacterFunctions::getHexDigitValue (result [nextPercent + 2])) >= 0) | |||
| { | |||
| const juce_wchar replacementChar = (juce_wchar) ((hexDigit1 << 16) + hexDigit2); | |||
| result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar)); | |||
| } | |||
| ++nextPercent; | |||
| } | |||
| @@ -337,66 +337,83 @@ void File::createDirectoryInternal (const String& fileName) const | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| } | |||
| void* juce_fileOpen (const File& file, bool forWriting) | |||
| //============================================================================== | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| { | |||
| int flags = O_RDONLY; | |||
| if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) | |||
| return pos; | |||
| if (forWriting) | |||
| { | |||
| if (file.exists()) | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||
| return -1; | |||
| } | |||
| if (f != -1) | |||
| lseek (f, 0, SEEK_END); | |||
| void FileInputStream::openHandle() | |||
| { | |||
| totalSize = file.getSize(); | |||
| return (void*) f; | |||
| } | |||
| else | |||
| { | |||
| flags = O_RDWR + O_CREAT; | |||
| } | |||
| } | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644); | |||
| return (void*) open (file.getFullPathName().toUTF8(), flags, 00644); | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| } | |||
| void juce_fileClose (void* handle) | |||
| void FileInputStream::closeHandle() | |||
| { | |||
| if (handle != 0) | |||
| close ((int) (pointer_sized_int) handle); | |||
| if (fileHandle != 0) | |||
| { | |||
| close ((int) (pointer_sized_int) fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| int juce_fileRead (void* handle, void* buffer, int size) | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| if (handle != 0) | |||
| return jmax (0, (int) read ((int) (pointer_sized_int) handle, buffer, size)); | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| return 0; | |||
| } | |||
| int juce_fileWrite (void* handle, const void* buffer, int size) | |||
| //============================================================================== | |||
| void FileOutputStream::openHandle() | |||
| { | |||
| if (handle != 0) | |||
| return (int) write ((int) (pointer_sized_int) handle, buffer, size); | |||
| if (file.exists()) | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||
| return 0; | |||
| if (f != -1) | |||
| { | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| fileHandle = (void*) f; | |||
| else | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644); | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| } | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| void FileOutputStream::closeHandle() | |||
| { | |||
| if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) | |||
| return pos; | |||
| return -1; | |||
| if (fileHandle != 0) | |||
| { | |||
| close ((int) (pointer_sized_int) fileHandle); | |||
| fileHandle = 0; | |||
| } | |||
| } | |||
| int64 FileOutputStream::getPositionInternal() const | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| if (fileHandle != 0) | |||
| return lseek ((int) (pointer_sized_int) fileHandle, 0, SEEK_CUR); | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return -1; | |||
| return 0; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| @@ -405,6 +422,7 @@ void FileOutputStream::flushInternal() | |||
| fsync ((int) (pointer_sized_int) fileHandle); | |||
| } | |||
| //============================================================================== | |||
| const File juce_getExecutableFile() | |||
| { | |||
| Dl_info exeInfo; | |||
| @@ -109,20 +109,25 @@ bool File::isOnRemovableDrive() const | |||
| static bool juce_isHiddenFile (const String& path) | |||
| { | |||
| #if JUCE_IOS | |||
| return File (path).getFileName().startsWithChar ('.'); | |||
| #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 | |||
| const ScopedAutoReleasePool pool; | |||
| NSNumber* hidden = nil; | |||
| NSError* err = nil; | |||
| return [[NSURL fileURLWithPath: juceStringToNS (path)] | |||
| getResourceValue: &hidden forKey: NSURLIsHiddenKey error: &err] | |||
| && [hidden boolValue]; | |||
| #else | |||
| #if JUCE_IOS | |||
| return File (path).getFileName().startsWithChar ('.'); | |||
| #else | |||
| FSRef ref; | |||
| if (! PlatformUtilities::makeFSRefFromPath (&ref, path)) | |||
| return false; | |||
| FSCatalogInfo info; | |||
| FSGetCatalogInfo (&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &info, 0, 0, 0); | |||
| LSItemInfoRecord info; | |||
| if ((info.nodeFlags & kFSNodeIsDirectoryBit) != 0) | |||
| return (((FolderInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; | |||
| return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; | |||
| return FSPathMakeRefWithOptions ((const UInt8*) path.toUTF8(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr | |||
| && LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr | |||
| && (info.flags & kLSItemInfoIsInvisible) != 0; | |||
| #endif | |||
| #endif | |||
| } | |||
| @@ -292,7 +297,7 @@ public: | |||
| wildCard (wildCard_), | |||
| enumerator (0) | |||
| { | |||
| ScopedAutoReleasePool pool; | |||
| const ScopedAutoReleasePool pool; | |||
| enumerator = [[[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory.getFullPathName())] retain]; | |||
| @@ -308,7 +313,7 @@ public: | |||
| bool* const isDir, bool* const isHidden, int64* const fileSize, | |||
| Time* const modTime, Time* const creationTime, bool* const isReadOnly) | |||
| { | |||
| ScopedAutoReleasePool pool; | |||
| const ScopedAutoReleasePool pool; | |||
| for (;;) | |||
| { | |||
| @@ -408,28 +413,24 @@ bool PlatformUtilities::openDocument (const String& fileName, const String& para | |||
| bool ok = false; | |||
| FSRef ref; | |||
| if (PlatformUtilities::makeFSRefFromPath (&ref, fileName)) | |||
| if (PlatformUtilities::isBundle (fileName)) | |||
| { | |||
| if (PlatformUtilities::isBundle (fileName)) | |||
| { | |||
| NSMutableArray* urls = [NSMutableArray array]; | |||
| StringArray docs; | |||
| docs.addTokens (parameters, true); | |||
| for (int i = 0; i < docs.size(); ++i) | |||
| [urls addObject: juceStringToNS (docs[i])]; | |||
| ok = [[NSWorkspace sharedWorkspace] openURLs: urls | |||
| withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] | |||
| options: 0 | |||
| additionalEventParamDescriptor: nil | |||
| launchIdentifiers: nil]; | |||
| } | |||
| else | |||
| { | |||
| ok = juce_launchExecutable ("\"" + fileName + "\" " + parameters); | |||
| } | |||
| NSMutableArray* urls = [NSMutableArray array]; | |||
| StringArray docs; | |||
| docs.addTokens (parameters, true); | |||
| for (int i = 0; i < docs.size(); ++i) | |||
| [urls addObject: juceStringToNS (docs[i])]; | |||
| ok = [[NSWorkspace sharedWorkspace] openURLs: urls | |||
| withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] | |||
| options: 0 | |||
| additionalEventParamDescriptor: nil | |||
| launchIdentifiers: nil]; | |||
| } | |||
| else if (File (fileName).exists()) | |||
| { | |||
| ok = juce_launchExecutable ("\"" + fileName + "\" " + parameters); | |||
| } | |||
| return ok; | |||
| @@ -475,7 +476,7 @@ OSType PlatformUtilities::getTypeOfFile (const String& filename) | |||
| #else | |||
| NSDictionary* fileDict = [[NSFileManager defaultManager] fileAttributesAtPath: juceStringToNS (filename) traverseLink: NO]; | |||
| #endif | |||
| //return (OSType) [fileDict objectForKey: NSFileHFSTypeCode]; | |||
| return [fileDict fileHFSTypeCode]; | |||
| } | |||
| @@ -146,70 +146,77 @@ void File::createDirectoryInternal (const String& fileName) const | |||
| } | |||
| //============================================================================== | |||
| // return 0 if not possible | |||
| void* juce_fileOpen (const File& file, bool forWriting) | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| { | |||
| HANDLE h; | |||
| if (forWriting) | |||
| { | |||
| h = CreateFile (file.getFullPathName(), GENERIC_WRITE, FILE_SHARE_READ, 0, | |||
| OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = pos; | |||
| li.LowPart = SetFilePointer ((HANDLE) handle, li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails) | |||
| return li.QuadPart; | |||
| } | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| SetFilePointer (h, 0, 0, FILE_END); | |||
| else | |||
| h = 0; | |||
| } | |||
| else | |||
| { | |||
| h = CreateFile (file.getFullPathName(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, | |||
| OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | |||
| void FileInputStream::openHandle() | |||
| { | |||
| totalSize = file.getSize(); | |||
| if (h == INVALID_HANDLE_VALUE) | |||
| h = 0; | |||
| } | |||
| HANDLE h = CreateFile (file.getFullPathName(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, | |||
| OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | |||
| return h; | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| fileHandle = (void*) h; | |||
| } | |||
| void juce_fileClose (void* handle) | |||
| void FileInputStream::closeHandle() | |||
| { | |||
| CloseHandle (handle); | |||
| CloseHandle ((HANDLE) fileHandle); | |||
| } | |||
| //============================================================================== | |||
| int juce_fileRead (void* handle, void* buffer, int size) | |||
| size_t FileInputStream::readInternal (void* buffer, size_t numBytes) | |||
| { | |||
| DWORD num = 0; | |||
| ReadFile ((HANDLE) handle, buffer, size, &num, 0); | |||
| return (int) num; | |||
| if (fileHandle != 0) | |||
| { | |||
| DWORD actualNum = 0; | |||
| ReadFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| return (size_t) actualNum; | |||
| } | |||
| return 0; | |||
| } | |||
| int juce_fileWrite (void* handle, const void* buffer, int size) | |||
| //============================================================================== | |||
| void FileOutputStream::openHandle() | |||
| { | |||
| DWORD num; | |||
| WriteFile ((HANDLE) handle, buffer, size, &num, 0); | |||
| return (int) num; | |||
| HANDLE h = CreateFile (file.getFullPathName(), GENERIC_WRITE, FILE_SHARE_READ, 0, | |||
| OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| { | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = 0; | |||
| li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_END); | |||
| if (li.LowPart != INVALID_SET_FILE_POINTER) | |||
| { | |||
| fileHandle = (void*) h; | |||
| currentPosition = li.QuadPart; | |||
| } | |||
| } | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| void FileOutputStream::closeHandle() | |||
| { | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = pos; | |||
| li.LowPart = SetFilePointer ((HANDLE) handle, li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails) | |||
| return li.QuadPart; | |||
| CloseHandle ((HANDLE) fileHandle); | |||
| } | |||
| int64 FileOutputStream::getPositionInternal() const | |||
| int FileOutputStream::writeInternal (const void* buffer, int numBytes) | |||
| { | |||
| if (fileHandle == 0) | |||
| return -1; | |||
| if (fileHandle != 0) | |||
| { | |||
| DWORD actualNum = 0; | |||
| WriteFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| return (int) actualNum; | |||
| } | |||
| LARGE_INTEGER li; | |||
| li.QuadPart = 0; | |||
| li.LowPart = SetFilePointer ((HANDLE) fileHandle, 0, &li.HighPart, FILE_CURRENT); // (returns -1 if it fails) | |||
| return jmax ((int64) 0, li.QuadPart); | |||
| return 0; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| @@ -218,6 +225,7 @@ void FileOutputStream::flushInternal() | |||
| FlushFileBuffers ((HANDLE) fileHandle); | |||
| } | |||
| //============================================================================== | |||
| int64 File::getSize() const | |||
| { | |||
| WIN32_FILE_ATTRIBUTE_DATA attributes; | |||
| @@ -259,22 +267,23 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int | |||
| bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const | |||
| { | |||
| void* const h = juce_fileOpen (fullPath, true); | |||
| bool ok = false; | |||
| HANDLE h = CreateFile (fullPath, GENERIC_WRITE, FILE_SHARE_READ, 0, | |||
| OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||
| if (h != 0) | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| { | |||
| FILETIME m, a, c; | |||
| timeToFileTime (modificationTime, &m); | |||
| timeToFileTime (accessTime, &a); | |||
| timeToFileTime (creationTime, &c); | |||
| ok = SetFileTime ((HANDLE) h, | |||
| ok = SetFileTime (h, | |||
| creationTime > 0 ? &c : 0, | |||
| accessTime > 0 ? &a : 0, | |||
| modificationTime > 0 ? &m : 0) != 0; | |||
| juce_fileClose (h); | |||
| CloseHandle (h); | |||
| } | |||
| return ok; | |||