Add support for uniquifying to all wxCocoa Objective-C classes.
[wxWidgets.git] / src / cocoa / utilsexc.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/cocoa/utilsexec.mm
3 // Purpose:     Execution-related utilities for wxCocoa
4 // Author:      Ryan Norton
5 // Modified by:
6 // Created:     2004-10-05
7 // RCS-ID:      $Id$
8 // Copyright:   (c) Ryan Norton
9 // Licence:     wxWindows licence
10 // Notes:       This code may be useful on platforms other than Darwin.
11 //              On Darwin we share the CoreFoundation code with wxMac.
12 /////////////////////////////////////////////////////////////////////////////
13
14 #include "wx/wxprec.h"
15
16 #ifndef WX_PRECOMP
17     #include "wx/utils.h"
18 #endif
19
20 #include "wx/unix/execute.h"
21
22 #if 0
23
24 #ifndef   WX_PRECOMP
25     #if wxUSE_STREAMS
26         #include  "wx/stream.h"
27     #endif // wxUSE_STREAMS
28 #endif  //WX_PRECOMP
29
30 #include "wx/process.h"
31
32 #include "wx/cocoa/string.h"
33
34 #include "wx/cocoa/objc/objc_uniquifying.h"
35
36 #import <Foundation/Foundation.h>
37 #import <AppKit/NSWorkspace.h>
38
39 //
40 // RN:  This is a prelimenary implementation - simple
41 // launching and process redirection works,
42 // but with the piping tests in the exec sample
43 // SIGPIPE is triggered...
44 //
45
46 class wxPipeInputStream : public wxInputStream
47 {
48 public:
49     wxPipeInputStream(NSPipe* thePipe) :
50             m_thePipe(thePipe),
51             m_theHandle([m_thePipe fileHandleForReading])
52     {
53     }
54
55     ~wxPipeInputStream()
56     {
57         [m_thePipe release];
58     }
59
60 protected:
61     virtual size_t OnSysRead(void *buffer, size_t size)
62     {
63         NSData* theData = [m_theHandle readDataOfLength:size];
64         memcpy(buffer, [theData bytes], [theData length]);
65         return [theData length];
66     }
67
68
69     NSPipe* m_thePipe;
70     NSFileHandle* m_theHandle;
71 };
72
73 class wxPipeOutputStream : public wxOutputStream
74 {
75 public:
76     wxPipeOutputStream(NSPipe* thePipe) :
77             m_thePipe(thePipe),
78             m_theHandle([m_thePipe fileHandleForWriting])
79     {
80     }
81
82     ~wxPipeOutputStream()
83     {
84         [m_thePipe release];
85     }
86
87 protected:
88
89     virtual size_t OnSysWrite(const void *buffer, size_t bufsize)
90     {
91         NSData* theData = [NSData dataWithBytesNoCopy:(void*)buffer
92                                   length:bufsize];
93         [m_theHandle writeData:theData];
94         return bufsize;
95     }
96
97     NSPipe* m_thePipe;
98     NSFileHandle* m_theHandle;
99 };
100
101 @interface wxTaskHandler : NSObject
102 {
103     long m_pid;
104     void* m_handle;
105 }
106 -(id)init:(void*)handle processIdentifier:(long)pid;
107 - (void)termHandler:(NSNotification *)aNotification;
108 @end
109 WX_DECLARE_GET_OBJC_CLASS(wxTaskHandler,NSObject)
110
111 @implementation wxTaskHandler : NSObject
112
113 -(id)init:(void*)handle processIdentifier:(long)pid
114 {
115     self = [super init];
116
117     m_handle = handle;
118     m_pid = pid;
119
120     [[NSNotificationCenter defaultCenter] addObserver:self
121             selector:@selector(termHandler:)
122             name:NSTaskDidTerminateNotification
123             object:nil];
124     return self;
125 }
126
127 - (void)termHandler:(NSNotification *)aNotification
128 {
129     NSTask* theTask = [aNotification object];
130
131     if ([theTask processIdentifier] == m_pid)
132     {
133         ((wxProcess*)m_handle)->OnTerminate([theTask processIdentifier],
134                           [theTask terminationStatus]);
135
136         [self release];
137     }
138 }
139
140 @end
141 WX_IMPLEMENT_GET_OBJC_CLASS(wxTaskHandler,NSObject)
142
143 long wxExecute(const wxString& command,
144                int sync,
145                wxProcess *handle)
146 {
147     NSTask* theTask = [[NSTask alloc] init];
148
149     if (handle && handle->IsRedirected())
150     {
151         NSPipe* theStdinPipe = [[NSPipe alloc] init];
152         NSPipe* theStderrPipe = [[NSPipe alloc] init];
153         NSPipe* theStdoutPipe = [[NSPipe alloc] init];
154
155         [theTask setStandardInput:theStdinPipe];
156         [theTask setStandardError:theStderrPipe];
157         [theTask setStandardOutput:theStdoutPipe];
158
159         handle->SetPipeStreams(new wxPipeInputStream(theStdoutPipe),
160                                new wxPipeOutputStream(theStdinPipe),
161                                new wxPipeInputStream(theStderrPipe) );
162     }
163
164     NSArray* theQuoteArguments =
165         [wxNSStringWithWxString(command) componentsSeparatedByString:@"\""];
166
167     NSMutableArray* theSeparatedArguments =
168         [NSMutableArray arrayWithCapacity:10];
169
170     for (unsigned i = 0; i < [theQuoteArguments count]; ++i)
171     {
172         [theSeparatedArguments addObjectsFromArray:
173             [[theQuoteArguments objectAtIndex:i] componentsSeparatedByString:@" "]
174         ];
175
176         if(++i < [theQuoteArguments count])
177             [theSeparatedArguments addObject:[theQuoteArguments objectAtIndex:i]];
178     }
179
180     [theTask setLaunchPath:[theSeparatedArguments objectAtIndex:0]];
181     [theTask setArguments:theSeparatedArguments];
182     [theTask launch];
183
184     if(sync & wxEXEC_ASYNC)
185     {
186         [[WX_GET_OBJC_CLASS(wxTaskHandler) alloc]init:handle
187                               processIdentifier:[theTask processIdentifier]];
188
189         return 0;
190     }
191     else
192     {
193         [theTask waitUntilExit];
194
195         return [theTask terminationStatus];
196     }
197 }
198 #endif //0