Kaynağa Gözat

Merge pull request #360 from facebook/nlutsenko.split

Split internal classes into their own source files.
Nikita Lutsenko 9 yıl önce
ebeveyn
işleme
3b995adaf3

+ 3 - 1
SocketRocket.podspec

@@ -6,8 +6,10 @@ Pod::Spec.new do |s|
   s.authors            = 'Square'
   s.license            = 'BSD'
   s.source             = { :git => 'https://github.com/facebook/SocketRocket.git', :tag => s.version.to_s }
-  s.source_files       = 'SocketRocket/*.{h,m}'
   s.requires_arc       = true
+  
+  s.source_files       = 'SocketRocket/**/*.{h,m}'
+  s.public_header_files       = 'SocketRocket/*.h'
 
   s.ios.deployment_target  = '6.0'
   s.osx.deployment_target  = '10.8'

+ 113 - 0
SocketRocket.xcodeproj/project.pbxproj

@@ -21,6 +21,38 @@
 		811934BC1CDAF725003AB243 /* SocketRocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 555E0EB11C51E56D00E6BB92 /* SocketRocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		811934BE1CDAF725003AB243 /* SocketRocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 555E0EB11C51E56D00E6BB92 /* SocketRocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		811934C01CDAF726003AB243 /* SocketRocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 555E0EB11C51E56D00E6BB92 /* SocketRocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		81B31C141CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };
+		81B31C151CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };
+		81B31C161CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };
+		81B31C171CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };
+		81B31C181CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };
+		81B31C191CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };
+		81B31C1A1CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };
+		81B31C1B1CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };
+		81B31C1C1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };
+		81B31C1D1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };
+		81B31C1E1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };
+		81B31C1F1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };
+		81B31C201CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };
+		81B31C211CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };
+		81B31C221CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };
+		81B31C231CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };
+		81B31C2D1CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };
+		81B31C2E1CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };
+		81B31C2F1CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };
+		81B31C301CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };
+		81B31C311CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };
+		81B31C321CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };
+		81B31C331CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };
+		81B31C341CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };
+		81B31C5F1CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };
+		81B31C601CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };
+		81B31C611CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };
+		81B31C621CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };
+		81B31C631CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };
+		81B31C641CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };
+		81B31C651CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };
+		81B31C661CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };
 		F6016C8814620EC70037BB3D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };
 		F6016C8914620ECC0037BB3D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };
 		F6016C8A1462143C0037BB3D /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
@@ -71,6 +103,14 @@
 		3345DC901C52ACD70083CCB8 /* SocketRocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		555E0EB11C51E56D00E6BB92 /* SocketRocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketRocket.h; sourceTree = "<group>"; };
 		811934B11CDAF711003AB243 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRIOConsumer.h; sourceTree = "<group>"; };
+		81B31C101CDC404100D86D43 /* SRIOConsumer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRIOConsumer.m; sourceTree = "<group>"; };
+		81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRIOConsumerPool.h; sourceTree = "<group>"; };
+		81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRIOConsumerPool.m; sourceTree = "<group>"; };
+		81B31C2B1CDC406B00D86D43 /* SRHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRHash.h; sourceTree = "<group>"; };
+		81B31C2C1CDC406B00D86D43 /* SRHash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRHash.m; sourceTree = "<group>"; };
+		81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRRunLoopThread.h; sourceTree = "<group>"; };
+		81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRRunLoopThread.m; sourceTree = "<group>"; };
 		F60CC29F14D4EA0500A005E4 /* SRTWebSocketOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRTWebSocketOperation.h; sourceTree = "<group>"; };
 		F60CC2A014D4EA0500A005E4 /* SRTWebSocketOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRTWebSocketOperation.m; sourceTree = "<group>"; };
 		F61A0DC71625F44D00365EBD /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "en.lproj/Default-568h@2x.png"; sourceTree = "<group>"; };
@@ -187,6 +227,46 @@
 			path = Resources;
 			sourceTree = "<group>";
 		};
+		81B31C0D1CDC404100D86D43 /* Internal */ = {
+			isa = PBXGroup;
+			children = (
+				81B31C0E1CDC404100D86D43 /* IOConsumer */,
+				81B31C5C1CDC443A00D86D43 /* RunLoop */,
+				81B31C131CDC404100D86D43 /* Utilities */,
+			);
+			path = Internal;
+			sourceTree = "<group>";
+		};
+		81B31C0E1CDC404100D86D43 /* IOConsumer */ = {
+			isa = PBXGroup;
+			children = (
+				81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */,
+				81B31C101CDC404100D86D43 /* SRIOConsumer.m */,
+				81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */,
+				81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */,
+			);
+			path = IOConsumer;
+			sourceTree = "<group>";
+		};
+		81B31C131CDC404100D86D43 /* Utilities */ = {
+			isa = PBXGroup;
+			children = (
+				81B31C2B1CDC406B00D86D43 /* SRHash.h */,
+				81B31C2C1CDC406B00D86D43 /* SRHash.m */,
+			);
+			path = Utilities;
+			sourceTree = "<group>";
+		};
+		81B31C5C1CDC443A00D86D43 /* RunLoop */ = {
+			isa = PBXGroup;
+			children = (
+				81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */,
+				81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */,
+			);
+			name = RunLoop;
+			path = SocketRocket/Internal/RunLoop;
+			sourceTree = SOURCE_ROOT;
+		};
 		F62417EA14D52F3C003CE997 /* TestChat */ = {
 			isa = PBXGroup;
 			children = (
@@ -277,6 +357,7 @@
 		F6B208321450F597009315AF /* SocketRocket */ = {
 			isa = PBXGroup;
 			children = (
+				81B31C0D1CDC404100D86D43 /* Internal */,
 				555E0EB11C51E56D00E6BB92 /* SocketRocket.h */,
 				F6A12CCF145119B700C1D980 /* SRWebSocket.h */,
 				F6A12CD0145119B700C1D980 /* SRWebSocket.m */,
@@ -314,8 +395,12 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C151CDC404100D86D43 /* SRIOConsumer.h in Headers */,
+				81B31C1D1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,
 				2D42277F1BB4365C000C1A6C /* SRWebSocket.h in Headers */,
+				81B31C2E1CDC406B00D86D43 /* SRHash.h in Headers */,
 				811934BE1CDAF725003AB243 /* SocketRocket.h in Headers */,
+				81B31C601CDC444900D86D43 /* SRRunLoopThread.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -323,8 +408,12 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C171CDC404100D86D43 /* SRIOConsumer.h in Headers */,
+				81B31C1F1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,
 				3345DC8A1C52ACD70083CCB8 /* SRWebSocket.h in Headers */,
+				81B31C301CDC406B00D86D43 /* SRHash.h in Headers */,
 				811934C01CDAF726003AB243 /* SocketRocket.h in Headers */,
+				81B31C621CDC444900D86D43 /* SRRunLoopThread.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -332,8 +421,12 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C161CDC404100D86D43 /* SRIOConsumer.h in Headers */,
+				81B31C1E1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,
 				F668C8AA153E92F90044DBAC /* SRWebSocket.h in Headers */,
+				81B31C2F1CDC406B00D86D43 /* SRHash.h in Headers */,
 				811934BC1CDAF725003AB243 /* SocketRocket.h in Headers */,
+				81B31C611CDC444900D86D43 /* SRRunLoopThread.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -341,8 +434,12 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C141CDC404100D86D43 /* SRIOConsumer.h in Headers */,
+				81B31C1C1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,
 				F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */,
+				81B31C2D1CDC406B00D86D43 /* SRHash.h in Headers */,
 				555E0EB41C51E57A00E6BB92 /* SocketRocket.h in Headers */,
+				81B31C5F1CDC444900D86D43 /* SRRunLoopThread.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -533,7 +630,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C191CDC404100D86D43 /* SRIOConsumer.m in Sources */,
 				2D4227851BB43734000C1A6C /* SRWebSocket.m in Sources */,
+				81B31C211CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,
+				81B31C641CDC444900D86D43 /* SRRunLoopThread.m in Sources */,
+				81B31C321CDC406B00D86D43 /* SRHash.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -541,7 +642,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C1B1CDC404100D86D43 /* SRIOConsumer.m in Sources */,
 				3345DC841C52ACD70083CCB8 /* SRWebSocket.m in Sources */,
+				81B31C231CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,
+				81B31C661CDC444900D86D43 /* SRRunLoopThread.m in Sources */,
+				81B31C341CDC406B00D86D43 /* SRHash.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -560,7 +665,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C1A1CDC404100D86D43 /* SRIOConsumer.m in Sources */,
 				F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */,
+				81B31C221CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,
+				81B31C651CDC444900D86D43 /* SRRunLoopThread.m in Sources */,
+				81B31C331CDC406B00D86D43 /* SRHash.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -568,7 +677,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				81B31C181CDC404100D86D43 /* SRIOConsumer.m in Sources */,
 				F6A12CD2145119B700C1D980 /* SRWebSocket.m in Sources */,
+				81B31C201CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,
+				81B31C631CDC444900D86D43 /* SRRunLoopThread.m in Sources */,
+				81B31C311CDC406B00D86D43 /* SRHash.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 40 - 0
SocketRocket/Internal/IOConsumer/SRIOConsumer.h

@@ -0,0 +1,40 @@
+//
+// Copyright 2012 Square Inc.
+// Portions Copyright (c) 2016-present, Facebook, Inc.
+//
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import <Foundation/Foundation.h>
+
+@class SRWebSocket; // TODO: (nlutsenko) Remove dependency on SRWebSocket here.
+
+// Returns number of bytes consumed. Returning 0 means you didn't match.
+// Sends bytes to callback handler;
+typedef size_t (^stream_scanner)(NSData *collected_data);
+typedef void (^data_callback)(SRWebSocket *webSocket,  NSData *data);
+
+@interface SRIOConsumer : NSObject {
+    stream_scanner _scanner;
+    data_callback _handler;
+    size_t _bytesNeeded;
+    BOOL _readToCurrentFrame;
+    BOOL _unmaskBytes;
+}
+@property (nonatomic, copy, readonly) stream_scanner consumer;
+@property (nonatomic, copy, readonly) data_callback handler;
+@property (nonatomic, assign) size_t bytesNeeded;
+@property (nonatomic, assign, readonly) BOOL readToCurrentFrame;
+@property (nonatomic, assign, readonly) BOOL unmaskBytes;
+
+- (void)resetWithScanner:(stream_scanner)scanner
+                 handler:(data_callback)handler
+             bytesNeeded:(size_t)bytesNeeded
+      readToCurrentFrame:(BOOL)readToCurrentFrame
+             unmaskBytes:(BOOL)unmaskBytes;
+
+@end

+ 36 - 0
SocketRocket/Internal/IOConsumer/SRIOConsumer.m

@@ -0,0 +1,36 @@
+//
+// Copyright 2012 Square Inc.
+// Portions Copyright (c) 2016-present, Facebook, Inc.
+//
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import "SRIOConsumer.h"
+
+@implementation SRIOConsumer
+
+@synthesize bytesNeeded = _bytesNeeded;
+@synthesize consumer = _scanner;
+@synthesize handler = _handler;
+@synthesize readToCurrentFrame = _readToCurrentFrame;
+@synthesize unmaskBytes = _unmaskBytes;
+
+- (void)resetWithScanner:(stream_scanner)scanner
+                 handler:(data_callback)handler
+             bytesNeeded:(size_t)bytesNeeded
+      readToCurrentFrame:(BOOL)readToCurrentFrame
+             unmaskBytes:(BOOL)unmaskBytes
+{
+    _scanner = [scanner copy];
+    _handler = [handler copy];
+    _bytesNeeded = bytesNeeded;
+    _readToCurrentFrame = readToCurrentFrame;
+    _unmaskBytes = unmaskBytes;
+    assert(_scanner || _bytesNeeded);
+}
+
+@end

+ 28 - 0
SocketRocket/Internal/IOConsumer/SRIOConsumerPool.h

@@ -0,0 +1,28 @@
+//
+// Copyright 2012 Square Inc.
+// Portions Copyright (c) 2016-present, Facebook, Inc.
+//
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SRIOConsumer.h" // TODO: (nlutsenko) Convert to @class and constants file for block types
+
+// This class is not thread-safe, and is expected to always be run on the same queue.
+@interface SRIOConsumerPool : NSObject
+
+- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;
+
+- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner
+                              handler:(data_callback)handler
+                          bytesNeeded:(size_t)bytesNeeded
+                   readToCurrentFrame:(BOOL)readToCurrentFrame
+                          unmaskBytes:(BOOL)unmaskBytes;
+- (void)returnConsumer:(SRIOConsumer *)consumer;
+
+@end

+ 64 - 0
SocketRocket/Internal/IOConsumer/SRIOConsumerPool.m

@@ -0,0 +1,64 @@
+//
+// Copyright 2012 Square Inc.
+// Portions Copyright (c) 2016-present, Facebook, Inc.
+//
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import "SRIOConsumerPool.h"
+
+@implementation SRIOConsumerPool {
+    NSUInteger _poolSize;
+    NSMutableArray<SRIOConsumer *> *_bufferedConsumers;
+}
+
+- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;
+{
+    self = [super init];
+    if (self) {
+        _poolSize = poolSize;
+        _bufferedConsumers = [NSMutableArray arrayWithCapacity:poolSize];
+    }
+    return self;
+}
+
+- (instancetype)init
+{
+    return [self initWithBufferCapacity:8];
+}
+
+- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner
+                              handler:(data_callback)handler
+                          bytesNeeded:(size_t)bytesNeeded
+                   readToCurrentFrame:(BOOL)readToCurrentFrame
+                          unmaskBytes:(BOOL)unmaskBytes
+{
+    SRIOConsumer *consumer = nil;
+    if (_bufferedConsumers.count) {
+        consumer = [_bufferedConsumers lastObject];
+        [_bufferedConsumers removeLastObject];
+    } else {
+        consumer = [[SRIOConsumer alloc] init];
+    }
+
+    [consumer resetWithScanner:scanner
+                       handler:handler
+                   bytesNeeded:bytesNeeded
+            readToCurrentFrame:readToCurrentFrame
+                   unmaskBytes:unmaskBytes];
+
+    return consumer;
+}
+
+- (void)returnConsumer:(SRIOConsumer *)consumer;
+{
+    if (_bufferedConsumers.count < _poolSize) {
+        [_bufferedConsumers addObject:consumer];
+    }
+}
+
+@end

+ 18 - 0
SocketRocket/Internal/RunLoop/SRRunLoopThread.h

@@ -0,0 +1,18 @@
+//
+// Copyright 2012 Square Inc.
+// Portions Copyright (c) 2016-present, Facebook, Inc.
+//
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface SRRunLoopThread : NSThread
+
+@property (nonatomic, strong, readonly) NSRunLoop *runLoop;
+
+@end

+ 77 - 0
SocketRocket/Internal/RunLoop/SRRunLoopThread.m

@@ -0,0 +1,77 @@
+//
+// Copyright 2012 Square Inc.
+// Portions Copyright (c) 2016-present, Facebook, Inc.
+//
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import "SRRunLoopThread.h"
+
+@interface SRRunLoopThread ()
+
+@property (nonatomic, strong, readwrite) NSRunLoop *runLoop;
+
+@end
+
+@implementation SRRunLoopThread {
+    dispatch_group_t _waitGroup;
+}
+
+- (void)dealloc
+{
+#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
+    dispatch_release(_waitGroup);
+#endif
+}
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        _waitGroup = dispatch_group_create();
+        dispatch_group_enter(_waitGroup);
+    }
+    return self;
+}
+
+- (void)main
+{
+    @autoreleasepool {
+        _runLoop = [NSRunLoop currentRunLoop];
+        dispatch_group_leave(_waitGroup);
+
+        // Add an empty run loop source to prevent runloop from spinning.
+        CFRunLoopSourceContext sourceCtx = {
+            .version = 0,
+            .info = NULL,
+            .retain = NULL,
+            .release = NULL,
+            .copyDescription = NULL,
+            .equal = NULL,
+            .hash = NULL,
+            .schedule = NULL,
+            .cancel = NULL,
+            .perform = NULL
+        };
+        CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);
+        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
+        CFRelease(source);
+
+        while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
+
+        }
+        assert(NO);
+    }
+}
+
+- (NSRunLoop *)runLoop;
+{
+    dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);
+    return _runLoop;
+}
+
+@end

+ 19 - 0
SocketRocket/Internal/Utilities/SRHash.h

@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2016-present, Facebook, Inc.
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+extern NSData *SRSHA1HashFromString(NSString *string);
+extern NSData *SRSHA1HashFromBytes(const char *bytes, size_t length);
+
+extern NSString *SRBase64EncodedStringFromData(NSData *data);
+
+NS_ASSUME_NONNULL_END

+ 43 - 0
SocketRocket/Internal/Utilities/SRHash.m

@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2016-present, Facebook, Inc.
+// All rights reserved.
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+//
+
+#import "SRHash.h"
+
+#import <CommonCrypto/CommonDigest.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+NSData *SRSHA1HashFromString(NSString *string)
+{
+    size_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+    return SRSHA1HashFromBytes(string.UTF8String, length);
+}
+
+NSData *SRSHA1HashFromBytes(const char *bytes, size_t length)
+{
+    uint8_t outputLength = CC_SHA1_DIGEST_LENGTH;
+    unsigned char output[outputLength];
+    CC_SHA1(bytes, (CC_LONG)length, output);
+
+    return [NSData dataWithBytes:output length:outputLength];
+}
+
+NSString *SRBase64EncodedStringFromData(NSData *data)
+{
+    if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
+        return [data base64EncodedStringWithOptions:0];
+    }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    return [data base64Encoding];
+#pragma clang diagnostic pop
+}
+
+NS_ASSUME_NONNULL_END

+ 9 - 224
SocketRocket/SRWebSocket.m

@@ -25,9 +25,13 @@
 #import <CoreServices/CoreServices.h>
 #endif
 
-#import <CommonCrypto/CommonDigest.h>
 #import <Security/SecRandom.h>
 
+#import "SRIOConsumer.h"
+#import "SRIOConsumerPool.h"
+#import "SRHash.h"
+#import "SRRunLoopThread.h"
+
 #if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
 #define sr_dispatch_retain(x)
 #define sr_dispatch_release(x)
@@ -68,20 +72,6 @@ static NSString *const SRWebSocketAppendToSecKeyString = @"258EAFA5-E914-47DA-95
 static inline int32_t validate_dispatch_data_partial_string(NSData *data);
 static inline void SRFastLog(NSString *format, ...);
 
-@interface NSData (SRWebSocket)
-
-- (NSString *)stringBySHA1ThenBase64Encoding;
-
-@end
-
-
-@interface NSString (SRWebSocket)
-
-- (NSString *)stringBySHA1ThenBase64Encoding;
-
-@end
-
-
 @interface NSURL (SRWebSocket)
 
 // The origin isn't really applicable for a native application.
@@ -90,86 +80,9 @@ static inline void SRFastLog(NSString *format, ...);
 
 @end
 
-
-@interface _SRRunLoopThread : NSThread
-
-@property (nonatomic, readonly) NSRunLoop *runLoop;
-
-@end
-
-
-static NSString *newSHA1String(const char *bytes, size_t length) {
-    uint8_t md[CC_SHA1_DIGEST_LENGTH];
-
-    assert(length >= 0);
-    assert(length <= UINT32_MAX);
-    CC_SHA1(bytes, (CC_LONG)length, md);
-    
-    NSData *data = [NSData dataWithBytes:md length:CC_SHA1_DIGEST_LENGTH];
-    
-    if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
-        return [data base64EncodedStringWithOptions:0];
-    }
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    return [data base64Encoding];
-#pragma clang diagnostic pop
-}
-
-@implementation NSData (SRWebSocket)
-
-- (NSString *)stringBySHA1ThenBase64Encoding;
-{
-    return newSHA1String(self.bytes, self.length);
-}
-
-@end
-
-
-@implementation NSString (SRWebSocket)
-
-- (NSString *)stringBySHA1ThenBase64Encoding;
-{
-    return newSHA1String(self.UTF8String, self.length);
-}
-
-@end
-
 NSString *const SRWebSocketErrorDomain = @"SRWebSocketErrorDomain";
 NSString *const SRHTTPResponseErrorKey = @"HTTPResponseStatusCode";
 
-// Returns number of bytes consumed. Returning 0 means you didn't match.
-// Sends bytes to callback handler;
-typedef size_t (^stream_scanner)(NSData *collected_data);
-
-typedef void (^data_callback)(SRWebSocket *webSocket,  NSData *data);
-
-@interface SRIOConsumer : NSObject {
-    stream_scanner _scanner;
-    data_callback _handler;
-    size_t _bytesNeeded;
-    BOOL _readToCurrentFrame;
-    BOOL _unmaskBytes;
-}
-@property (nonatomic, copy, readonly) stream_scanner consumer;
-@property (nonatomic, copy, readonly) data_callback handler;
-@property (nonatomic, assign) size_t bytesNeeded;
-@property (nonatomic, assign, readonly) BOOL readToCurrentFrame;
-@property (nonatomic, assign, readonly) BOOL unmaskBytes;
-
-@end
-
-// This class is not thread-safe, and is expected to always be run on the same queue.
-@interface SRIOConsumerPool : NSObject
-
-- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;
-
-- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner handler:(data_callback)handler bytesNeeded:(size_t)bytesNeeded readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes;
-- (void)returnConsumer:(SRIOConsumer *)consumer;
-
-@end
-
 @interface SRWebSocket ()  <NSStreamDelegate>
 
 @property (nonatomic) SRReadyState readyState;
@@ -423,8 +336,8 @@ static __strong NSData *CRLFCRLF;
     }
     
     NSString *concattedString = [_secKey stringByAppendingString:SRWebSocketAppendToSecKeyString];
-    NSString *expectedAccept = [concattedString stringBySHA1ThenBase64Encoding];
-    
+    NSData *hashedString = SRSHA1HashFromString(concattedString);
+    NSString *expectedAccept = SRBase64EncodedStringFromData(hashedString);
     return [acceptHeader isEqualToString:expectedAccept];
 }
 
@@ -1627,74 +1540,6 @@ static const size_t SRFrameHeaderOverhead = 32;
 
 @end
 
-
-@implementation SRIOConsumer
-
-@synthesize bytesNeeded = _bytesNeeded;
-@synthesize consumer = _scanner;
-@synthesize handler = _handler;
-@synthesize readToCurrentFrame = _readToCurrentFrame;
-@synthesize unmaskBytes = _unmaskBytes;
-
-- (void)setupWithScanner:(stream_scanner)scanner handler:(data_callback)handler bytesNeeded:(size_t)bytesNeeded readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes;
-{
-    _scanner = [scanner copy];
-    _handler = [handler copy];
-    _bytesNeeded = bytesNeeded;
-    _readToCurrentFrame = readToCurrentFrame;
-    _unmaskBytes = unmaskBytes;
-    assert(_scanner || _bytesNeeded);
-}
-
-
-@end
-
-
-@implementation SRIOConsumerPool {
-    NSUInteger _poolSize;
-    NSMutableArray<SRIOConsumer *> *_bufferedConsumers;
-}
-
-- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;
-{
-    self = [super init];
-    if (self) {
-        _poolSize = poolSize;
-        _bufferedConsumers = [NSMutableArray arrayWithCapacity:poolSize];
-    }
-    return self;
-}
-
-- (instancetype)init
-{
-    return [self initWithBufferCapacity:8];
-}
-
-- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner handler:(data_callback)handler bytesNeeded:(size_t)bytesNeeded readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes;
-{
-    SRIOConsumer *consumer = nil;
-    if (_bufferedConsumers.count) {
-        consumer = [_bufferedConsumers lastObject];
-        [_bufferedConsumers removeLastObject];
-    } else {
-        consumer = [[SRIOConsumer alloc] init];
-    }
-    
-    [consumer setupWithScanner:scanner handler:handler bytesNeeded:bytesNeeded readToCurrentFrame:readToCurrentFrame unmaskBytes:unmaskBytes];
-    
-    return consumer;
-}
-
-- (void)returnConsumer:(SRIOConsumer *)consumer;
-{
-    if (_bufferedConsumers.count < _poolSize) {
-        [_bufferedConsumers addObject:consumer];
-    }
-}
-
-@end
-
-
 @implementation  NSURLRequest (SRCertificateAdditions)
 
 - (NSArray *)SR_SSLPinnedCertificates;
@@ -1826,7 +1671,7 @@ static inline int32_t validate_dispatch_data_partial_string(NSData *data) {
 
 #endif
 
-static _SRRunLoopThread *networkThread = nil;
+static SRRunLoopThread *networkThread = nil;
 static NSRunLoop *networkRunLoop = nil;
 
 @implementation NSRunLoop (SRWebSocket)
@@ -1834,7 +1679,7 @@ static NSRunLoop *networkRunLoop = nil;
 + (NSRunLoop *)SR_networkRunLoop {
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
-        networkThread = [[_SRRunLoopThread alloc] init];
+        networkThread = [[SRRunLoopThread alloc] init];
         networkThread.name = @"com.squareup.SocketRocket.NetworkThread";
         [networkThread start];
         networkRunLoop = networkThread.runLoop;
@@ -1844,63 +1689,3 @@ static NSRunLoop *networkRunLoop = nil;
 }
 
 @end
-
-
-@implementation _SRRunLoopThread {
-    dispatch_group_t _waitGroup;
-}
-
-@synthesize runLoop = _runLoop;
-
-- (void)dealloc
-{
-    sr_dispatch_release(_waitGroup);
-}
-
-- (instancetype)init
-{
-    self = [super init];
-    if (self) {
-        _waitGroup = dispatch_group_create();
-        dispatch_group_enter(_waitGroup);
-    }
-    return self;
-}
-
-- (void)main;
-{
-    @autoreleasepool {
-        _runLoop = [NSRunLoop currentRunLoop];
-        dispatch_group_leave(_waitGroup);
-        
-        // Add an empty run loop source to prevent runloop from spinning.
-        CFRunLoopSourceContext sourceCtx = {
-            .version = 0,
-            .info = NULL,
-            .retain = NULL,
-            .release = NULL,
-            .copyDescription = NULL,
-            .equal = NULL,
-            .hash = NULL,
-            .schedule = NULL,
-            .cancel = NULL,
-            .perform = NULL
-        };
-        CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);
-        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
-        CFRelease(source);
-        
-        while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
-            
-        }
-        assert(NO);
-    }
-}
-
-- (NSRunLoop *)runLoop;
-{
-    dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);
-    return _runLoop;
-}
-
-@end