Vuo  2.4.0
VuoFileUtilitiesCocoa.mm
Go to the documentation of this file.
1
10#include "VuoFileUtilities.hh"
12#include "VuoException.hh"
13#include "VuoStringUtilities.hh"
14
15#include <AppKit/AppKit.h>
16#include <sys/utsname.h>
17
24{
25 NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:filePath.c_str()]];
26 if (!url)
27 throw VuoException("Couldn't move file '" + filePath + "' to the trash: Couldn't create NSURL.");
28
29 NSError *error = nil;
30 bool success = [[NSFileManager defaultManager] trashItemAtURL:url resultingItemURL:nil error:&error];
31 if (!success)
32 throw VuoException(string("Couldn't move file '" + filePath + "' to the trash: ") + [[error localizedDescription] UTF8String]);
33}
34
46{
47 NSString *pathNS = [NSString stringWithUTF8String:path.c_str()];
48 if (!pathNS)
49 throw VuoException("Path \"" + path + "\" isn't a valid UTF-8 string.");
50
51 NSURL *baseURL = [NSURL fileURLWithPath:pathNS isDirectory:YES];
52 if (!baseURL)
53 throw VuoException("Path \"" + path + "\" isn't a valid directory.");
54
55 NSURL *temporaryDirectoryURL = nil;
56 while (true)
57 {
58 NSError *error = nil;
59 temporaryDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSItemReplacementDirectory
60 inDomain:NSUserDomainMask
61 appropriateForURL:baseURL
62 create:YES
63 error:&error];
64 if (error)
65 {
66 NSError *underlyingError = [[error userInfo] objectForKey:NSUnderlyingErrorKey];
67 if ([[underlyingError domain] isEqualToString:NSPOSIXErrorDomain]
68 && [underlyingError code] == ENOENT)
69 {
70 // File not found; go up a directory and try again.
71 baseURL = [baseURL URLByDeletingLastPathComponent];
72 }
73 else
74 throw VuoException((string("Couldn't get a temp folder: ") + [[error localizedDescription] UTF8String]).c_str());
75 }
76 else if (!temporaryDirectoryURL)
77 throw VuoException("Couldn't get a temp folder for path \"" + path + "\".");
78 else
79 break;
80 }
81
82 return [[temporaryDirectoryURL path] UTF8String];
83}
84
93{
94 NSString *pathNS = [NSString stringWithUTF8String:path.c_str()];
95 if (!pathNS)
96 throw VuoException("Path \"" + path + "\" isn't a valid UTF-8 string.");
97
98 NSDictionary *fileAttributes;
99 while (true)
100 {
101 NSError *error = nil;
102 fileAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:pathNS error:&error];
103 if (error)
104 {
105 NSError *underlyingError = [[error userInfo] objectForKey:NSUnderlyingErrorKey];
106 if ([[underlyingError domain] isEqualToString:NSPOSIXErrorDomain]
107 && [underlyingError code] == ENOENT)
108 {
109 // File not found; go up a directory and try again.
110 pathNS = [pathNS stringByDeletingLastPathComponent];
111 }
112 else
113 throw VuoException((string("Couldn't get information about path: ") + [[error localizedDescription] UTF8String]).c_str());
114 }
115 else if (!fileAttributes)
116 throw VuoException("Couldn't get information about path \"" + path + "\".");
117 else
118 break;
119 }
120
121 unsigned long long freeSpace = [fileAttributes[NSFileSystemFreeSize] longLongValue];
122 return freeSpace;
123}
124
130void VuoFileUtilitiesCocoa_focusProcess(pid_t pid, bool force)
131{
132 NSRunningApplication *compositionApp = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
133 [compositionApp activateWithOptions: NSApplicationActivateAllWindows
134 | (force ? NSApplicationActivateIgnoringOtherApps : 0)];
135}
136
141{
142 return NSProcessInfo.processInfo.operatingSystemVersion.majorVersion;
143}
144
149{
150 return NSProcessInfo.processInfo.operatingSystemVersion.minorVersion;
151}
152
157{
158 struct utsname un;
159 if (uname(&un) < 0)
160 throw VuoException("Couldn't look up the system's architecture: %s", strerror(errno));
161
162 return un.machine;
163}
164
170{
171 CFStringRef path = CFStringCreateWithCString(NULL, filePath.c_str(), kCFStringEncodingUTF8);
172 CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, true);
173 CFErrorRef error;
174 if (!CFURLSetResourcePropertyForKey(url, kCFURLIsPackageKey, kCFBooleanTrue, &error))
175 {
176 CFStringRef errorString = CFErrorCopyDescription(error);
177 VUserLog("Warning: Couldn't set kCFURLIsPackageKey on this bundle: %s", VuoStringUtilities::makeFromCFString(errorString).c_str());
178 CFRelease(errorString);
179 }
180 CFRelease(url);
181 CFRelease(path);
182}
183
187static CFURLRef VuoFileUtilitiesCocoa_getCFURL(const string &path)
188{
189 if (path.empty())
190 return nullptr;
191
192 CFStringRef cfpath = CFStringCreateWithCString(nullptr, path.c_str(), kCFStringEncodingUTF8);
193 if (!cfpath)
194 throw VuoException("Path \"" + path + "\" isn't a valid UTF-8 string.");
195 VuoDefer(^{ CFRelease(cfpath); });
196
197 CFURLRef url = CFURLCreateWithFileSystemPath(nullptr, cfpath, kCFURLPOSIXPathStyle, true);
198 if (!url)
199 throw VuoException("Path \"" + path + "\" isn't a valid POSIX path.");
200
201 return url;
202}
203
207static CFDataRef VuoFileUtilitiesCocoa_getMacAliasData(const string &path)
208{
209 CFURLRef url = VuoFileUtilitiesCocoa_getCFURL(path);
210 if (!url)
211 return nullptr;
212 VuoDefer(^{ CFRelease(url); });
213
214 return CFURLCreateBookmarkDataFromFile(nullptr, url, nullptr);
215}
216
222bool VuoFileUtilitiesCocoa_isMacAlias(const string &path)
223{
224 CFDataRef aliasData = VuoFileUtilitiesCocoa_getMacAliasData(path);
225 if (!aliasData)
226 return false;
227
228 CFRelease(aliasData);
229 return true;
230}
231
238{
239 CFDataRef aliasData = VuoFileUtilitiesCocoa_getMacAliasData(path);
240 if (!aliasData)
241 throw VuoException("Path \"" + path + "\" isn't a macOS Alias.");
242 VuoDefer(^{ CFRelease(aliasData); });
243
244 CFURLRef url = VuoFileUtilitiesCocoa_getCFURL(path);
245 VuoDefer(^{ CFRelease(url); });
246
247 Boolean isStale = false;
248 CFErrorRef error = nullptr;
249 CFURLRef resolvedURL = CFURLCreateByResolvingBookmarkData(nullptr, aliasData, kCFBookmarkResolutionWithoutUIMask, url, nullptr, &isStale, &error);
250 if (!resolvedURL)
251 {
252 CFStringRef desc = CFErrorCopyDescription(error);
253 VuoDefer(^{ CFRelease(desc); });
254 throw VuoException("Path \"" + path + "\" is a macOS Alias, but it couldn't be resolved: \"" + VuoStringUtilities::makeFromCFString(desc) + "\" (isStale=" + std::to_string(isStale) + ")");
255 }
256 VuoDefer(^{ CFRelease(resolvedURL); });
257
258 CFStringRef resolvedPath = CFURLCopyFileSystemPath(resolvedURL, kCFURLPOSIXPathStyle);
259 if (!resolvedPath)
260 throw VuoException("Path \"" + path + "\" is a macOS Alias, but it resolved to something that isn't a POSIX path (\"" + VuoStringUtilities::makeFromCFString(((NSURL *)resolvedURL).description) + "\").");
261 VuoDefer(^{ CFRelease(resolvedPath); });
262
263 return VuoStringUtilities::makeFromCFString(resolvedPath);
264}