return [[result copy] autorelease];
}
+- (BOOL)_doesBundleInfo:(NSDictionary *)_bundleInfo path:(NSString *)_path
+ provideResource:(id)_resourceName ofType:(NSString *)_type
+ rnKeys:(NSArray *)_rnKeys
+ resourceSelector:(NGBundleResourceSelector)_selector context:(void *)_context
+{
+ NSEnumerator *providedResources;
+ NSDictionary *info;
+
+ providedResources =
+ [[(NSDictionary *)[_bundleInfo objectForKey:@"provides"]
+ objectForKey:_type] objectEnumerator];
+ if (providedResources == nil) return NO;
+
+ /* scan provide array */
+ while ((info = [providedResources nextObject])) {
+ if (_rnKeys != nil) {
+ if (!_doesInfoMatch(_rnKeys, _resourceName, info))
+ continue;
+ }
+ else {
+ NSString *name;
+
+ name = [[(NSDictionary *)info objectForKey:@"name"] stringValue];
+ if (name == nil) continue;
+ if (![name isEqualToString:_resourceName]) continue;
+ }
+
+ if (_selector != NULL) {
+ if (!_selector(_resourceName, _type, _path, info, self, _context))
+ continue;
+ }
+
+ /* all conditions applied (found) */
+ return YES;
+ }
+ return NO;
+}
+
+- (NSString *)pathOfLoadedBundleProvidingResource:(id)_resourceName
+ ofType:(NSString *)_type
+ resourceSelector:(NGBundleResourceSelector)_selector context:(void *)_context
+{
+ NSMapEnumerator menum;
+ NSString *path;
+ NSDictionary *bundleInfo;
+ NSArray *rnKeys;
+
+ rnKeys = ([_resourceName respondsToSelector:@selector(objectForKey:)])
+ ? [_resourceName allKeys]
+ : nil;
+
+ menum = NSEnumerateMapTable(self->pathToBundleInfo);
+ while (NSNextMapEnumeratorPair(&menum, (void *)&path, (void *)&bundleInfo)) {
+ if (debugOn) {
+ NSLog(@"check loaded bundle for resource %@: %@", _resourceName,
+ path);
+ }
+
+ if ([self _doesBundleInfo:bundleInfo path:path
+ provideResource:_resourceName ofType:_type rnKeys:rnKeys
+ resourceSelector:_selector context:_context])
+ /* strip bundle-info.plist name */
+ return [path stringByDeletingLastPathComponent];
+ }
+
+ return nil;
+}
+
- (NSString *)pathForBundleProvidingResource:(id)_resourceName
ofType:(NSString *)_type
resourceSelector:(NGBundleResourceSelector)_selector
context:(void *)_context
{
- NSFileManager *fm = [NSFileManager defaultManager];
+ /* main path lookup method */
+ // TODO: this method seriously needs some refactoring
+ NSFileManager *fm;
NSEnumerator *e;
NSString *path;
NSArray *rnKeys = nil;
int rnKeyCount = 0;
-
+
+ if (debugOn) {
+ NSLog(@"BM LOOKUP path (%d bundles loaded): %@ / %@",
+ NSCountMapTable(self->loadedBundles), _resourceName, _type);
+ }
+
+ /* look in loaded bundles */
+
+ path = [self pathOfLoadedBundleProvidingResource:_resourceName ofType:_type
+ resourceSelector:_selector context:_context];
+ if (path != nil) return path;
+
+ /* look in filesystem */
+
if ([_resourceName respondsToSelector:@selector(objectForKey:)]) {
rnKeys = [_resourceName allKeys];
rnKeyCount = [rnKeys count];
}
+ fm = [NSFileManager defaultManager];
e = [self->bundleSearchPaths objectEnumerator];
- while ((path = [e nextObject])) {
- BOOL isDir = NO;
+ while ((path = [e nextObject]) != nil) {
+ NSEnumerator *dir;
+ BOOL isDir = NO;
+ NSString *tmp;
+ id info = nil;
- if ([fm fileExistsAtPath:path isDirectory:&isDir]) {
- NSString *tmp;
- id info = nil;
+ if (![fm fileExistsAtPath:path isDirectory:&isDir])
+ continue;
+
+ if (!isDir) continue;
+
+ /* check whether an appropriate bundle is contained in 'path' */
+
+ dir = [[fm directoryContentsAtPath:path] objectEnumerator];
+ while ((tmp = [dir nextObject])) {
+ NSDictionary *bundleInfo = nil;
+ NSString *infoPath;
- if (!isDir) continue;
+ tmp = [path stringByAppendingPathComponent:tmp];
+ infoPath = [self makeBundleInfoPath:tmp];
- /* check whether an appropriate bundle is contained in 'path' */
- {
- NSEnumerator *dir;
-
- dir = [[fm directoryContentsAtPath:path] objectEnumerator];
- while ((tmp = [dir nextObject])) {
- NSDictionary *bundleInfo = nil;
- NSEnumerator *providedResources = nil;
- NSString *infoPath;
- id info;
-
- tmp = [path stringByAppendingPathComponent:tmp];
- infoPath = [self makeBundleInfoPath:tmp];
-
- if (debugOn)
- NSLog(@"check path path=%@ info=%@", tmp, infoPath);
-
- if ((bundleInfo=NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
- if (![fm fileExistsAtPath:infoPath])
- continue;
-
- bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
- }
- if (debugOn) {
- NSLog(@"found info for path=%@ info=%@: %@",
- tmp, infoPath, bundleInfo);
- }
+ if (debugOn)
+ NSLog(@"check path path=%@ info=%@", tmp, infoPath);
- providedResources =
- [[(NSDictionary *)[bundleInfo objectForKey:@"provides"]
- objectForKey:_type]
- objectEnumerator];
- if (providedResources == nil) continue;
-
- // scan provide array
- while ((info = [providedResources nextObject])) {
- if (rnKeys) {
- if (!_doesInfoMatch(rnKeys, _resourceName, info))
- continue;
- }
- else {
- NSString *name;
+ if ((bundleInfo = NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
+ if (![fm fileExistsAtPath:infoPath])
+ continue;
- name = [[(NSDictionary *)info objectForKey:@"name"] stringValue];
- if (name == nil) continue;
- if (![name isEqualToString:_resourceName]) continue;
- }
-
- if (_selector) {
- if (!_selector(_resourceName, _type, tmp, info, self, _context))
- continue;
- }
- /* all conditions applied */
- return tmp;
- }
- }
+ bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
}
-
- /* check for direct match */
+ if (debugOn)
+ NSLog(@"found info for path=%@ info=%@: %@", tmp,infoPath,bundleInfo);
- tmp = [self makeBundleInfoPath:path];
+ if ([self _doesBundleInfo:bundleInfo path:tmp
+ provideResource:_resourceName ofType:_type rnKeys:rnKeys
+ resourceSelector:_selector context:_context])
+ return tmp;
+ }
+
+ /* check for direct match */
+
+ tmp = [self makeBundleInfoPath:path];
- if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
+ if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
if ([fm fileExistsAtPath:tmp])
info = [self _loadBundleInfoAtExistingPath:tmp];
else if (debugOn) {
NSLog(@"WARNING(%s): did not find direct path '%@'",
__PRETTY_FUNCTION__, tmp);
}
- }
+ }
- if (info) {
+ if (info != nil) {
// direct match (a bundle was specified in the path)
NSEnumerator *providedResources;
NSDictionary *provides;
/* all conditions applied */
return tmp;
}
- }
}
}
return nil;
}
-- (NSBundle *)bundleProvidingResource:(id)_resourceName
- ofType:(NSString *)_resourceType
-{
+- (NSBundle *)bundleProvidingResource:(id)_name ofType:(NSString *)_type {
NSString *bp;
- bp = [self pathForBundleProvidingResource:_resourceName
- ofType:_resourceType
+ if (debugOn) NSLog(@"BM LOOKUP: %@ / %@", _name, _type);
+
+ bp = [self pathForBundleProvidingResource:_name
+ ofType:_type
resourceSelector:NULL context:nil];
if ([bp length] == 0) {
#if (NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY) && HEAVY_DEBUG
NSLog(@"%s: found no resource '%@' of type '%@' ...",
__PRETTY_FUNCTION__, _resourceName, _resourceType);
#endif
+ if (debugOn) NSLog(@" did not find: %@ / %@", _name, _type);
return nil;
}
+ if (debugOn) NSLog(@" FOUND: %@", bp);
return [self bundleWithPath:bp];
}
objectForKey:_resourceType];
}
+- (void)_addRegisteredProvidedResourcesOfType:(NSString *)_type
+ toSet:(NSMutableSet *)_result
+{
+ NSMapEnumerator menum;
+ NSString *path;
+ NSDictionary *bundleInfo;
+
+ menum = NSEnumerateMapTable(self->pathToBundleInfo);
+ while (NSNextMapEnumeratorPair(&menum, (void *)&path, (void *)&bundleInfo)) {
+ NSArray *providedResources;
+
+ if (debugOn)
+ NSLog(@"check loaded bundle for resource types %@: %@", _type, path);
+
+ providedResources =
+ [(NSDictionary *)[bundleInfo objectForKey:@"provides"]
+ objectForKey:_type];
+ if (providedResources == nil) continue;
+
+ [_result addObjectsFromArray:providedResources];
+ }
+}
+
- (NSArray *)providedResourcesOfType:(NSString *)_resourceType {
NSMutableSet *result = nil;
NSFileManager *fm = [NSFileManager defaultManager];
result = [NSMutableSet setWithCapacity:128];
+ /* scan loaded bundles */
+
+ [self _addRegisteredProvidedResourcesOfType:_resourceType toSet:result];
+
+ /* scan all bundle search paths */
+
e = [self->bundleSearchPaths objectEnumerator];
while ((path = [e nextObject])) {
- BOOL isDir = NO;
+ NSEnumerator *dir;
+ BOOL isDir = NO;
+ NSString *tmp;
+ id info = nil;
- if ([fm fileExistsAtPath:path isDirectory:&isDir]) {
- NSString *tmp;
- id info = nil;
- if (!isDir) continue;
+ if (![fm fileExistsAtPath:path isDirectory:&isDir])
+ continue;
+ if (!isDir) continue;
- /* check whether an appropriate bundle is contained in 'path' */
- {
- NSEnumerator *dir;
+ /* check whether an appropriate bundle is contained in 'path' */
- dir = [[fm directoryContentsAtPath:path] objectEnumerator];
- while ((tmp = [dir nextObject])) {
- NSDictionary *bundleInfo = nil;
- NSArray *providedResources = nil;
- NSString *infoPath;
+ dir = [[fm directoryContentsAtPath:path] objectEnumerator];
+ while ((tmp = [dir nextObject])) {
+ NSDictionary *bundleInfo = nil;
+ NSArray *providedResources = nil;
+ NSString *infoPath;
- tmp = [path stringByAppendingPathComponent:tmp];
- infoPath = [self makeBundleInfoPath:tmp];
-
- //NSLog(@" info path: %@", tmp);
-
- if ((bundleInfo = NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
- if (![fm fileExistsAtPath:infoPath])
- continue;
-
- bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
- }
+ tmp = [path stringByAppendingPathComponent:tmp];
+ infoPath = [self makeBundleInfoPath:tmp];
+
+#if 0
+ NSLog(@" info path: %@", tmp);
+#endif
- providedResources =
- [(NSDictionary *)[bundleInfo objectForKey:@"provides"]
- objectForKey:_resourceType];
- if (providedResources == nil) continue;
+ if ((bundleInfo = NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
+ if (![fm fileExistsAtPath:infoPath])
+ continue;
- [result addObjectsFromArray:providedResources];
- }
+ bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
}
- /* check for direct match */
+ providedResources =
+ [(NSDictionary *)[bundleInfo objectForKey:@"provides"]
+ objectForKey:_resourceType];
+ if (providedResources == nil) continue;
+
+ [result addObjectsFromArray:providedResources];
+ }
+
+ /* check for direct match */
- tmp = [self makeBundleInfoPath:path];
+ tmp = [self makeBundleInfoPath:path];
- if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
- if ([fm fileExistsAtPath:tmp])
- info = [self _loadBundleInfoAtExistingPath:tmp];
- }
+ if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
+ if ([fm fileExistsAtPath:tmp])
+ info = [self _loadBundleInfoAtExistingPath:tmp];
+ }
- if (info) {
- // direct match (a bundle was specified in the path)
- NSArray *providedResources;
- NSDictionary *provides;
+ if (info != nil) {
+ // direct match (a bundle was specified in the path)
+ NSArray *providedResources;
+ NSDictionary *provides;
- provides = [(NSDictionary *)info objectForKey:@"provides"];
- providedResources = [provides objectForKey:_resourceType];
- info = nil;
- if (providedResources == nil) continue;
+ provides = [(NSDictionary *)info objectForKey:@"provides"];
+ providedResources = [provides objectForKey:_resourceType];
+ info = nil;
+ if (providedResources == nil) continue;
- [result addObjectsFromArray:providedResources];
- }
+ [result addObjectsFromArray:providedResources];
}
}
return [result allObjects];