Split out the C++ class into its own file. Also move NetworkConnection's private...
authorRobert Sesek <rsesek@bluestatic.org>
Fri, 24 Dec 2010 18:53:56 +0000 (13:53 -0500)
committerRobert Sesek <rsesek@bluestatic.org>
Fri, 24 Dec 2010 18:53:56 +0000 (13:53 -0500)
MacGDBp.xcodeproj/project.pbxproj
Source/NetworkCallbackController.h [new file with mode: 0644]
Source/NetworkCallbackController.mm [new file with mode: 0644]
Source/NetworkConnection.h
Source/NetworkConnection.mm
Source/NetworkConnectionPrivate.h [new file with mode: 0644]

index 539e6adc7c02bd93f9b2e0e4aad9ec8471892c6d..3b8509d678bce8f655283309094ec13e98eda7d9 100644 (file)
@@ -43,6 +43,7 @@
                1EEBFD120D359A9F008F835B /* dimple.png in Resources */ = {isa = PBXBuildFile; fileRef = 1EEBFD110D359A9F008F835B /* dimple.png */; };
                1EEE875D0D9DE4B4009CBA7C /* MacGDBp.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1EEE875C0D9DE4B4009CBA7C /* MacGDBp.icns */; };
                1EFBE63012C515C200F96D6E /* NetworkConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EFBE62F12C515C200F96D6E /* NetworkConnection.mm */; };
+               1EFBE66B12C51E3900F96D6E /* NetworkCallbackController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EFBE66A12C51E3900F96D6E /* NetworkCallbackController.mm */; };
                1EFF70C30DFDC018006B9D33 /* BreakpointController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EFF70C20DFDC018006B9D33 /* BreakpointController.m */; };
                8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
                8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
                1EEBFD110D359A9F008F835B /* dimple.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dimple.png; sourceTree = "<group>"; };
                1EEE875C0D9DE4B4009CBA7C /* MacGDBp.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = MacGDBp.icns; path = Icons/MacGDBp.icns; sourceTree = "<group>"; };
                1EFBE62F12C515C200F96D6E /* NetworkConnection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkConnection.mm; path = Source/NetworkConnection.mm; sourceTree = "<group>"; };
+               1EFBE66912C51E3900F96D6E /* NetworkCallbackController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkCallbackController.h; path = Source/NetworkCallbackController.h; sourceTree = "<group>"; };
+               1EFBE66A12C51E3900F96D6E /* NetworkCallbackController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkCallbackController.mm; path = Source/NetworkCallbackController.mm; sourceTree = "<group>"; };
+               1EFBE66C12C51EFA00F96D6E /* NetworkConnectionPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkConnectionPrivate.h; path = Source/NetworkConnectionPrivate.h; sourceTree = "<group>"; };
                1EFF70C10DFDC018006B9D33 /* BreakpointController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointController.h; path = Source/BreakpointController.h; sourceTree = "<group>"; };
                1EFF70C20DFDC018006B9D33 /* BreakpointController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BreakpointController.m; path = Source/BreakpointController.m; sourceTree = "<group>"; };
                29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                1E0724E111B47BCC0017AD3C /* NetworkConnection.h */,
+                               1EFBE66C12C51EFA00F96D6E /* NetworkConnectionPrivate.h */,
                                1EFBE62F12C515C200F96D6E /* NetworkConnection.mm */,
+                               1EFBE66912C51E3900F96D6E /* NetworkCallbackController.h */,
+                               1EFBE66A12C51E3900F96D6E /* NetworkCallbackController.mm */,
                                1E02C56F0C610158006F1752 /* DebuggerBackEnd.h */,
                                1E02C5700C610158006F1752 /* DebuggerBackEnd.m */,
                                1E35FFB00C65A74C0030F527 /* NSXMLElementAdditions.h */,
                                1EC1337E127DBB00007946FC /* VariableNode.m in Sources */,
                                1EC6965812BBC6A700A8D984 /* modp_b64.cc in Sources */,
                                1EFBE63012C515C200F96D6E /* NetworkConnection.mm in Sources */,
