ITOSA looks like NSAppleScript, almost. It works quite well now, except
[ITFoundation.git] / ITOSAScript.m
1 /*
2  *      ITFoundation
3  *      ITOSAScript
4  *          An extended NSAppleScript that allows any OSA language.
5  *
6  *      Original Author : Kent Sutherland <ksutherland@ithinksw.com>
7  *      Responsibility : Kent Sutherland <ksutherland@ithinksw.com>
8  *      Responsibility : Joseph Spiros <joseph.spiros@ithinksw.com>
9  *
10  *      Copyright (c) 2002 - 2004 iThink Software.
11  *      All Rights Reserved
12  *
13  */
14
15 /*
16 Script Subtypes:
17     kAppleScriptSubtype - AppleScript (Default)
18     'Jscr' - JavaScript (if installed)
19 */
20
21 #import "ITOSAScript.h"
22 #import "ITOSAComponent.h"
23
24 @implementation ITOSAScript
25
26 - (id)init
27 {
28     if ( (self = [super init]) ) {
29         _source = nil;
30     }
31     return self;
32 }
33
34 - (id)initWithContentsOfFile:(NSString *)path
35 {
36     if ( (self = [super init]) ) {
37         _source = [[NSString alloc] initWithContentsOfFile:path];
38         _scriptID = kOSANullScript;
39     }
40     return self;
41 }
42
43 - (id)initWithSource:(NSString *)source
44 {
45     if ( (self = [super init]) ) {
46         _source = [source copy];
47         _scriptID = kOSANullScript;
48     }
49     return self;
50 }
51
52 - (void)dealloc
53 {
54     if (_scriptID != kOSANullScript) {
55         OSADispose([_component componentInstance], _scriptID);
56     }
57     
58     [_source release];
59     [super dealloc];
60 }
61
62 - (NSString *)source
63 {
64     return _source;
65 }
66
67 - (ITOSAComponent *)component
68 {
69     return _component;
70 }
71
72 - (void)setComponent:(ITOSAComponent *)newComponent
73 {
74     _component = newComponent;
75 }
76
77 - (BOOL)compileAndReturnError:(NSDictionary **)errorInfo
78 {
79     if ([_component componentInstance] == nil) {
80         //Set the error dictionary
81         return NO;
82     }
83     
84     AEDesc moof;
85     AECreateDesc(typeChar, [_source cString], [_source cStringLength], &moof);
86     if (OSACompile([_component componentInstance], &moof, kOSAModeNull, &_scriptID) != 0) {
87         NSLog(@"Compile error!");
88         return NO;
89     }
90     return YES;
91 }
92
93 - (BOOL)isCompiled
94 {
95     return (_scriptID != kOSANullScript);
96 }
97
98 - (NSString *)executeAndReturnError:(NSDictionary **)errorInfo
99 {
100     if ([_component componentInstance] == nil) {
101         //Set the error dictionary
102         return nil;
103     }
104     
105     AEDesc scriptDesc, resultDesc;
106     Size length;
107     NSString *result;
108     Ptr buffer;
109     OSAID resultID = kOSANullScript;
110     
111     //If not compiled, compile it
112     if (![self isCompiled]) {
113         if (![self compileAndReturnError:nil]) {
114             //Set the error info dictionary
115             return nil;
116         }
117     }
118     
119     OSAExecute([_component componentInstance], _scriptID, kOSANullScript, kOSANullMode, &resultID);
120     
121     OSADisplay([_component componentInstance], resultID, typeChar, kOSAModeDisplayForHumans, &resultDesc);
122     
123     length = AEGetDescDataSize(&resultDesc);
124     buffer = malloc(length);
125     
126     AEGetDescData(&resultDesc, buffer, length);
127     AEDisposeDesc(&scriptDesc);
128     AEDisposeDesc(&resultDesc);
129     result = [NSString stringWithCString:buffer length:length];
130     if (![result isEqualToString:@""] &&
131         ([result characterAtIndex:0] == '\"') &&
132         ([result characterAtIndex:[result length] - 1] == '\"'))
133     {
134         result = [result substringWithRange:NSMakeRange(1, [result length] - 2)];
135     }
136     free(buffer);
137     buffer = NULL;
138     
139     OSADispose([_component componentInstance], resultID);
140     
141     return result;
142 }
143
144 @end