iPlug2 - C++ Audio Plug-in Framework
IPlugPaths.mm
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
17 #include "IPlugPaths.h"
18 #include <string>
19 #include <map>
20 
21 #if defined(OS_IOS) || defined(OS_MAC)
22 #import <Foundation/Foundation.h>
23 #include <TargetConditionals.h>
24 #endif
25 
26 #ifdef IGRAPHICS_METAL
27 extern std::map<std::string, void*> gTextureMap;
28 #endif
29 
30 BEGIN_IPLUG_NAMESPACE
31 
32 #ifdef OS_MAC
33 void HostPath(WDL_String& path, const char* bundleID)
34 {
35  @autoreleasepool
36  {
37  NSBundle* pBundle = [NSBundle bundleWithIdentifier: [NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
38 
39  if (pBundle)
40  {
41  NSString* pPath = [pBundle executablePath];
42  if (pPath)
43  {
44  path.Set([pPath UTF8String]);
45  }
46  }
47  }
48 }
49 
50 void PluginPath(WDL_String& path, PluginIDType bundleID)
51 {
52  @autoreleasepool
53  {
54  NSBundle* pBundle = [NSBundle bundleWithIdentifier: [NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
55 
56  if (pBundle)
57  {
58  NSString* pPath = [[pBundle bundlePath] stringByDeletingLastPathComponent];
59 
60  if (pPath)
61  {
62  path.Set([pPath UTF8String]);
63  path.Append("/");
64  }
65  }
66  }
67 }
68 
69 void BundleResourcePath(WDL_String& path, PluginIDType bundleID)
70 {
71  @autoreleasepool
72  {
73  NSBundle* pBundle = [NSBundle bundleWithIdentifier:[NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
74  NSString* pResPath = [pBundle resourcePath];
75 
76  path.Set([pResPath UTF8String]);
77  }
78 }
79 
80 void DesktopPath(WDL_String& path)
81 {
82  NSArray* pPaths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
83  NSString* pDesktopDirectory = [pPaths objectAtIndex:0];
84  path.Set([pDesktopDirectory UTF8String]);
85 }
86 
87 void UserHomePath(WDL_String& path)
88 {
89  NSString* pHomeDir = NSHomeDirectory();
90  path.Set([pHomeDir UTF8String]);
91 }
92 
93 void VST3PresetsPath(WDL_String& path, const char* mfrName, const char* pluginName, bool isSystem)
94 {
95  NSArray* pPaths;
96  if (isSystem)
97  pPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES);
98  else
99  pPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
100 
101  NSString* pApplicationSupportDirectory = [pPaths objectAtIndex:0];
102  path.SetFormatted(MAX_MACOS_PATH_LEN, "%s/Audio/Presets/%s/%s/", [pApplicationSupportDirectory UTF8String], mfrName, pluginName);
103 }
104 
105 void INIPath(WDL_String& path, const char* pluginName)
106 {
107  AppSupportPath(path, false);
108  path.AppendFormatted(MAX_MACOS_PATH_LEN, "/%s", pluginName);
109 }
110 
111 void AppSupportPath(WDL_String& path, bool isSystem)
112 {
113  NSArray* pPaths;
114 
115  if (isSystem)
116  pPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSSystemDomainMask, YES);
117  else
118  pPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
119 
120  NSString *pApplicationSupportDirectory = [pPaths objectAtIndex:0];
121  path.Set([pApplicationSupportDirectory UTF8String]);
122 }
123 
124 void SandboxSafeAppSupportPath(WDL_String& path, const char* appGroupID)
125 {
126  NSArray* pPaths = NSSearchPathForDirectoriesInDomains(NSMusicDirectory, NSUserDomainMask, YES);
127  NSString* pUserMusicDirectory = [pPaths objectAtIndex:0];
128  path.Set([pUserMusicDirectory UTF8String]);
129 }
130 
131 bool GetResourcePathFromBundle(const char* fileName, const char* searchExt, WDL_String& fullPath, const char* bundleID)
132 {
133  @autoreleasepool
134  {
135  const char* ext = fileName+strlen(fileName)-1;
136  while (ext >= fileName && *ext != '.') --ext;
137  ++ext;
138 
139  bool isCorrectType = !strcasecmp(ext, searchExt);
140 
141  NSBundle* pBundle = [NSBundle bundleWithIdentifier:[NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
142  NSString* pFile = [[[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
143 
144  if (isCorrectType && pBundle && pFile)
145  {
146  NSString* pPath = [pBundle pathForResource:pFile ofType:[NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding]];
147 
148  if (!pPath)
149  {
150  pFile = [[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] stringByDeletingPathExtension];
151  pPath = [pBundle pathForResource:pFile ofType:[NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding]];
152  }
153 
154  if (pPath)
155  {
156  if([[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
157  {
158  fullPath.Set([pPath cString]);
159  return true;
160  }
161  }
162  }
163 
164  fullPath.Set("");
165  return false;
166  }
167 }
168 
169 bool GetResourcePathFromSharedLocation(const char* fileName, const char* searchExt, WDL_String& fullPath, const char* subfolder)
170 {
171  @autoreleasepool
172  {
173  const char* ext = fileName+strlen(fileName)-1;
174  while (ext >= fileName && *ext != '.') --ext;
175  ++ext;
176 
177  bool isCorrectType = !strcasecmp(ext, searchExt);
178 
179  NSString* pExt = [NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding];
180  NSString* pFile = [[[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
181 
182  if (isCorrectType && pFile)
183  {
184  WDL_String musicFolder;
185  SandboxSafeAppSupportPath(musicFolder);
186 
187  if(subfolder)
188  {
189  NSString* pPluginName = [NSString stringWithCString: subfolder encoding:NSUTF8StringEncoding];
190  NSString* pMusicLocation = [NSString stringWithCString: musicFolder.Get() encoding:NSUTF8StringEncoding];
191  NSString* pPath = [[[[pMusicLocation stringByAppendingPathComponent:pPluginName] stringByAppendingPathComponent:@"Resources"] stringByAppendingPathComponent: pFile] stringByAppendingPathExtension:pExt];
192 
193  if([[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
194  {
195  fullPath.Set([pPath cString]);
196  return true;
197  }
198  }
199  }
200 
201  fullPath.Set("");
202  return false;
203  }
204 }
205 
206 EResourceLocation LocateResource(const char* name, const char* type, WDL_String& result, const char* bundleID, void*, const char* sharedResourcesSubPath)
207 {
208  if(CStringHasContents(name))
209  {
210  // first check this bundle
211  if(GetResourcePathFromBundle(name, type, result, bundleID))
212  return EResourceLocation::kAbsolutePath;
213 
214  // then check ~/Music/sharedResourcesSubPath, which is a shared folder that can be accessed from app sandbox
215  if(GetResourcePathFromSharedLocation(name, type, result, sharedResourcesSubPath))
216  return EResourceLocation::kAbsolutePath;
217 
218  // finally check name, which might be a full path - if the plug-in is trying to load a resource at runtime (e.g. skin-able UI)
219  NSString* pPath = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
220 
221  if([[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
222  {
223  result.Set([pPath UTF8String]);
224  return EResourceLocation::kAbsolutePath;
225  }
226  }
227  return EResourceLocation::kNotFound;
228 }
229 
230 bool AppIsSandboxed()
231 {
232  NSString* pHomeDir = NSHomeDirectory();
233 
234  if ([pHomeDir containsString:@"Library/Containers/"])
235  return true;
236  else
237  return false;
238 }
239 
240 #elif defined OS_IOS
241 #pragma mark - IOS
242 
243 void HostPath(WDL_String& path, const char* bundleID)
244 {
245 }
246 
247 void PluginPath(WDL_String& path, PluginIDType bundleID)
248 {
249 }
250 
251 void BundleResourcePath(WDL_String& path, PluginIDType bundleID)
252 {
253  NSBundle* pBundle = [NSBundle mainBundle];
254 
255  if(IsAuv3AppExtension())
256  pBundle = [NSBundle bundleWithPath: [[[pBundle bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent]];
257 
258  path.Set([[pBundle resourcePath] UTF8String]);
259 }
260 
261 void AppSupportPath(WDL_String& path, bool isSystem)
262 {
263 }
264 
265 void SandboxSafeAppSupportPath(WDL_String& path, const char* appGroupID)
266 {
267  NSFileManager* mgr = [NSFileManager defaultManager];
268  NSURL* url = [mgr containerURLForSecurityApplicationGroupIdentifier:[NSString stringWithUTF8String:appGroupID]];
269  path.Set([[url path] UTF8String]);
270 }
271 
272 void DesktopPath(WDL_String& path)
273 {
274 }
275 
276 void VST3PresetsPath(WDL_String& path, const char* mfrName, const char* pluginName, bool isSystem)
277 {
278  path.Set("");
279 }
280 
281 void INIPath(WDL_String& path, const char* pluginName)
282 {
283  path.Set("");
284 }
285 
286 bool GetResourcePathFromBundle(const char* fileName, const char* searchExt, WDL_String& fullPath, const char* bundleID)
287 {
288  @autoreleasepool
289  {
290  const char* ext = fileName+strlen(fileName)-1;
291  while (ext >= fileName && *ext != '.') --ext;
292  ++ext;
293 
294  bool isCorrectType = !strcasecmp(ext, searchExt);
295 
296  bool isAppExtension = false;
297 
298  NSBundle* pBundle = [NSBundle mainBundle];
299 
300  if([[pBundle bundleIdentifier] containsString:@"AUv3"])
301  isAppExtension = true;
302 
303  if(isAppExtension)
304  pBundle = [NSBundle bundleWithIdentifier:[NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
305 
306  NSString* pFile = [[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] stringByDeletingPathExtension];
307  NSString* pExt = [NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding];
308 
309  if (isCorrectType && pBundle && pFile)
310  {
311  NSString* pRootPath;
312 
313  if(isAppExtension)
314  pRootPath = [[[pBundle bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
315  else
316  {
317 #ifdef TARGET_OS_MACCATALYST
318  pRootPath = [pBundle resourcePath];
319 #else
320  pRootPath = [pBundle bundlePath];
321 #endif
322  }
323 
324  NSString* pPath = [[[[pRootPath stringByAppendingString:@"/"] stringByAppendingString:pFile] stringByAppendingString: @"."] stringByAppendingString:pExt];
325 
326  if (pPath)
327  {
328  fullPath.Set([pPath cStringUsingEncoding:NSUTF8StringEncoding]);
329  return true;
330  }
331  }
332 
333  fullPath.Set("");
334  return false;
335  }
336 }
337 
338 EResourceLocation LocateResource(const char* name, const char* type, WDL_String& result, const char* bundleID, void*, const char*)
339 {
340  if(CStringHasContents(name))
341  {
342 #ifdef IGRAPHICS_METAL
343  auto itr = gTextureMap.find(name);
344 
345  if (itr != gTextureMap.end())
346  {
347  result.Set(name);
348  return EResourceLocation::kPreloadedTexture;
349  }
350 #endif
351 
352  if(GetResourcePathFromBundle(name, type, result, bundleID))
353  return EResourceLocation::kAbsolutePath;
354  }
355 
356  return EResourceLocation::kNotFound;
357 }
358 
359 bool AppIsSandboxed()
360 {
361  return true;
362 }
363 
364 bool IsAuv3AppExtension()
365 {
366  return ([[[NSBundle mainBundle] bundleIdentifier] containsString:@"AUv3"]);
367 }
368 
369 #endif
370 
371 END_IPLUG_NAMESPACE
bool AppIsSandboxed()
Common paths useful for plug-ins.
void BundleResourcePath(WDL_String &path, PluginIDType pExtra=0)
Get the path to the plug-in bundle resource path.
void SandboxSafeAppSupportPath(WDL_String &path, const char *appGroupID="")
void AppSupportPath(WDL_String &path, bool isSystem=false)
void UserHomePath(WDL_String &path)
EResourceLocation LocateResource(const char *fileNameOrResID, const char *type, WDL_String &result, const char *bundleID, void *pHInstance, const char *sharedResourcesSubPath)
Find the absolute path of a resource based on it&#39;s file name (e.g.
void INIPath(WDL_String &path, const char *pluginName)
Get the path to the folder where the App&#39;s settings.ini file is stored.
void VST3PresetsPath(WDL_String &path, const char *mfrName, const char *pluginName, bool isSystem=true)
void HostPath(WDL_String &path, const char *bundleID=0)
Get the path to the host binary.
void PluginPath(WDL_String &path, PluginIDType pExtra)
Get the path to the plug-in binary.
void DesktopPath(WDL_String &path)