Connect ProtocolClient to the LoggingController.
[macgdbp.git] / Source / NetworkConnection.m
1 /*
2 * MacGDBp
3 * Copyright (c) 2007 - 2011, Blue Static <http://www.bluestatic.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17 #import "NetworkConnection.h"
18
19 // This is the private interface for the NetworkConnection class. This is shared
20 // by the C++ NetworkCallbackController to communicate.
21 @interface NetworkConnection (Private)
22
23 - (void)handleResponse:(NSXMLDocument*)response;
24
25 // Threadsafe wrappers for the delegate's methods.
26 - (void)errorEncountered:(NSString*)error;
27
28 @end
29
30
31 ////////////////////////////////////////////////////////////////////////////////
32
33 @implementation NetworkConnection
34
35 @synthesize port = port_;
36 @synthesize connected = connected_;
37 @synthesize delegate = delegate_;
38
39 - (id)initWithPort:(NSUInteger)aPort
40 {
41 if (self = [super initWithDelegate:self]) {
42 port_ = aPort;
43 _ideClient = self;
44 }
45 return self;
46 }
47
48 /**
49 * Kicks off the socket on another thread.
50 */
51 - (void)connect
52 {
53 [_ideClient connectOnPort:port_];
54 }
55
56 - (void)close
57 {
58 [_ideClient disconnect];
59 }
60
61 - (void)debuggerEngineConnected:(ProtocolClient*)client
62 {
63 if ([delegate_ respondsToSelector:@selector(connectionDidAccept:)])
64 [delegate_ connectionDidAccept:self];
65 }
66
67 - (void)debuggerEngineDisconnected:(ProtocolClient*)client
68 {
69 if ([delegate_ respondsToSelector:@selector(connectionDidClose:)])
70 [delegate_ connectionDidClose:self];
71 }
72
73 - (void)debuggerEngine:(ProtocolClient*)client receivedMessage:(NSXMLDocument*)message
74 {
75 [self handleResponse:message];
76 }
77
78 - (void)dealloc
79 {
80 [_ideClient release];
81 [super dealloc];
82 }
83
84 /**
85 * Given a file path, this returns a file:// URI and escapes any spaces for the
86 * debugger engine.
87 */
88 - (NSString*)escapedURIPath:(NSString*)path
89 {
90 // Custon GDBp paths are fine.
91 if ([[path substringToIndex:4] isEqualToString:@"gdbp"])
92 return path;
93
94 // Create a temporary URL that will escape all the nasty characters.
95 NSURL* url = [NSURL fileURLWithPath:path];
96 NSString* urlString = [url absoluteString];
97
98 // Remove the host because this is a file:// URL;
99 urlString = [urlString stringByReplacingOccurrencesOfString:[url host] withString:@""];
100
101 // Escape % for use in printf-style NSString formatters.
102 urlString = [urlString stringByReplacingOccurrencesOfString:@"%" withString:@"%%"];
103 return urlString;
104 }
105
106 // Private /////////////////////////////////////////////////////////////////////
107 #pragma mark Private
108
109 // Delegate Thread-Safe Wrappers ///////////////////////////////////////////////
110
111 /**
112 * Receives errors from the SocketWrapper and updates the display
113 */
114 - (void)errorEncountered:(NSString*)error
115 {
116 if (![delegate_ respondsToSelector:@selector(errorEncountered:)])
117 return;
118 [delegate_ performSelectorOnMainThread:@selector(errorEncountered:)
119 withObject:error
120 waitUntilDone:NO];
121 }
122
123 - (void)handleResponse:(NSXMLDocument*)response
124 {
125 // Check and see if there's an error.
126 NSArray* error = [[response rootElement] elementsForName:@"error"];
127 if ([error count] > 0) {
128 NSLog(@"Xdebug error: %@", error);
129 NSString* errorMessage = [[[[error objectAtIndex:0] children] objectAtIndex:0] stringValue];
130 [self errorEncountered:errorMessage];
131 }
132
133 if ([[[response rootElement] name] isEqualToString:@"init"]) {
134 connected_ = YES;
135 [delegate_ handleInitialResponse:response];
136 return;
137 }
138
139 if ([delegate_ respondsToSelector:@selector(handleResponse:)])
140 [delegate_ handleResponse:response];
141 }
142
143 @end