+                               1EFBE66B12C51E3900F96D6E /* NetworkCallbackController.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/Source/NetworkCallbackController.h b/Source/NetworkCallbackController.h
new file mode 100644 (file)
index 0000000..4e9e78b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * MacGDBp
+ * Copyright (c) 2007 - 2010, Blue Static <http://www.bluestatic.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it under the terms of the GNU 
+ * General Public License as published by the Free Software Foundation; either version 2 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with this program; if not, 
+ * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#import <CoreFoundation/CoreFoundation.h>
+
+@class NetworkConnection;
+
+// This class is used for the CFNetwork callbacks. It is a private class and
+// the instance is owned by the NewtorkConnection instance. This class can be
+// considered an extension of NetworkConnection.
+class NetworkCallbackController
+{
+ public:
+  // This object should be constructed on the thread which the streams are
+  // to be scheduled on. It will hold a weak reference to the run loop on that
+  // thread.
+  NetworkCallbackController(NetworkConnection* connection);
+
+  // These static methods forward an invocation to the instance methods. The
+  // last void pointer, named |self|, is the instance of this class.
+  static void SocketAcceptCallback(CFSocketRef socket,
+                                   CFSocketCallBackType callbackType,
+                                   CFDataRef address,
+                                   const void* data,
+                                   void* self);
+  static void ReadStreamCallback(CFReadStreamRef stream,
+                                 CFStreamEventType eventType,
+                                 void* self);  
+  static void WriteStreamCallback(CFWriteStreamRef stream,
+                                  CFStreamEventType eventType,
+                                  void* self);
+
+ private:
+  void OnSocketAccept(CFSocketRef socket,
+                      CFDataRef address,
+                      const void* data);
+  void OnReadStreamEvent(CFReadStreamRef stream, CFStreamEventType eventType);
+  void OnWriteStreamEvent(CFWriteStreamRef stream, CFStreamEventType eventType);
+
+  // Removes the read or write stream from the run loop, closes the stream,
+  // releases the reference.
+  void UnscheduleReadStream();
+  void UnscheduleWriteStream();
+
+  // Messages the NetworkConnection's delegate and takes ownership of |error|.
+  void ReportError(CFErrorRef error);
+  
+  NetworkConnection* connection_;  // Weak, owns this.
+  CFRunLoopRef runLoop_;  // Weak.
+};
+
diff --git a/Source/NetworkCallbackController.mm b/Source/NetworkCallbackController.mm
new file mode 100644 (file)
index 0000000..7356912
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * MacGDBp
+ * Copyright (c) 2007 - 2010, Blue Static <http://www.bluestatic.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it under the terms of the GNU 
+ * General Public License as published by the Free Software Foundation; either version 2 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with this program; if not, 
+ * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#import "NetworkCallbackController.h"
+
+#import "NetworkConnection.h"
+#import "NetworkConnectionPrivate.h"
+
+NetworkCallbackController::NetworkCallbackController(NetworkConnection* connection)
+    : connection_(connection),
+      runLoop_(CFRunLoopGetCurrent())
+{
+}
+
+// Static Methods //////////////////////////////////////////////////////////////
+
+void NetworkCallbackController::SocketAcceptCallback(CFSocketRef socket,
+                                                     CFSocketCallBackType callbackType,
+                                                     CFDataRef address,
+                                                     const void* data,
+                                                     void* self)
+{
+  assert(callbackType == kCFSocketAcceptCallBack);
+  static_cast<NetworkCallbackController*>(self)->OnSocketAccept(socket, address, data);
+}
+
+void NetworkCallbackController::ReadStreamCallback(CFReadStreamRef stream,
+                                                   CFStreamEventType eventType,
+                                                   void* self)
+{
+  static_cast<NetworkCallbackController*>(self)->OnReadStreamEvent(stream, eventType);
+}
+
+void NetworkCallbackController::WriteStreamCallback(CFWriteStreamRef stream,
+                                                    CFStreamEventType eventType,
+                                                    void* self)
+{
+  static_cast<NetworkCallbackController*>(self)->OnWriteStreamEvent(stream, eventType);
+}
+
+
+// Private Instance Methods ////////////////////////////////////////////////////
+
+void NetworkCallbackController::OnSocketAccept(CFSocketRef socket,
+                                               CFDataRef address,
+                                               const void* data)
+{
+  CFReadStreamRef readStream;
+  CFWriteStreamRef writeStream;
+  
+  // Create the streams on the socket.
+  CFStreamCreatePairWithSocket(kCFAllocatorDefault,
+                               *(CFSocketNativeHandle*)data,  // Socket handle.
+                               &readStream,  // Read stream in-pointer.
+                               &writeStream);  // Write stream in-pointer.
+  
+  // Create struct to register callbacks for the stream.
+  CFStreamClientContext context = { 0 };
+  context.info = this;
+  
+  // Set the client of the read stream.
+  CFOptionFlags readFlags = kCFStreamEventOpenCompleted |
+  kCFStreamEventHasBytesAvailable |
+  kCFStreamEventErrorOccurred |
+  kCFStreamEventEndEncountered;
+  if (CFReadStreamSetClient(readStream, readFlags, &NetworkCallbackController::ReadStreamCallback, &context))
+    // Schedule in run loop to do asynchronous communication with the engine.
+    CFReadStreamScheduleWithRunLoop(readStream, runLoop_, kCFRunLoopCommonModes);
+  else
+    return;
+  
+  // Open the stream now that it's scheduled on the run loop.
+  if (!CFReadStreamOpen(readStream)) {
+    ReportError(CFReadStreamCopyError(readStream));
+    return;
+  }
+  
+  // Set the client of the write stream.
+  CFOptionFlags writeFlags = kCFStreamEventOpenCompleted |
+  kCFStreamEventCanAcceptBytes |
+  kCFStreamEventErrorOccurred |
+  kCFStreamEventEndEncountered;
+  if (CFWriteStreamSetClient(writeStream, writeFlags, &NetworkCallbackController::WriteStreamCallback, &context))
+    // Schedule it in the run loop to receive error information.
+    CFWriteStreamScheduleWithRunLoop(writeStream, runLoop_, kCFRunLoopCommonModes);
+  else
+    return;
+  
+  // Open the write stream.
+  if (!CFWriteStreamOpen(writeStream)) {
+    ReportError(CFWriteStreamCopyError(writeStream));
+    return;
+  }
+  
+  connection_.readStream = readStream;
+  connection_.writeStream = writeStream;
+  [connection_ socketDidAccept];
+}
+
+void NetworkCallbackController::OnReadStreamEvent(CFReadStreamRef stream,
+                                                  CFStreamEventType eventType)
+{
+  switch (eventType)
+  {
+    case kCFStreamEventHasBytesAvailable:
+      [connection_ readStreamHasData];
+      break;
+      
+    case kCFStreamEventErrorOccurred:
+    {
+      ReportError(CFReadStreamCopyError(stream));
+      UnscheduleReadStream();
+      break;
+    }
+      
+    case kCFStreamEventEndEncountered:
+      UnscheduleReadStream();
+      [connection_ socketDisconnected];
+      break;
+  };
+}
+
+void NetworkCallbackController::OnWriteStreamEvent(CFWriteStreamRef stream,
+                                                   CFStreamEventType eventType)
+{
+  switch (eventType)
+  {
+    case kCFStreamEventCanAcceptBytes:
+      [connection_ sendQueuedWrites];
+      break;
+      
+    case kCFStreamEventErrorOccurred:
+    {
+      ReportError(CFWriteStreamCopyError(stream));
+      UnscheduleWriteStream();
+      break;
+    }
+      
+    case kCFStreamEventEndEncountered:
+      UnscheduleReadStream();
+      [connection_ socketDisconnected];
+      break;
+  }
+}
+
+void NetworkCallbackController::UnscheduleReadStream()
+{
+  CFReadStreamUnscheduleFromRunLoop(connection_.readStream, runLoop_, kCFRunLoopCommonModes);
+  CFReadStreamClose(connection_.readStream);
+  CFRelease(connection_.readStream);    
+  connection_.readStream = NULL;
+}
+
+void NetworkCallbackController::UnscheduleWriteStream()
+{
+  CFWriteStreamUnscheduleFromRunLoop(connection_.writeStream, runLoop_, kCFRunLoopCommonModes);
+  CFWriteStreamClose(connection_.writeStream);
+  CFRelease(connection_.writeStream);
+  connection_.writeStream = NULL;
+}
+
+void NetworkCallbackController::ReportError(CFErrorRef error)
+{
+  [connection_ errorEncountered:[(NSError*)error description]];
+  CFRelease(error);
+}
index 0b27ebea1ba3879dc3bb2e97afbfe1bb097b54f7..234e79747b53983e83dab010195d30327b201ef5 100644 (file)
@@ -55,7 +55,7 @@ class NetworkCallbackController;
   // The write stream. Weak.
   CFWriteStreamRef writeStream_;
 
-  // Run loop source used to quit the thread.
+  // Run loop source used to quit the thread. Strong.
   CFRunLoopSourceRef quitSource_;
 
   // An ever-increasing integer that gives each transaction a unique ID for the
index c5728c0627830ea9f03033e8bc9fab16e8ff09e5..08c3d6012b12206bdb94217a9d654213dbd5925f 100644 (file)
  */
 
 #import "NetworkConnection.h"
