|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-7 by Raw Material Software ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the
- GNU General Public License, as published by the Free Software Foundation;
- either version 2 of the License, or (at your option) any later version.
-
- JUCE is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with JUCE; if not, visit www.gnu.org/licenses or write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ------------------------------------------------------------------------------
-
- If you'd like to release a closed-source product which uses JUCE, commercial
- licenses are also available: visit www.rawmaterialsoftware.com/juce for
- more information.
-
- ==============================================================================
- */
-
- // (This file gets included by juce_mac_NativeCode.mm, rather than being
- // compiled on its own).
- #ifdef JUCE_INCLUDED_FILE
-
- /*
- Note that a lot of methods that you'd expect to find in this file actually
- live in juce_posix_SharedCode.h!
- */
-
- //==============================================================================
- static File executableFile;
-
- const unsigned int macTimeToUnixTimeDiff = 0x7c25be90;
-
- static uint64 utcDateTimeToUnixTime (const UTCDateTime& d) throw()
- {
- if (d.highSeconds == 0 && d.lowSeconds == 0 && d.fraction == 0)
- return 0;
-
- return (((((uint64) d.highSeconds) << 32) | (uint64) d.lowSeconds) * 1000)
- + ((d.fraction * 1000) >> 16)
- - 2082844800000ll;
- }
-
- static void unixTimeToUtcDateTime (uint64 t, UTCDateTime& d) throw()
- {
- if (t != 0)
- t += 2082844800000ll;
-
- d.highSeconds = (t / 1000) >> 32;
- d.lowSeconds = (t / 1000) & (uint64) 0xffffffff;
- d.fraction = ((t % 1000) << 16) / 1000;
- }
-
- void juce_getFileTimes (const String& fileName,
- int64& modificationTime,
- int64& accessTime,
- int64& creationTime) throw()
- {
- modificationTime = 0;
- accessTime = 0;
- creationTime = 0;
-
- FSRef fileRef;
- if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName))
- {
- FSRefParam info;
- zerostruct (info);
-
- info.ref = &fileRef;
- info.whichInfo = kFSCatInfoAllDates;
-
- FSCatalogInfo catInfo;
- info.catInfo = &catInfo;
-
- if (PBGetCatalogInfoSync (&info) == noErr)
- {
- creationTime = utcDateTimeToUnixTime (catInfo.createDate);
- accessTime = utcDateTimeToUnixTime (catInfo.accessDate);
- modificationTime = utcDateTimeToUnixTime (catInfo.contentModDate);
- }
- }
- }
-
- bool juce_setFileTimes (const String& fileName,
- int64 modificationTime,
- int64 accessTime,
- int64 creationTime) throw()
- {
- FSRef fileRef;
- if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName))
- {
- FSRefParam info;
- zerostruct (info);
-
- info.ref = &fileRef;
- info.whichInfo = kFSCatInfoAllDates;
-
- FSCatalogInfo catInfo;
- info.catInfo = &catInfo;
-
- if (PBGetCatalogInfoSync (&info) == noErr)
- {
- if (creationTime != 0)
- unixTimeToUtcDateTime (creationTime, catInfo.createDate);
-
- if (modificationTime != 0)
- unixTimeToUtcDateTime (modificationTime, catInfo.contentModDate);
-
- if (accessTime != 0)
- unixTimeToUtcDateTime (accessTime, catInfo.accessDate);
-
- return PBSetCatalogInfoSync (&info) == noErr;
- }
- }
-
- return false;
- }
-
- bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
- {
- const char* const fileNameUTF8 = fileName.toUTF8();
-
- struct stat info;
- const int res = stat (fileNameUTF8, &info);
-
- bool ok = false;
-
- if (res == 0)
- {
- info.st_mode &= 0777; // Just permissions
-
- if (isReadOnly)
- info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- else
- // Give everybody write permission?
- info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
-
- ok = chmod (fileNameUTF8, info.st_mode) == 0;
- }
-
- return ok;
- }
-
- bool juce_copyFile (const String& src, const String& dst) throw()
- {
- const ScopedAutoReleasePool pool;
- NSFileManager* fm = [NSFileManager defaultManager];
-
- return [fm fileExistsAtPath: juceStringToNS (src)]
- && [fm copyPath: juceStringToNS (src)
- toPath: juceStringToNS (dst)
- handler: nil];
- }
-
- const StringArray juce_getFileSystemRoots() throw()
- {
- StringArray s;
- s.add (T("/"));
- return s;
- }
-
- //==============================================================================
- static bool isFileOnDriveType (const File* const f, const char** types) throw()
- {
- struct statfs buf;
-
- if (doStatFS (f, buf))
- {
- const String type (buf.f_fstypename);
-
- while (*types != 0)
- if (type.equalsIgnoreCase (*types++))
- return true;
- }
-
- return false;
- }
-
- bool File::isOnCDRomDrive() const throw()
- {
- static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 };
-
- return isFileOnDriveType (this, (const char**) cdTypes);
- }
-
- bool File::isOnHardDisk() const throw()
- {
- static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 };
-
- return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes));
- }
-
- bool File::isOnRemovableDrive() const throw()
- {
- const ScopedAutoReleasePool pool;
- BOOL removable = false;
-
- [[NSWorkspace sharedWorkspace]
- getFileSystemInfoForPath: juceStringToNS (getFullPathName())
- isRemovable: &removable
- isWritable: nil
- isUnmountable: nil
- description: nil
- type: nil];
-
- return removable;
- }
-
- static bool juce_isHiddenFile (const String& path) throw()
- {
- 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;
-
- return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0;
- }
-
- bool File::isHidden() const throw()
- {
- return juce_isHiddenFile (getFullPathName());
- }
-
- //==============================================================================
- const File File::getSpecialLocation (const SpecialLocationType type)
- {
- const ScopedAutoReleasePool pool;
-
- const char* resultPath = 0;
-
- switch (type)
- {
- case userHomeDirectory:
- resultPath = nsStringToJuce (NSHomeDirectory());
- break;
-
- case userDocumentsDirectory:
- resultPath = "~/Documents";
- break;
-
- case userDesktopDirectory:
- resultPath = "~/Desktop";
- break;
-
- case userApplicationDataDirectory:
- resultPath = "~/Library";
- break;
-
- case commonApplicationDataDirectory:
- resultPath = "/Library";
- break;
-
- case globalApplicationsDirectory:
- resultPath = "/Applications";
- break;
-
- case userMusicDirectory:
- resultPath = "~/Music";
- break;
-
- case userMoviesDirectory:
- resultPath = "~/Movies";
- break;
-
- case tempDirectory:
- {
- File tmp (T("~/Library/Caches/") + executableFile.getFileNameWithoutExtension());
-
- tmp.createDirectory();
- return tmp.getFullPathName();
- }
-
- case currentExecutableFile:
- return executableFile;
-
- case currentApplicationFile:
- {
- const File parent (executableFile.getParentDirectory());
-
- return parent.getFullPathName().endsWithIgnoreCase (T("Contents/MacOS"))
- ? parent.getParentDirectory().getParentDirectory()
- : executableFile;
- }
-
- default:
- jassertfalse // unknown type?
- break;
- }
-
- if (resultPath != 0)
- return File (PlatformUtilities::convertToPrecomposedUnicode (resultPath));
-
- return File::nonexistent;
- }
-
- void juce_setCurrentExecutableFileName (const String& filename) throw()
- {
- executableFile = File::getCurrentWorkingDirectory()
- .getChildFile (PlatformUtilities::convertToPrecomposedUnicode (filename));
- }
-
- void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId) throw()
- {
- const ScopedAutoReleasePool pool;
-
- NSBundle* b = [NSBundle bundleWithIdentifier: juceStringToNS (bundleId)];
-
- if (b != nil)
- executableFile = nsStringToJuce ([b executablePath]);
- }
-
- //==============================================================================
- const File File::getCurrentWorkingDirectory() throw()
- {
- char buf [2048];
- getcwd (buf, sizeof(buf));
-
- return File (PlatformUtilities::convertToPrecomposedUnicode (buf));
- }
-
- bool File::setAsCurrentWorkingDirectory() const throw()
- {
- return chdir (getFullPathName().toUTF8()) == 0;
- }
-
- //==============================================================================
- const String File::getVersion() const throw()
- {
- const ScopedAutoReleasePool pool;
- String result;
-
- NSBundle* bundle = [NSBundle bundleWithPath: juceStringToNS (getFullPathName())];
-
- if (bundle != 0)
- {
- NSDictionary* info = [bundle infoDictionary];
-
- if (info != 0)
- {
- NSString* name = [info valueForKey: @"CFBundleShortVersionString"];
-
- if (name != nil)
- result = nsStringToJuce (name);
- }
- }
-
- return result;
- }
-
- //==============================================================================
- const File File::getLinkedTarget() const throw()
- {
- FSRef ref;
- Boolean targetIsAFolder, wasAliased;
-
- if (PlatformUtilities::makeFSRefFromPath (&ref, getFullPathName())
- && (FSResolveAliasFileWithMountFlags (&ref, true, &targetIsAFolder, &wasAliased, 0) == noErr)
- && wasAliased)
- {
- return File (PlatformUtilities::makePathFromFSRef (&ref));
- }
-
- return *this;
- }
-
- //==============================================================================
- bool File::moveToTrash() const throw()
- {
- if (! exists())
- return true;
-
- const ScopedAutoReleasePool pool;
-
- NSString* p = juceStringToNS (getFullPathName());
-
- return [[NSWorkspace sharedWorkspace]
- performFileOperation: NSWorkspaceRecycleOperation
- source: [p stringByDeletingLastPathComponent]
- destination: @""
- files: [NSArray arrayWithObject: [p lastPathComponent]]
- tag: nil ];
- }
-
- //==============================================================================
- struct FindFileStruct
- {
- String parentDir, wildCard;
- DIR* dir;
-
- bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize,
- Time* const modTime, Time* const creationTime, bool* const isReadOnly) throw()
- {
- const char* const wildCardUTF8 = wildCard.toUTF8();
-
- for (;;)
- {
- struct dirent* const de = readdir (dir);
-
- if (de == 0)
- break;
-
- if (fnmatch (wildCardUTF8, de->d_name, 0) == 0)
- {
- result = String::fromUTF8 ((const uint8*) de->d_name);
-
- const String path (parentDir + result);
-
- if (isDir != 0 || fileSize != 0)
- {
- struct stat info;
- const bool statOk = juce_stat (path, info);
-
- if (isDir != 0)
- *isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0));
-
- if (isHidden != 0)
- *isHidden = (de->d_name[0] == '.')
- || juce_isHiddenFile (path);
-
- if (fileSize != 0)
- *fileSize = statOk ? info.st_size : 0;
- }
-
- if (modTime != 0 || creationTime != 0)
- {
- int64 m, a, c;
- juce_getFileTimes (path, m, a, c);
-
- if (modTime != 0)
- *modTime = m;
-
- if (creationTime != 0)
- *creationTime = c;
- }
-
- if (isReadOnly != 0)
- *isReadOnly = ! juce_canWriteToFile (path);
-
- return true;
- }
- }
-
- return false;
- }
- };
-
- // returns 0 on failure
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
- bool* isDir, bool* isHidden, int64* fileSize, Time* modTime,
- Time* creationTime, bool* isReadOnly) throw()
- {
- DIR* const d = opendir (directory.toUTF8());
-
- if (d != 0)
- {
- FindFileStruct* const ff = new FindFileStruct();
- ff->parentDir = directory;
-
- if (!ff->parentDir.endsWithChar (File::separator))
- ff->parentDir += File::separator;
-
- ff->wildCard = wildCard;
- ff->dir = d;
-
- if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly))
- {
- return ff;
- }
- else
- {
- firstResultFile = String::empty;
- isDir = false;
- closedir (d);
- delete ff;
- }
- }
-
- return 0;
- }
-
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw()
- {
- FindFileStruct* const ff = (FindFileStruct*) handle;
-
- if (ff != 0)
- return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
-
- return false;
- }
-
- void juce_findFileClose (void* handle) throw()
- {
- FindFileStruct* const ff = (FindFileStruct*)handle;
-
- if (ff != 0)
- {
- closedir (ff->dir);
- delete ff;
- }
- }
-
- //==============================================================================
- bool juce_launchExecutable (const String& pathAndArguments) throw()
- {
- char* const argv[4] = { "/bin/sh", "-c", (char*) (const char*) pathAndArguments, 0 };
-
- const int cpid = fork();
-
- if (cpid == 0)
- {
- // Child process
- if (execve (argv[0], argv, 0) < 0)
- exit (0);
- }
- else
- {
- if (cpid < 0)
- return false;
- }
-
- return true;
- }
-
- bool juce_launchFile (const String& fileName,
- const String& parameters) throw()
- {
- const ScopedAutoReleasePool pool;
-
- if (parameters.isEmpty())
- return [[NSWorkspace sharedWorkspace] openFile: juceStringToNS (fileName)];
-
- bool ok = false;
-
- FSRef ref;
- if (PlatformUtilities::makeFSRefFromPath (&ref, 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: nil
- additionalEventParamDescriptor: nil
- launchIdentifiers: nil];
- }
- else
- {
- ok = juce_launchExecutable (T("\"") + fileName + T("\" ") + parameters);
- }
- }
-
- return ok;
- }
-
- //==============================================================================
- bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path)
- {
- return FSPathMakeRef ((const UInt8*) path.toUTF8(), destFSRef, 0) == noErr;
- }
-
- const String PlatformUtilities::makePathFromFSRef (FSRef* file)
- {
- uint8 path [2048];
- zeromem (path, sizeof (path));
-
- String result;
-
- if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr)
- result = String::fromUTF8 (path);
-
- return PlatformUtilities::convertToPrecomposedUnicode (result);
- }
-
- //==============================================================================
- OSType PlatformUtilities::getTypeOfFile (const String& filename)
- {
- const ScopedAutoReleasePool pool;
- return NSHFSTypeCodeFromFileType (NSHFSTypeOfFile (juceStringToNS (filename)));
- }
-
- bool PlatformUtilities::isBundle (const String& filename)
- {
- const ScopedAutoReleasePool pool;
- return [[NSWorkspace sharedWorkspace] isFilePackageAtPath: juceStringToNS (filename)];
- }
-
- #endif
|