diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 5276be9f3d..05725cb5af 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -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]; } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 2cbe15f21c..18456bff44 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -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 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__ diff --git a/src/application/juce_ApplicationProperties.cpp b/src/application/juce_ApplicationProperties.cpp index 4b3e662589..b477f24a47 100644 --- a/src/application/juce_ApplicationProperties.cpp +++ b/src/application/juce_ApplicationProperties.cpp @@ -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(); diff --git a/src/application/juce_ApplicationProperties.h b/src/application/juce_ApplicationProperties.h index 8d9a985ef3..0ed512c7aa 100644 --- a/src/application/juce_ApplicationProperties.h +++ b/src/application/juce_ApplicationProperties.h @@ -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(); }; diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 793cea0fbf..37b7ff535f 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -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. diff --git a/src/io/files/juce_FileInputStream.cpp b/src/io/files/juce_FileInputStream.cpp index 4556f6ea14..20508f32c0 100644 --- a/src/io/files/juce_FileInputStream.cpp +++ b/src/io/files/juce_FileInputStream.cpp @@ -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; diff --git a/src/io/files/juce_FileInputStream.h b/src/io/files/juce_FileInputStream.h index 10a9909f2c..0f08f51562 100644 --- a/src/io/files/juce_FileInputStream.h +++ b/src/io/files/juce_FileInputStream.h @@ -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&); }; diff --git a/src/io/files/juce_FileOutputStream.cpp b/src/io/files/juce_FileOutputStream.cpp index 40383bdc75..3774e583cb 100644 --- a/src/io/files/juce_FileOutputStream.cpp +++ b/src/io/files/juce_FileOutputStream.cpp @@ -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; } } diff --git a/src/io/files/juce_FileOutputStream.h b/src/io/files/juce_FileOutputStream.h index e15dd4bf5b..ef11fcd6a1 100644 --- a/src/io/files/juce_FileOutputStream.h +++ b/src/io/files/juce_FileOutputStream.h @@ -88,8 +88,11 @@ private: int bufferSize, bytesInBuffer; HeapBlock 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&); diff --git a/src/io/network/juce_URL.cpp b/src/io/network/juce_URL.cpp index a384e9d820..e4ddcc35a0 100644 --- a/src/io/network/juce_URL.cpp +++ b/src/io/network/juce_URL.cpp @@ -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; } diff --git a/src/native/common/juce_posix_SharedCode.h b/src/native/common/juce_posix_SharedCode.h index 01d28a71f0..86e32bee1d 100644 --- a/src/native/common/juce_posix_SharedCode.h +++ b/src/native/common/juce_posix_SharedCode.h @@ -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; diff --git a/src/native/mac/juce_mac_Files.mm b/src/native/mac/juce_mac_Files.mm index 01fa1ce62d..e9947d00df 100644 --- a/src/native/mac/juce_mac_Files.mm +++ b/src/native/mac/juce_mac_Files.mm @@ -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]; } diff --git a/src/native/windows/juce_win32_Files.cpp b/src/native/windows/juce_win32_Files.cpp index a927858f1d..88454000c0 100644 --- a/src/native/windows/juce_win32_Files.cpp +++ b/src/native/windows/juce_win32_Files.cpp @@ -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;