+#import "NetworkConnectionPrivate.h"
 
 #import <sys/socket.h>
 #import <netinet/in.h>
 
 #import "AppDelegate.h"
 #import "LoggingController.h"
-
-// NetworkConnection (Private) /////////////////////////////////////////////////
-
-@interface NetworkConnection ()
-
-@property (assign) CFSocketRef socket;
-@property (assign) CFReadStreamRef readStream;
-@property NSUInteger lastReadTransaction;
-@property (retain) NSMutableString* currentPacket;
-@property (assign) CFWriteStreamRef writeStream;
-@property NSUInteger lastWrittenTransaction;
-@property (retain) NSMutableArray* queuedWrites;
-
-- (void)runNetworkThread;
-
-- (void)socketDidAccept;
-- (void)socketDisconnected;
-- (void)readStreamHasData;
-
-// These methods MUST be called on the network thread as they are not threadsafe.
-- (void)send:(NSString*)command;
-- (void)performSend:(NSString*)command;
-- (void)sendQueuedWrites;
-
-- (void)performQuitSignal;
-
-- (void)handleResponse:(NSXMLDocument*)response;
-- (void)handlePacket:(NSString*)packet;
-
-// Threadsafe wrappers for the delegate's methods.
-- (void)errorEncountered:(NSString*)error;
-- (LogEntry*)recordSend:(NSString*)command;
-- (LogEntry*)recordReceive:(NSString*)command;
-
-@end
-
-// CFNetwork Callbacks /////////////////////////////////////////////////////////
-
-class NetworkCallbackController
-{
- public:
-  NetworkCallbackController(NetworkConnection* connection)
-      : connection_(connection),
-        runLoop_(CFRunLoopGetCurrent())
-  {
-  }
-
-  static void SocketAcceptCallback(CFSocketRef socket,
-                                   CFSocketCallBackType callbackType,
-                                   CFDataRef address,
-                                   const void* data,
-                                   void* self)
-  {
-    assert(callbackType == kCFSocketAcceptCallBack);
-    static_cast<NetworkCallbackController*>(self)->OnSocketAccept(socket, address, data);
-  }
-
-  void OnSocketAccept(CFSocketRef socket,
-                      CFDataRef address,
-                      const void* data)
-  {
-    CFReadStreamRef readStream;
-    CFWriteStreamRef writeStream;
-    
-    // Create the streams on the socket.
-    CFStreamCreatePairWithSocket(kCFAllocatorDefault,
-                                 *(CFSocketNativeHandle*)data,  // Socket handle.
-                                 &readStream,  // Read stream in-pointer.
-                                 &writeStream);  // Write stream in-pointer.
-    
-    // Create struct to register callbacks for the stream.
-    CFStreamClientContext context = { 0 };
-    context.info = this;
-    
-    // Set the client of the read stream.
-    CFOptionFlags readFlags = kCFStreamEventOpenCompleted |
-                              kCFStreamEventHasBytesAvailable |
-                              kCFStreamEventErrorOccurred |
-                              kCFStreamEventEndEncountered;
-    if (CFReadStreamSetClient(readStream, readFlags, &NetworkCallbackController::ReadStreamCallback, &context))
-      // Schedule in run loop to do asynchronous communication with the engine.
-      CFReadStreamScheduleWithRunLoop(readStream, runLoop_, kCFRunLoopCommonModes);
-    else
-      return;
-    
-    // Open the stream now that it's scheduled on the run loop.
-    if (!CFReadStreamOpen(readStream)) {
-      ReportError(CFReadStreamCopyError(readStream));
-      return;
-    }
-    
-    // Set the client of the write stream.
-    CFOptionFlags writeFlags = kCFStreamEventOpenCompleted |
-                               kCFStreamEventCanAcceptBytes |
-                               kCFStreamEventErrorOccurred |
-                               kCFStreamEventEndEncountered;
-    if (CFWriteStreamSetClient(writeStream, writeFlags, &NetworkCallbackController::WriteStreamCallback, &context))
-      // Schedule it in the run loop to receive error information.
-      CFWriteStreamScheduleWithRunLoop(writeStream, runLoop_, kCFRunLoopCommonModes);
-    else
-      return;
-    
-    // Open the write stream.
-    if (!CFWriteStreamOpen(writeStream)) {
-      ReportError(CFWriteStreamCopyError(writeStream));
-      return;
-    }
-    
-    connection_.readStream = readStream;
-    connection_.writeStream = writeStream;
-    [connection_ socketDidAccept];
-  }
-
-  static void ReadStreamCallback(CFReadStreamRef stream,
-                                 CFStreamEventType eventType,
-                                 void* self)
-  {
-    static_cast<NetworkCallbackController*>(self)->OnReadStreamEvent(stream, eventType);
-  }
-
-  void OnReadStreamEvent(CFReadStreamRef stream, CFStreamEventType eventType)
-  {
-    switch (eventType)
-    {
-      case kCFStreamEventHasBytesAvailable:
-        [connection_ readStreamHasData];
-        break;
-        
-      case kCFStreamEventErrorOccurred:
-      {
-        ReportError(CFReadStreamCopyError(stream));
-        UnscheduleReadStream();
-        break;
-      }
-        
-      case kCFStreamEventEndEncountered:
-        UnscheduleReadStream();
-        [connection_ socketDisconnected];
-        break;
-    };
-  }
-
-  void UnscheduleReadStream()
-  {
-    CFReadStreamUnscheduleFromRunLoop(connection_.readStream, runLoop_, kCFRunLoopCommonModes);
-    CFReadStreamClose(connection_.readStream);
-    CFRelease(connection_.readStream);    
-    connection_.readStream = NULL;
-  }
-
-  static void WriteStreamCallback(CFWriteStreamRef stream,
-                                  CFStreamEventType eventType,
-                                  void* self)
-  {
-    static_cast<NetworkCallbackController*>(self)->OnWriteStreamEvent(stream, eventType);
-  }
-
-  void OnWriteStreamEvent(CFWriteStreamRef stream, CFStreamEventType eventType)
-  {
-    switch (eventType)
-    {
-      case kCFStreamEventCanAcceptBytes:
-        [connection_ sendQueuedWrites];
-        break;
-        
-      case kCFStreamEventErrorOccurred:
-      {
-        ReportError(CFWriteStreamCopyError(stream));
-        UnscheduleWriteStream();
-        break;
-      }
-        
-      case kCFStreamEventEndEncountered:
-        UnscheduleReadStream();
-        [connection_ socketDisconnected];
-        break;
-    }
-  }
-  void UnscheduleWriteStream()
-  {
-    CFWriteStreamUnscheduleFromRunLoop(connection_.writeStream, runLoop_, kCFRunLoopCommonModes);
-    CFWriteStreamClose(connection_.writeStream);
-    CFRelease(connection_.writeStream);
-    connection_.writeStream = NULL;
-  }
-
- private:
-  void ReportError(CFErrorRef error)
-  {
-    [connection_ errorEncountered:[(NSError*)error description]];
-    CFRelease(error);
-  }
-
-  NetworkConnection* connection_;  // Weak, owns this.
-  CFRunLoopRef runLoop_;  // Weak.
-};
+#include "NetworkCallbackController.h"
 
 // Other Run Loop Callbacks ////////////////////////////////////////////////////
 
