root/branches/perian-1.1/ECQTComponent.m

Revision 887, 10.4 kB (checked in by astrange, 4 months ago)

Merge trunk to 1.1 branch.

Line 
1 //
2 //  ECQTComponent.m
3 //  QTManager
4 //
5 //  Created by Ken on 12/15/07.
6 //  Copyright 2007 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ECQTComponent.h"
10
11 #define DISABLED_SUFFIX @" (Disabled)"
12
13 @implementation ECQTComponent
14
15 NSMutableDictionary*    mCache = 0;
16
17 #define SET_KEY(key, value) [mParameters setObject:(value) forKey:(key)]
18 #define SET_KEY_BOOLVAL(key, value) [mParameters setObject:[NSNumber numberWithBool:(value)] forKey:(key)]
19 #define GET_KEY(key) [mParameters objectForKey:(key)]
20 #define GET_KEY_BOOLVAL(key) (([mParameters objectForKey:(key)]) ? [[mParameters objectForKey:(key)] boolValue] : NO)
21
22 +(id)componentWithPath:(NSString*)path
23 {
24         return [[[ECQTComponent alloc] initWithPath:path] autorelease];
25 }
26
27 -(id)initWithPath:(NSString*)path
28 {
29 //      NSLog(@"init with %@", path);
30 #warning TODO(durin42) There's a lot of caching here - I don't think we really need it to be efficient.
31         if (!mCache)
32         {
33                 mCache = [[NSMutableDictionary dictionary] retain];
34         }
35
36         NSDictionary* cachedParams = [mCache objectForKey:path];
37        
38         if (cachedParams)
39         {
40                 mParameters = [cachedParams retain];           
41         }
42         else
43         {
44                 mParameters = [[NSMutableDictionary dictionary] retain];
45                
46                 SET_KEY(@"Location", path);
47                 [self setComponentInfo];
48         }
49
50         SET_KEY_BOOLVAL(@"Enabled", !([path rangeOfString:DISABLED_SUFFIX].length > 0));
51
52         [self setComponentScope];
53
54         return self;
55 }
56
57
58 -(void)setComponentInfo
59 {
60         short resFile = 0;
61
62         NSString* filePath = GET_KEY(@"Location");
63        
64         BOOL isDirectory = NO;
65         NSFileManager* fm = [NSFileManager defaultManager];
66         NSURL* url = [NSURL fileURLWithPath:filePath];
67         if (![fm fileExistsAtPath:filePath isDirectory:&isDirectory])
68         {
69                 return;
70         }
71                        
72         CFBundleRef bundleRef = 0;
73         if (isDirectory)
74         {
75                 bundleRef = CFBundleCreate(0, (CFURLRef)url);
76
77                 if (!bundleRef)
78                         return;
79                
80                 resFile = CFBundleOpenBundleResourceMap(bundleRef);
81                
82                 NSString* cfvers = (NSString*)CFBundleGetValueForInfoDictionaryKey(bundleRef, kCFBundleVersionKey);
83                 if (cfvers)
84                         SET_KEY(@"Version", cfvers);
85                
86         }
87         else
88         {
89                 FSRef ref;
90                 if (CFURLGetFSRef((CFURLRef)url,&ref))
91                 {
92                         resFile = FSOpenResFile(&ref, fsRdPerm);
93                 }
94         }
95
96         NSString* name = [NSString stringWithString:@"Unknown"];
97        
98         short saveRes = CurResFile();
99         if (resFile > 0)
100         {
101                 UseResFile(resFile);
102                 int x = 0;
103                 int count = CountResources('thng');
104                 NSString* firstType = 0;
105                 BOOL mixed = false;
106                
107                 NSString* singletype = 0;
108                 NSMutableArray* allTypes = [NSMutableArray array];
109                 NSMutableArray* allNames = [NSMutableArray array];
110                
111                 for (x = 1; x <= count; x++)
112                 {
113                        
114                         Handle data = Get1IndResource('thng', x);
115                         if (data)
116                         {
117                                 ComponentResource* thng = (ComponentResource*)*data;
118
119                                 ComponentDescription desc;
120
121                                 memcpy(&desc, thng, sizeof(ComponentDescription));
122
123                                 Handle nameData = Get1Resource(thng->componentName.resType, thng->componentName.resID);
124
125                                 if (firstType == 0 && singletype)
126                                         firstType = [singletype copy];
127                                
128                                 if (desc.componentType == 'vdig')
129                                         singletype = @"Camera Driver";
130                                 else if (desc.componentType == 'sgpn')
131                                         singletype = @"Camera Driver";
132                                 else if (desc.componentType == 'spit')
133                                         singletype = @"Exporter";
134                                 else if (desc.componentType == 'eat ')
135                                         singletype = @"Media Importer";
136                                 else if (desc.componentType == 'imdc')
137                                         singletype = @"Image Codec";
138                                 else if (desc.componentType == 'imco')
139                                         singletype = @"Image Codec";
140                                 else if (desc.componentType == 'sdec')
141                                         singletype = @"Sound Decoder";
142                                 else if (desc.componentType == 'scom')
143                                         singletype = @"Sound Compressor";
144                                 else if (desc.componentType == 'aenc')
145                                         singletype = @"Audio Encoder";
146                                 else if (desc.componentType == 'adec')
147                                         singletype = @"Audio Decoder";
148                                 else if (desc.componentType == 'aunt')
149                                         singletype = @"Audio Unit";
150                                 else if (desc.componentType == 'grip')
151                                         singletype = @"Graphics Importer";
152                                 else if (desc.componentType == 'shlr')
153                                         singletype = @"Sound Handler";
154                                 else if (desc.componentType == 'dhlr')
155                                         singletype = @"Data Handler";
156                                 else if (desc.componentType == 'mhlr')
157                                         singletype = @"Media Handler";
158                                 else if (desc.componentType == 'tsvc')
159                                         singletype = @"Text Service";
160                                 else if (desc.componentType == 'osa ')
161                                         singletype = @"Scripting Component";
162                                 else if (desc.componentType == 'crnc')
163                                         singletype = @"Cruncher";
164                                 else if (desc.componentType == 'ihlr')
165                                         singletype = @"Isochronous Handler";
166                                 else if (desc.componentType == 'acca')
167                                         singletype = @"Audio Context";
168                                 else if (desc.componentType == 'sift')
169                                         singletype = @"Sound Converter";
170                                 else
171                                         singletype = @"Unknown";
172
173                                 if (firstType && singletype && ![firstType isEqualToString:singletype])
174                                 {
175                                         mixed = true;
176                                 }
177
178                                 if (![allTypes containsObject:singletype])
179                                         [allTypes addObject:singletype];
180                                
181         //                      NSLog(@"%@", singletype);
182                                 if (nameData && *nameData)
183                                 {
184                                         name = [[[NSString alloc] initWithBytes:(*nameData) + 1 length:**nameData encoding:NSUTF8StringEncoding] autorelease];
185                                         if (!name)
186                                                 name = [[[NSString alloc] initWithBytes:(*nameData) + 1 length:**nameData encoding:NSUnicodeStringEncoding] autorelease];
187                                 }       
188
189                                 if (![allNames containsObject:name])
190                                         [allNames addObject:name];
191                                
192                                 if (GetHandleSize(data) >= (Size)sizeof(ExtComponentResource))
193                                 {
194
195                                         SET_KEY_BOOLVAL(@"Extended", YES);
196                                         NSMutableArray* arches = [NSMutableArray array];
197                                         ExtComponentResource* extthng = (ExtComponentResource*)*data;
198                                         if (extthng)
199                                         {
200                                                 SET_KEY(@"ComponentVersion", [NSNumber numberWithInt:extthng->componentVersion]);
201                                                 SET_KEY(@"RegisterFlags", [NSNumber numberWithInt:extthng->componentRegisterFlags]);
202                                                 int i= 0;
203                                                 for (i = 0; i < extthng->count; i++)
204                                                 {
205                                                         ComponentPlatformInfo* info = &(extthng->platformArray[i]);
206                        
207                                                         NSMutableDictionary* pinfo = [NSMutableDictionary dictionary];
208                                                        
209                                                         [pinfo setObject:[NSNumber numberWithInt:info->platformType] forKey:@"Platform"];
210                                                         [pinfo setObject:[NSNumber numberWithInt:info->componentFlags] forKey:@"Flags"];
211
212                                                         [arches addObject:pinfo];
213                                                 }
214                                                 SET_KEY(@"Arches", arches);
215                                         }
216                                 }
217                         }
218
219                 }
220
221                 name = [GET_KEY(@"Location") lastPathComponent];
222                 if ([[name pathExtension] isEqualToString:@"component"])
223                          name = [name stringByDeletingPathExtension];
224                
225                 SET_KEY(@"Name", name);
226                 SET_KEY(@"Type", singletype);
227                 SET_KEY(@"Types", allTypes);
228                 SET_KEY(@"Names", allNames);
229        
230                 [mCache setObject:mParameters forKey:filePath];
231         }
232        
233         UseResFile(saveRes);
234
235         if (isDirectory && bundleRef && resFile >= 0)
236         {
237                 CFBundleCloseBundleResourceMap(bundleRef, resFile);
238         }
239         else if (!isDirectory && resFile >= 0)
240         {
241                 CloseResFile(resFile);
242         }
243 }
244
245
246
247 -(void)setComponentScope
248 {
249         NSString* mLocation = GET_KEY(@"Location");
250
251         if ([mLocation hasPrefix:@"/System/"])
252                 mWhere = componentIsSystem;
253         else if ([mLocation hasPrefix:@"/Library/"])
254                 mWhere = componentIsGlobal;
255         else if ([mLocation hasPrefix:@"/Users/"])
256                 mWhere = componentIsLocal;
257 }
258
259 -(void)dealloc
260 {
261         if (mParameters)
262                 [mParameters release];
263
264         [super dealloc];
265 }
266
267 -(NSString*)name
268 {
269         return GET_KEY(@"Name");
270 }
271
272 -(NSString*)location
273 {
274         return GET_KEY(@"Location");
275 }
276
277 -(NSString*)version
278 {
279         if (GET_KEY(@"Version"))
280                 return GET_KEY(@"Version");
281         else
282                 return GET_KEY(@"ComponentVersion");   
283 }
284
285 -(NSString*)type
286 {
287         return GET_KEY(@"Type");
288 }
289
290 -(NSString*)types
291 {
292         return [GET_KEY(@"Types") componentsJoinedByString:@", "];
293 }
294
295 -(NSString*)names
296 {
297         return [GET_KEY(@"Names") componentsJoinedByString:@", "];
298 }
299
300 -(NSString*)whereSort
301 {
302         if (mWhere == componentIsLocal)
303                 return @"Home";
304         else if (mWhere == componentIsGlobal)
305                 return @"Library";
306         else if (mWhere == componentIsSystem)
307                 return @"System";
308        
309         return @"";
310 }
311
312 -(NSString*)enabledSort
313 {
314         return [NSString stringWithFormat:@"%d", GET_KEY_BOOLVAL(@"Enabled")];
315 }
316
317 -(componentScope)isWhere
318 {
319         return mWhere;
320 }
321
322 -(BOOL)extended
323 {
324         return GET_KEY_BOOLVAL(@"Extended");
325 }
326
327 -(NSNumber*)compVersion
328 {
329         return GET_KEY(@"ComponentVersion");
330 }
331
332 -(NSNumber*)compFlags
333 {
334         return GET_KEY(@"RegisterFlags");
335 }
336
337 -(NSString*)arches
338 {
339         NSArray* arches = GET_KEY(@"Arches");
340         NSMutableString* archesString = [NSMutableString string];
341         int x= 0;
342         int count = [arches count];
343         for (x = 0; x < count; x++)
344         {
345                 NSDictionary* pinfo = [arches objectAtIndex:x];
346                 int platform = [[pinfo objectForKey:@"Platform"] intValue];
347                
348                 if (platform ==platformPowerPCNativeEntryPoint)
349                         [archesString appendFormat:@" PowerPC"];
350                 else if (platform ==platformIA32NativeEntryPoint)
351                         [archesString appendFormat:@" Intel"];
352                 else
353                         [archesString appendFormat:@" %d", x];
354         }       
355         return archesString;
356 }
357
358
359
360 -(NSImage*)where
361 {
362         NSImage* image = 0;
363         if (mWhere == componentIsLocal)
364                 image = [NSImage imageNamed:@"user"];
365         else if (mWhere == componentIsGlobal)
366                 image = [NSImage imageNamed:@"global"];
367         else if (mWhere == componentIsSystem)
368                 image = [NSImage imageNamed:@"system"];
369                
370         return image;
371 }
372
373 -(NSNumber*)componentEnabled
374 {
375         return GET_KEY(@"Enabled");
376 }
377
378 -(void)setEnabled:(BOOL)enabled
379 {               
380         NSString* mLocation = GET_KEY(@"Location");
381         BOOL mEnabled = GET_KEY_BOOLVAL(@"Enabled");
382        
383         NSString* componentFile = [mLocation lastPathComponent];
384         NSString* containingFolderPath = [mLocation stringByDeletingLastPathComponent];
385         NSString* containingFolder = [containingFolderPath lastPathComponent];
386         NSString* containingFolderFolderPath = [containingFolderPath stringByDeletingLastPathComponent];
387         NSString* otherFolder = 0;
388         if (mEnabled)
389                 otherFolder = [containingFolderFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@", containingFolder, DISABLED_SUFFIX]];
390         else
391         {
392                 NSRange range = [containingFolder rangeOfString:DISABLED_SUFFIX];
393                 if (range.length > 0)
394                         otherFolder = [containingFolderFolderPath stringByAppendingPathComponent:[containingFolder substringToIndex:range.location]];
395         }
396        
397         if (!otherFolder)
398                 return;
399                
400         NSFileManager* fm = [NSFileManager defaultManager];
401         BOOL successful = YES;
402         if (![fm fileExistsAtPath:otherFolder isDirectory:nil])
403         {
404                 successful = [fm createDirectoryAtPath:otherFolder attributes:0];
405         }
406         NSString* destFile = [otherFolder stringByAppendingPathComponent:componentFile];
407         if (successful)
408                 successful = [fm movePath:mLocation toPath:destFile handler:self];
409
410         SET_KEY(@"Location", destFile);
411
412         SET_KEY_BOOLVAL(@"Enabled", enabled);
413 }
414
415
416 - (BOOL)fileManager:(NSFileManager *)manager shouldProceedAfterError:(NSDictionary *)errorInfo
417 {
418         NSLog(@"QTComponent Manager: Error: %@", errorInfo);
419         return YES;
420 }
421
422 - (void)fileManager:(NSFileManager *)manager willProcessPath:(NSString *)path
423 {
424 }
425
426 @end
Note: See TracBrowser for help on using the browser.