-
Notifications
You must be signed in to change notification settings - Fork 285
/
NSAppleScript_BLTRExtensions.m
213 lines (179 loc) · 7.91 KB
/
NSAppleScript_BLTRExtensions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
//
// NSAppleScript_BLTRExtensions.m
// Quicksilver
//
// Created by Alcor on Thu Aug 28 2003.
// Copyright (c) 2003 Blacktree. All rights reserved.
//
#import "NSAppleScript_BLTRExtensions.h"
#import "NSData_RangeExtensions.h"
#import "NDScript.h"
#import "NDResourceFork.h"
#import <Carbon/Carbon.h>
#import "NSAppleEventDescriptor+NDCoercion.h"
@interface NSAppleScript (NSPrivate)
+ (struct ComponentInstanceRecord *)_defaultScriptingComponent;
- (OSAID) _compiledScriptID;
@end
@interface NSScriptObjectSpecifier (NSScriptObjectSpecifierPrivate) // Private Foundation Methods
+ (id)_objectSpecifierFromDescriptor:(NSAppleEventDescriptor *)descriptor inCommandConstructionContext:(id)context;
- (NSAppleEventDescriptor *)_asDescriptor;
@end
@interface NSAEDescriptorTranslator : NSObject // Private Foundation Class
+ (id)sharedAEDescriptorTranslator;
- (NSAppleEventDescriptor *)descriptorByTranslatingObject:(id)object ofType:(id)type inSuite:(id)suite;
- (id)objectByTranslatingDescriptor:(NSAppleEventDescriptor *)descriptor toType:(id)type inSuite:(id)suite;
- (void)registerTranslator:(id)translator selector:(SEL) selector toTranslateFromClass:(Class) class;
- (void)registerTranslator:(id)translator selector:(SEL) selector toTranslateFromDescriptorType:(NSUInteger) type;
@end
@implementation NSAppleScript (Constructors)
+ (NSAppleScript *)scriptWithContentsOfFile:(NSString *)path {
return [[[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil] autorelease];
}
+ (NSAppleScript *)scriptWithContentsOfResource:(NSString *)path inBundle:(NSBundle *)bundle {
return [[[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[bundle pathForResource:[path stringByDeletingPathExtension] ofType:[path pathExtension]]] error:nil] autorelease];
}
@end
@implementation NSAppleScript (Subroutine)
- (NSAppleEventDescriptor *)executeSubroutine:(NSString *)name arguments:(id)arguments error:(NSDictionary **)errorInfo {
// NSLog(@"Handlers: %@", [self handlers]);
NSAppleEventDescriptor* event;
NSAppleEventDescriptor* targetAddress;
NSAppleEventDescriptor* subroutineDescriptor;
// NSAppleEventDescriptor* arguments;
if (arguments && ![arguments isKindOfClass:[NSAppleEventDescriptor class]])
arguments = [NSAppleEventDescriptor descriptorWithObjectAPPLE:arguments];
if (arguments && [arguments descriptorType] != cAEList) {
NSAppleEventDescriptor *argumentList = [NSAppleEventDescriptor listDescriptor];
[argumentList insertDescriptor:arguments atIndex:[arguments numberOfItems] +1];
arguments = argumentList;
}
NSInteger pid = [[NSProcessInfo processInfo] processIdentifier];
targetAddress = [[NSAppleEventDescriptor alloc] initWithDescriptorType:typeKernelProcessID bytes:&pid length:sizeof(pid)];
event = [[NSAppleEventDescriptor alloc] initWithEventClass:kASAppleScriptSuite eventID:kASSubroutineEvent targetDescriptor:targetAddress returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
subroutineDescriptor = [NSAppleEventDescriptor descriptorWithString:name];
[event setParamDescriptor:subroutineDescriptor forKeyword:keyASSubroutineName];
if (arguments) [event setParamDescriptor:arguments forKeyword:keyDirectObject];
NSAppleEventDescriptor *desc = [self executeAppleEvent:event error:errorInfo];
[event release];
[targetAddress release];
return desc;
}
- (NSAppleEventDescriptor *)executeAppleEventWithEventClass:(AEEventClass)aEventClass eventID:(AEEventID)aEventID arguments:(id)arguments error:(NSDictionary **)errorInfo {
return nil;
}
- (NSData *)data {
AEDesc theDesc = { typeNull, NULL } ;
NSData * theData = nil;
{ if ( [self isCompiled] && (noErr == OSAStore( [NSAppleScript _defaultScriptingComponent] , [self _compiledScriptID] , typeOSAGenericStorage, kOSAModeNull, &theDesc ) ) )
theData = [[NSAppleEventDescriptor descriptorWithAEDescNoCopy:&theDesc] data];
}
return theData;
}
- (BOOL)storeInFile:(NSString *)path {
FSRef ref;
FSPathMakeRef((const UInt8 *)[path UTF8String] , &ref, NULL );
OSAStoreFile([NSAppleScript _defaultScriptingComponent] , [self _compiledScriptID] , typeOSAGenericStorage, kOSAModeNull,
&ref);
// [[self data] writeToFile:(NSString *)path atomically:flag];
return YES;
}
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag {
[[self data] writeToFile:path atomically:flag];
return YES;
}
/*
-(NSArray *)handlers {
NSLog(@"id %d", _compiledScriptID);
NSArray * theNamesArray = nil;
AEDescList theNamesDescList;
if ( OSAGetHandlerNames (OpenDefaultComponent( kOSAComponentType, kAppleScriptSubtype ), kOSAModeNull, _compiledScriptID, &theNamesDescList ) == noErr ) {
theNamesArray = [NDAppleScriptObject objectForAEDesc: &theNamesDescList];
AEDisposeDesc( &theNamesDescList );
}
return theNamesArray;
}
*/
@end
@implementation NSAppleEventDescriptor (CocoaConversion)
+ (NSAppleEventDescriptor *)descriptorWithObjectAPPLE:(id)object {
return [[NSAEDescriptorTranslator sharedAEDescriptorTranslator] descriptorByTranslatingObject:object ofType:nil inSuite:nil];
}
- (id)objectValueAPPLE {
return [[NSAEDescriptorTranslator sharedAEDescriptorTranslator] objectByTranslatingDescriptor:self toType:nil inSuite:nil];
}
+ (NSAppleEventDescriptor *)XdescriptorWithObject:(id)object {
NSAppleEventDescriptor *descriptorObject = nil;
if ([object isKindOfClass:[NSArray class]]) {
descriptorObject = [NSAppleEventDescriptor listDescriptor];
NSUInteger i;
for (i = 0; i < [(NSArray *)object count]; i++) {
[descriptorObject insertDescriptor:[NSAppleEventDescriptor descriptorWithObject:[object objectAtIndex:i]] atIndex:i+1];
}
return descriptorObject;
} else if ([object isKindOfClass:[NSString class]]) {
return [NSAppleEventDescriptor descriptorWithString:object];
} else if ([object isKindOfClass:[NSNumber class]]) {
return [NSAppleEventDescriptor descriptorWithInt32:[object integerValue]];
} else if ([object isKindOfClass:[NSAppleEventDescriptor class]]) {
return object;
} else if ([object isKindOfClass:[NSNull class]]) {
return [NSAppleEventDescriptor nullDescriptor];
} else {
return nil;
}
}
- (id)xobjectValue {
// NSLog(@"Convert type: %@", NSFileTypeForHFSTypeCode([self descriptorType]) );
switch ([self descriptorType]) {
case kAENullEvent:
return nil;
case cAEList: {
NSMutableArray *array = [NSMutableArray arrayWithCapacity:[self numberOfItems]];
NSInteger i;
id theItem;
for (i = 0; i<[self numberOfItems]; i++) {
theItem = [[self descriptorAtIndex:i+1] objectValue];
if (theItem) [array addObject:theItem];
}
return array;
}
case cBoolean:
return [NSNumber numberWithBool:[self booleanValue]];
// if (typeAERecord == [self descriptorType]) {
// return [NSNumber numberWithBool:[self booleanValue]];
// }
default:
return [self stringValue];
}
return nil;
}
+ (NSAppleEventDescriptor *)descriptorWithPath:(NSString *)path {
if (!path) return 0;
// AppleEvent event, reply;
OSErr err;
FSRef fileRef;
AliasHandle fileAlias;
err = FSPathMakeRef((const UInt8 *)[path fileSystemRepresentation] , &fileRef, NULL);
if (err != noErr) return nil;
err = FSNewAliasMinimal(&fileRef, &fileAlias);
if (err != noErr) return nil;
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeAlias bytes:fileAlias length:sizeof(*fileAlias)];
}
@end
@implementation NSAppleScript (FilePeeking)
+ (NSArray *)validHandlersFromArray:(NSArray *)array inScriptFile:(NSString *)path {
NSData *scriptData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:path] options:NSDataReadingMappedAlways error:nil];
if (![scriptData length]) {
NDResourceFork *resource = [NDResourceFork resourceForkForReadingAtPath:path];
scriptData = [resource dataForType:'scpt' Id:128];
[resource closeFile];
}
NSMutableArray *validHandlers = [NSMutableArray array];
for (NSString *handler in array) {
if ([scriptData offsetOfData:[handler dataUsingEncoding:NSASCIIStringEncoding]] != NSNotFound)
[validHandlers addObject:handler];
}
return validHandlers;
}
@end