diff --git a/Source/NetworkConnectionPrivate.h b/Source/NetworkConnectionPrivate.h
new file mode 100644 (file)
index 0000000..9ce998a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * MacGDBp
+ * Copyright (c) 2007 - 2010, Blue Static <http://www.bluestatic.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it under the terms of the GNU 
+ * General Public License as published by the Free Software Foundation; either version 2 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with this program; if not, 
+ * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+@class LogEntry;
+
+@interface NetworkConnection ()
+
+@property (assign) CFSocketRef socket;
+@property (assign) CFReadStreamRef readStream;
+@property NSUInteger lastReadTransaction;
+@property (retain) NSMutableString* currentPacket;
+@property (assign) CFWriteStreamRef writeStream;
+@property NSUInteger lastWrittenTransaction;
+@property (retain) NSMutableArray* queuedWrites;
+
+- (void)runNetworkThread;
+
+- (void)socketDidAccept;
+- (void)socketDisconnected;
+- (void)readStreamHasData;
+
+// These methods MUST be called on the network thread as they are not threadsafe.
+- (void)send:(NSString*)command;
+- (void)performSend:(NSString*)command;
+- (void)sendQueuedWrites;
+
+- (void)performQuitSignal;
+
+- (void)handleResponse:(NSXMLDocument*)response;
+- (void)handlePacket:(NSString*)packet;
+
+// Threadsafe wrappers for the delegate's methods.
+- (void)errorEncountered:(NSString*)error;
+- (LogEntry*)recordSend:(NSString*)command;
+- (LogEntry*)recordReceive:(NSString*)command;
+
+@end