Compare commits
24 Commits
master
...
lewis/disp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95de1ea335 | ||
|
|
e3c402beab | ||
|
|
f616386954 | ||
|
|
61b19ab633 | ||
|
|
c62bfb90ad | ||
|
|
d7078b082c | ||
|
|
49c79072d2 | ||
|
|
a797a0f568 | ||
|
|
7c6e18e858 | ||
|
|
e6c3850c9b | ||
|
|
fe572dc752 | ||
|
|
9b0d5134f8 | ||
|
|
1883c521d6 | ||
|
|
5214ed5347 | ||
|
|
7ea9d25976 | ||
|
|
5278664ab7 | ||
|
|
2a2ed772c3 | ||
|
|
d237938434 | ||
|
|
ac861d6ff2 | ||
|
|
2ab4b7d421 | ||
|
|
edd6faceed | ||
|
|
f58b21618c | ||
|
|
fdf93c6f9c | ||
|
|
72f7f81ff4 |
@ -107,6 +107,7 @@
|
||||
|
||||
- (NSUInteger)testCaseCount;
|
||||
{
|
||||
return 0;
|
||||
if (self.invocation) {
|
||||
return [super testCaseCount];
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.squareup.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
13
SRWebSocketTests/STRDispatchTest.h
Normal file
13
SRWebSocketTests/STRDispatchTest.h
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// STRDispatchTest.h
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#import <SenTestingKit/SenTestingKit.h>
|
||||
|
||||
@interface STRDispatchTest : SenTestCase
|
||||
|
||||
@end
|
||||
151
SRWebSocketTests/STRDispatchTest.mm
Normal file
151
SRWebSocketTests/STRDispatchTest.mm
Normal file
@ -0,0 +1,151 @@
|
||||
//
|
||||
// STRDispatchTest.m
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
extern "C" {
|
||||
#import <SenTestingKit/SenTestingKit.h>
|
||||
}
|
||||
|
||||
#include <Security/SecureTransport.h>
|
||||
|
||||
#include "DispatchIO.h"
|
||||
#include "DispatchData.h"
|
||||
#include "SecureIO.h"
|
||||
|
||||
using namespace squareup::dispatch;
|
||||
|
||||
@interface STRDispatchTest : SenTestCase
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation STRDispatchTest
|
||||
|
||||
- (void)testConnect;
|
||||
{
|
||||
bool finished = false;
|
||||
dispatch_queue_t workQueue = dispatch_queue_create("dispatch queue", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
Dial(workQueue, "localhost", "9932", dispatch_get_main_queue(), [&](dispatch_fd_t fd, int error_code, const char *error_message) {
|
||||
NSLog(@"code: %d, msg: %s", error_code, error_message);
|
||||
STAssertEquals(error_code, 0, @"Should not error but got %s", error_message);
|
||||
finished = true;
|
||||
});
|
||||
|
||||
[self runCurrentRunLoopUntilTestPasses:[&finished](){
|
||||
return (BOOL)finished;
|
||||
} timeout:100.0];
|
||||
}
|
||||
|
||||
|
||||
- (void)testSimpleDial;
|
||||
{
|
||||
RawIO *raw_io = nullptr;
|
||||
bool finished = false;
|
||||
|
||||
auto cleanupBlock = [&finished](int error) {
|
||||
finished = true;
|
||||
};
|
||||
|
||||
SimpleDial("localhost", "9934", dispatch_get_main_queue(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [&raw_io, self, &finished](squareup::dispatch::RawIO *io, int error, const char *error_message) {
|
||||
|
||||
STAssertEquals(error, 0, @"Should not have errored, but got %s", error_message);
|
||||
STAssertTrue(io != nullptr, @"io should be valid");
|
||||
|
||||
|
||||
if (!io) {
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
raw_io = io;
|
||||
|
||||
io->Write(Data("HELLO THERE!", dispatch_get_main_queue()), dispatch_get_main_queue(), [self, &raw_io](bool done, dispatch_data_t data, int error) {
|
||||
STAssertEquals(error, 0, @"Error should == 0");
|
||||
if (done) {
|
||||
raw_io->Close(0);
|
||||
}
|
||||
});
|
||||
|
||||
}, cleanupBlock);
|
||||
|
||||
[self runCurrentRunLoopUntilTestPasses:[&finished](){
|
||||
return (BOOL)finished;
|
||||
} timeout:100.0];
|
||||
}
|
||||
|
||||
- (void)testDialTLS;
|
||||
{
|
||||
SecureIO *raw_io = nullptr;
|
||||
bool finished = false;
|
||||
|
||||
auto cleanupBlock = [&finished, raw_io](int error) {
|
||||
dispatch_async(dispatch_get_main_queue(), [raw_io]{
|
||||
delete raw_io;
|
||||
});
|
||||
NSLog(@"FINISHED");
|
||||
finished = true;
|
||||
};
|
||||
|
||||
SSLContextRef ctx = SSLCreateContext(CFAllocatorGetDefault(), kSSLClientSide, kSSLStreamType);
|
||||
|
||||
DialTLS("10.0.1.15", "10248", ctx, dispatch_get_main_queue(), dispatch_get_main_queue(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [&raw_io, self, &finished](squareup::dispatch::SecureIO *io, int error, const char *error_message) {
|
||||
|
||||
STAssertEquals(error, 0, @"Should not have errored, but got %s", error_message);
|
||||
STAssertTrue(io != nullptr, @"io should be valid");
|
||||
|
||||
if (!io) {
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
raw_io = io;
|
||||
|
||||
__block bool seenInner = false;
|
||||
__block bool seenOuter = false;
|
||||
//
|
||||
// raw_io->Write(Data("HELLO THERE!\n", dispatch_get_main_queue()), ^(bool done, dispatch_data_t data, int error) {
|
||||
// STAssertEquals(error, 0, @"Error should == 0");
|
||||
// STAssertFalse(seenOuter, @"Should only see the outer once");
|
||||
// if (done) {
|
||||
// seenOuter = true;
|
||||
// }
|
||||
// if (done && !error) {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// raw_io->Write(Data("HELLO THERE2!\n", dispatch_get_main_queue()), ^(bool done, dispatch_data_t data, int error) {
|
||||
// STAssertFalse(seenInner, @"Shouldn't have seen inner yet");
|
||||
// if (done) {
|
||||
// seenInner = done;
|
||||
// }
|
||||
// STAssertEquals(error, 0, @"Error should == 0");
|
||||
// STAssertFalse(finished, @"Shouldn't have finished");
|
||||
// });
|
||||
|
||||
|
||||
raw_io->Read(SIZE_MAX, dispatch_get_main_queue(), ^(bool done, dispatch_data_t data, int error) {
|
||||
if (!error) {
|
||||
raw_io->Write(data, dispatch_get_main_queue(), ^(bool done, dispatch_data_t data, int error) {
|
||||
|
||||
});
|
||||
} else {
|
||||
STAssertTrue(error == ECANCELED, @"Server should terminate");
|
||||
|
||||
if (done && !error) {
|
||||
raw_io->Close(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}, cleanupBlock);
|
||||
|
||||
[self runCurrentRunLoopUntilTestPasses:[&finished](){
|
||||
return (BOOL)finished;
|
||||
} timeout:100.0];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,4 +1,4 @@
|
||||
//
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@ -7,17 +7,31 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2725F85B16A29D18007018E9 /* SecureIO.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2725F85916A29D18007018E9 /* SecureIO.mm */; };
|
||||
2725F85C16A29D18007018E9 /* SecureIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 2725F85A16A29D18007018E9 /* SecureIO.h */; };
|
||||
27CA136116A21E4D00A35C2D /* DispatchIO.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27CA135F16A21E4D00A35C2D /* DispatchIO.mm */; };
|
||||
27CA136216A21E4D00A35C2D /* DispatchIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 27CA136016A21E4D00A35C2D /* DispatchIO.h */; };
|
||||
27CA136616A2243000A35C2D /* DispatchData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27CA136416A2243000A35C2D /* DispatchData.mm */; };
|
||||
27CA136716A2243000A35C2D /* DispatchData.h in Headers */ = {isa = PBXBuildFile; fileRef = 27CA136516A2243000A35C2D /* DispatchData.h */; };
|
||||
27CA136A16A23AAE00A35C2D /* STRDispatchTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27CA136916A23AAE00A35C2D /* STRDispatchTest.mm */; };
|
||||
27DC4A9516A64EB800E9C084 /* Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 27DC4A9416A64EB800E9C084 /* Common.h */; };
|
||||
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 */; };
|
||||
F60CC2A114D4EA0500A005E4 /* SRTWebSocketOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F60CC2A014D4EA0500A005E4 /* SRTWebSocketOperation.m */; };
|
||||
F6191F3B1B6C4694003DF396 /* SystemShims.h in Headers */ = {isa = PBXBuildFile; fileRef = F6191F3A1B6C4694003DF396 /* SystemShims.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F6191F4D1B6C4694003DF396 /* SystemShims.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6191F381B6C4694003DF396 /* SystemShims.framework */; };
|
||||
F6191F4E1B6C4694003DF396 /* SystemShims.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F6191F381B6C4694003DF396 /* SystemShims.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
F6191F581B6C46B1003DF396 /* SystemShims.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6191F381B6C4694003DF396 /* SystemShims.framework */; };
|
||||
F6191F5A1B6C46D2003DF396 /* SystemShims.m in Sources */ = {isa = PBXBuildFile; fileRef = F6191F591B6C46D2003DF396 /* SystemShims.m */; };
|
||||
F6191F5C1B6C5598003DF396 /* IOTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6191F5B1B6C5598003DF396 /* IOTests.swift */; };
|
||||
F61A0DC81625F44D00365EBD /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F61A0DC71625F44D00365EBD /* Default-568h@2x.png */; };
|
||||
F62417E614D52F3C003CE997 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F62417E514D52F3C003CE997 /* UIKit.framework */; };
|
||||
F62417E714D52F3C003CE997 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };
|
||||
F62417E914D52F3C003CE997 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F62417E814D52F3C003CE997 /* CoreGraphics.framework */; };
|
||||
F62417EF14D52F3C003CE997 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F62417ED14D52F3C003CE997 /* InfoPlist.strings */; };
|
||||
F62417F114D52F3C003CE997 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417F014D52F3C003CE997 /* main.m */; };
|
||||
F62417F514D52F3C003CE997 /* TCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417F414D52F3C003CE997 /* TCAppDelegate.m */; };
|
||||
F62417F514D52F3C003CE997 /* TCAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = F62417F414D52F3C003CE997 /* TCAppDelegate.mm */; };
|
||||
F62417F814D52F3C003CE997 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F62417F614D52F3C003CE997 /* MainStoryboard.storyboard */; };
|
||||
F62417FB14D52F3C003CE997 /* TCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417FA14D52F3C003CE997 /* TCViewController.m */; };
|
||||
F624180114D5300C003CE997 /* TCChatCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F624180014D5300C003CE997 /* TCChatCell.m */; };
|
||||
@ -25,24 +39,57 @@
|
||||
F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
|
||||
F624180414D53449003CE997 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };
|
||||
F624180614D53451003CE997 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C41C95145F7C4700641356 /* libicucore.dylib */; };
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.mm */; };
|
||||
F668C899153E923C0044DBAC /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396BA4153E6D7400345B5E /* CoreServices.framework */; };
|
||||
F668C89A153E923C0044DBAC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396BA1153E6D4800345B5E /* Foundation.framework */; };
|
||||
F668C89B153E923C0044DBAC /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396B9F153E6D3700345B5E /* Security.framework */; };
|
||||
F668C8AA153E92F90044DBAC /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F69DAA171B6AEF6900B456D0 /* SocketRocketIO.h in Headers */ = {isa = PBXBuildFile; fileRef = F69DAA161B6AEF6900B456D0 /* SocketRocketIO.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F69DAA1E1B6AEF6900B456D0 /* SocketRocketIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F69DAA141B6AEF6900B456D0 /* SocketRocketIO.framework */; };
|
||||
F69DAA231B6AEF6900B456D0 /* SocketRocketIOTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69DAA221B6AEF6900B456D0 /* SocketRocketIOTests.swift */; };
|
||||
F69DAA2C1B6AF09B00B456D0 /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69DAA2B1B6AF09B00B456D0 /* IO.swift */; };
|
||||
F69DAA2E1B6AF0CF00B456D0 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69DAA2D1B6AF0CF00B456D0 /* Queue.swift */; };
|
||||
F69DAA521B6AF53F00B456D0 /* QueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69DAA511B6AF53F00B456D0 /* QueueTests.swift */; };
|
||||
F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.mm */; };
|
||||
F6A2077C1B73E5B7002C359E /* Fixtures in Resources */ = {isa = PBXBuildFile; fileRef = F6A2077B1B73E5B7002C359E /* Fixtures */; };
|
||||
F6A2077E1B73E5EA002C359E /* QueueStreamableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A2077D1B73E5EA002C359E /* QueueStreamableTests.swift */; };
|
||||
F6AD27211B70547200756377 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AD27201B70547200756377 /* Promise.swift */; };
|
||||
F6AD27231B70550C00756377 /* ErrorOptional.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AD27221B70550C00756377 /* ErrorOptional.swift */; };
|
||||
F6AD27251B705DAB00756377 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AD27241B705DAB00756377 /* Lock.swift */; };
|
||||
F6AD27271B707EFA00756377 /* PromisesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AD27261B707EFA00756377 /* PromisesTests.swift */; };
|
||||
F6AD390B1B73FE52001D93F5 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AD390A1B73FE52001D93F5 /* Extensions.swift */; };
|
||||
F6AE451D145906A70022AF3C /* libSocketRocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B2082D1450F597009315AF /* libSocketRocket.a */; };
|
||||
F6AE4520145906B20022AF3C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };
|
||||
F6AE45241459071C0022AF3C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
|
||||
F6AE4528145907D30022AF3C /* SenTestCase+SRTAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6AE4527145907D30022AF3C /* SenTestCase+SRTAdditions.m */; };
|
||||
F6B24CB61B75364100664E0B /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6B24CB51B75364100664E0B /* Error.swift */; };
|
||||
F6BDA806145900D200FE3253 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };
|
||||
F6BDA80C145900D200FE3253 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F6BDA80A145900D200FE3253 /* InfoPlist.strings */; };
|
||||
F6BDA8161459016900FE3253 /* SRTAutobahnTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F6BDA8151459016900FE3253 /* SRTAutobahnTests.m */; };
|
||||
F6C41C98145F7C6100641356 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C41C95145F7C4700641356 /* libicucore.dylib */; };
|
||||
F6E95FF01B72DA580019AAF0 /* QueueStreamable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E95FEE1B72D8080019AAF0 /* QueueStreamable.swift */; };
|
||||
F6FC407A1B74872D0007246E /* Unicode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6FC40791B74872D0007246E /* Unicode.swift */; };
|
||||
F6FC407C1B7487630007246E /* UnicodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6FC407B1B7487630007246E /* UnicodeTests.swift */; };
|
||||
F6FC407E1B751F330007246E /* Concurrent.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6FC407D1B751F330007246E /* Concurrent.swift */; };
|
||||
F6FC40801B75244A0007246E /* ConcurrentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6FC407F1B75244A0007246E /* ConcurrentTests.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
F6191F4B1B6C4694003DF396 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F6B208241450F597009315AF /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = F6191F371B6C4694003DF396;
|
||||
remoteInfo = SystemShims;
|
||||
};
|
||||
F6191F561B6C46AD003DF396 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F6B208241450F597009315AF /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = F6191F371B6C4694003DF396;
|
||||
remoteInfo = SystemShims;
|
||||
};
|
||||
F62417D514D50869003CE997 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F6B208241450F597009315AF /* Project object */;
|
||||
@ -50,11 +97,45 @@
|
||||
remoteGlobalIDString = F6B2082C1450F597009315AF;
|
||||
remoteInfo = SocketRocket;
|
||||
};
|
||||
F69DAA1F1B6AEF6900B456D0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F6B208241450F597009315AF /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = F69DAA131B6AEF6900B456D0;
|
||||
remoteInfo = SocketRocketIO;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
F6191F541B6C4694003DF396 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
F6191F4E1B6C4694003DF396 /* SystemShims.framework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2725F85916A29D18007018E9 /* SecureIO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SecureIO.mm; sourceTree = "<group>"; };
|
||||
2725F85A16A29D18007018E9 /* SecureIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecureIO.h; sourceTree = "<group>"; };
|
||||
27CA135F16A21E4D00A35C2D /* DispatchIO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatchIO.mm; sourceTree = "<group>"; };
|
||||
27CA136016A21E4D00A35C2D /* DispatchIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchIO.h; sourceTree = "<group>"; };
|
||||
27CA136416A2243000A35C2D /* DispatchData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatchData.mm; sourceTree = "<group>"; };
|
||||
27CA136516A2243000A35C2D /* DispatchData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchData.h; sourceTree = "<group>"; };
|
||||
27CA136916A23AAE00A35C2D /* STRDispatchTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = STRDispatchTest.mm; sourceTree = "<group>"; };
|
||||
27DC4A9416A64EB800E9C084 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; 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>"; };
|
||||
F6191F381B6C4694003DF396 /* SystemShims.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SystemShims.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F6191F3A1B6C4694003DF396 /* SystemShims.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemShims.h; sourceTree = "<group>"; };
|
||||
F6191F3C1B6C4694003DF396 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
F6191F591B6C46D2003DF396 /* SystemShims.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SystemShims.m; sourceTree = "<group>"; };
|
||||
F6191F5B1B6C5598003DF396 /* IOTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IOTests.swift; 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>"; };
|
||||
F62417E314D52F3C003CE997 /* TestChat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestChat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F62417E514D52F3C003CE997 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
@ -64,7 +145,7 @@
|
||||
F62417F014D52F3C003CE997 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
F62417F214D52F3C003CE997 /* TestChat-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestChat-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F62417F314D52F3C003CE997 /* TCAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TCAppDelegate.h; sourceTree = "<group>"; };
|
||||
F62417F414D52F3C003CE997 /* TCAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TCAppDelegate.m; sourceTree = "<group>"; };
|
||||
F62417F414D52F3C003CE997 /* TCAppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TCAppDelegate.mm; sourceTree = "<group>"; };
|
||||
F62417F714D52F3C003CE997 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
F62417F914D52F3C003CE997 /* TCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TCViewController.h; sourceTree = "<group>"; };
|
||||
F62417FA14D52F3C003CE997 /* TCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TCViewController.m; sourceTree = "<group>"; };
|
||||
@ -78,30 +159,60 @@
|
||||
F668C885153E91210044DBAC /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
F668C886153E91210044DBAC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
F668C889153E91210044DBAC /* SocketRocketOSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SocketRocketOSX-Info.plist"; sourceTree = "<group>"; };
|
||||
F69DAA141B6AEF6900B456D0 /* SocketRocketIO.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocketIO.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F69DAA161B6AEF6900B456D0 /* SocketRocketIO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SocketRocketIO.h; sourceTree = "<group>"; };
|
||||
F69DAA181B6AEF6900B456D0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
F69DAA1D1B6AEF6900B456D0 /* SocketRocketIOTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SocketRocketIOTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F69DAA221B6AEF6900B456D0 /* SocketRocketIOTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketRocketIOTests.swift; sourceTree = "<group>"; };
|
||||
F69DAA241B6AEF6900B456D0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
F69DAA2B1B6AF09B00B456D0 /* IO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IO.swift; sourceTree = "<group>"; };
|
||||
F69DAA2D1B6AF0CF00B456D0 /* Queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = "<group>"; };
|
||||
F69DAA511B6AF53F00B456D0 /* QueueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueueTests.swift; sourceTree = "<group>"; };
|
||||
F6A12CCF145119B700C1D980 /* SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRWebSocket.h; sourceTree = "<group>"; };
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRWebSocket.m; sourceTree = "<group>"; };
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SRWebSocket.mm; sourceTree = "<group>"; };
|
||||
F6A12CD3145122FC00C1D980 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
F6A12CD51451231B00C1D980 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
F6A2077B1B73E5B7002C359E /* Fixtures */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Fixtures; sourceTree = "<group>"; };
|
||||
F6A2077D1B73E5EA002C359E /* QueueStreamableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueueStreamableTests.swift; sourceTree = "<group>"; };
|
||||
F6AD27201B70547200756377 /* Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = "<group>"; };
|
||||
F6AD27221B70550C00756377 /* ErrorOptional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorOptional.swift; sourceTree = "<group>"; };
|
||||
F6AD27241B705DAB00756377 /* Lock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lock.swift; sourceTree = "<group>"; };
|
||||
F6AD27261B707EFA00756377 /* PromisesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromisesTests.swift; sourceTree = "<group>"; };
|
||||
F6AD390A1B73FE52001D93F5 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
|
||||
F6AE4526145907D30022AF3C /* SenTestCase+SRTAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SenTestCase+SRTAdditions.h"; sourceTree = "<group>"; };
|
||||
F6AE4527145907D30022AF3C /* SenTestCase+SRTAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SenTestCase+SRTAdditions.m"; sourceTree = "<group>"; };
|
||||
F6B2082D1450F597009315AF /* libSocketRocket.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSocketRocket.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F6B208301450F597009315AF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
F6B208341450F597009315AF /* SocketRocket-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SocketRocket-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F6B24CB51B75364100664E0B /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = "<group>"; };
|
||||
F6BDA802145900D200FE3253 /* SRWebSocketTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SRWebSocketTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F6BDA809145900D200FE3253 /* SRWebSocketTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SRWebSocketTests-Info.plist"; sourceTree = "<group>"; };
|
||||
F6BDA80B145900D200FE3253 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
F6BDA810145900D200FE3253 /* SRWebSocketTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SRWebSocketTests-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F6BDA8151459016900FE3253 /* SRTAutobahnTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRTAutobahnTests.m; sourceTree = "<group>"; };
|
||||
F6C41C95145F7C4700641356 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = usr/lib/libicucore.dylib; sourceTree = SDKROOT; };
|
||||
F6E95FEE1B72D8080019AAF0 /* QueueStreamable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = QueueStreamable.swift; path = SocketRocketIOTests/QueueStreamable.swift; sourceTree = SOURCE_ROOT; };
|
||||
F6FC40791B74872D0007246E /* Unicode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unicode.swift; sourceTree = "<group>"; };
|
||||
F6FC407B1B7487630007246E /* UnicodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnicodeTests.swift; sourceTree = "<group>"; };
|
||||
F6FC407D1B751F330007246E /* Concurrent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Concurrent.swift; sourceTree = "<group>"; };
|
||||
F6FC407F1B75244A0007246E /* ConcurrentTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentTests.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
F6191F341B6C4694003DF396 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F62417E014D52F3C003CE997 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F62417E614D52F3C003CE997 /* UIKit.framework in Frameworks */,
|
||||
F62417E714D52F3C003CE997 /* Foundation.framework in Frameworks */,
|
||||
F6191F4D1B6C4694003DF396 /* SystemShims.framework in Frameworks */,
|
||||
F62417E914D52F3C003CE997 /* CoreGraphics.framework in Frameworks */,
|
||||
F624180214D532E0003CE997 /* libSocketRocket.a in Frameworks */,
|
||||
F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */,
|
||||
@ -120,6 +231,22 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA101B6AEF6900B456D0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6191F581B6C46B1003DF396 /* SystemShims.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA1A1B6AEF6900B456D0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F69DAA1E1B6AEF6900B456D0 /* SocketRocketIO.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6B2082A1450F597009315AF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -145,12 +272,22 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
F6191F391B6C4694003DF396 /* SystemShims */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6191F3A1B6C4694003DF396 /* SystemShims.h */,
|
||||
F6191F3C1B6C4694003DF396 /* Info.plist */,
|
||||
F6191F591B6C46D2003DF396 /* SystemShims.m */,
|
||||
);
|
||||
path = SystemShims;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F62417EA14D52F3C003CE997 /* TestChat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F62417EB14D52F3C003CE997 /* Supporting Files */,
|
||||
F62417F314D52F3C003CE997 /* TCAppDelegate.h */,
|
||||
F62417F414D52F3C003CE997 /* TCAppDelegate.m */,
|
||||
F62417F414D52F3C003CE997 /* TCAppDelegate.mm */,
|
||||
F62417F614D52F3C003CE997 /* MainStoryboard.storyboard */,
|
||||
F62417F914D52F3C003CE997 /* TCViewController.h */,
|
||||
F62417FA14D52F3C003CE997 /* TCViewController.m */,
|
||||
@ -200,6 +337,41 @@
|
||||
path = SocketRocketOSX;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F69DAA151B6AEF6900B456D0 /* SocketRocketIO */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F69DAA161B6AEF6900B456D0 /* SocketRocketIO.h */,
|
||||
F69DAA181B6AEF6900B456D0 /* Info.plist */,
|
||||
F69DAA2B1B6AF09B00B456D0 /* IO.swift */,
|
||||
F69DAA2D1B6AF0CF00B456D0 /* Queue.swift */,
|
||||
F6AD27201B70547200756377 /* Promise.swift */,
|
||||
F6AD27221B70550C00756377 /* ErrorOptional.swift */,
|
||||
F6AD27241B705DAB00756377 /* Lock.swift */,
|
||||
F6E95FEE1B72D8080019AAF0 /* QueueStreamable.swift */,
|
||||
F6AD390A1B73FE52001D93F5 /* Extensions.swift */,
|
||||
F6FC40791B74872D0007246E /* Unicode.swift */,
|
||||
F6FC407D1B751F330007246E /* Concurrent.swift */,
|
||||
F6B24CB51B75364100664E0B /* Error.swift */,
|
||||
);
|
||||
path = SocketRocketIO;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F69DAA211B6AEF6900B456D0 /* SocketRocketIOTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6A2077B1B73E5B7002C359E /* Fixtures */,
|
||||
F69DAA221B6AEF6900B456D0 /* SocketRocketIOTests.swift */,
|
||||
F69DAA241B6AEF6900B456D0 /* Info.plist */,
|
||||
F69DAA511B6AF53F00B456D0 /* QueueTests.swift */,
|
||||
F6191F5B1B6C5598003DF396 /* IOTests.swift */,
|
||||
F6AD27261B707EFA00756377 /* PromisesTests.swift */,
|
||||
F6A2077D1B73E5EA002C359E /* QueueStreamableTests.swift */,
|
||||
F6FC407B1B7487630007246E /* UnicodeTests.swift */,
|
||||
F6FC407F1B75244A0007246E /* ConcurrentTests.swift */,
|
||||
);
|
||||
path = SocketRocketIOTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6B208221450F597009315AF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -207,6 +379,9 @@
|
||||
F6BDA807145900D200FE3253 /* SRWebSocketTests */,
|
||||
F62417EA14D52F3C003CE997 /* TestChat */,
|
||||
F668C887153E91210044DBAC /* SocketRocketOSX */,
|
||||
F69DAA151B6AEF6900B456D0 /* SocketRocketIO */,
|
||||
F69DAA211B6AEF6900B456D0 /* SocketRocketIOTests */,
|
||||
F6191F391B6C4694003DF396 /* SystemShims */,
|
||||
F6B2082F1450F597009315AF /* Frameworks */,
|
||||
F6B2082E1450F597009315AF /* Products */,
|
||||
);
|
||||
@ -221,6 +396,9 @@
|
||||
F6BDA802145900D200FE3253 /* SRWebSocketTests.xctest */,
|
||||
F62417E314D52F3C003CE997 /* TestChat.app */,
|
||||
F668C880153E91210044DBAC /* SocketRocket.framework */,
|
||||
F69DAA141B6AEF6900B456D0 /* SocketRocketIO.framework */,
|
||||
F69DAA1D1B6AEF6900B456D0 /* SocketRocketIOTests.xctest */,
|
||||
F6191F381B6C4694003DF396 /* SystemShims.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -245,7 +423,14 @@
|
||||
children = (
|
||||
F6B208331450F597009315AF /* Supporting Files */,
|
||||
F6A12CCF145119B700C1D980 /* SRWebSocket.h */,
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.m */,
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.mm */,
|
||||
27CA135F16A21E4D00A35C2D /* DispatchIO.mm */,
|
||||
27CA136016A21E4D00A35C2D /* DispatchIO.h */,
|
||||
2725F85916A29D18007018E9 /* SecureIO.mm */,
|
||||
2725F85A16A29D18007018E9 /* SecureIO.h */,
|
||||
27CA136416A2243000A35C2D /* DispatchData.mm */,
|
||||
27CA136516A2243000A35C2D /* DispatchData.h */,
|
||||
27DC4A9416A64EB800E9C084 /* Common.h */,
|
||||
);
|
||||
path = SocketRocket;
|
||||
sourceTree = "<group>";
|
||||
@ -268,6 +453,7 @@
|
||||
F6AE4527145907D30022AF3C /* SenTestCase+SRTAdditions.m */,
|
||||
F60CC29F14D4EA0500A005E4 /* SRTWebSocketOperation.h */,
|
||||
F60CC2A014D4EA0500A005E4 /* SRTWebSocketOperation.m */,
|
||||
27CA136916A23AAE00A35C2D /* STRDispatchTest.mm */,
|
||||
);
|
||||
path = SRWebSocketTests;
|
||||
sourceTree = "<group>";
|
||||
@ -284,6 +470,14 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
F6191F351B6C4694003DF396 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6191F3B1B6C4694003DF396 /* SystemShims.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F668C87D153E91210044DBAC /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -292,17 +486,47 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA111B6AEF6900B456D0 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F69DAA171B6AEF6900B456D0 /* SocketRocketIO.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6B2082B1450F597009315AF /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */,
|
||||
27CA136216A21E4D00A35C2D /* DispatchIO.h in Headers */,
|
||||
27CA136716A2243000A35C2D /* DispatchData.h in Headers */,
|
||||
2725F85C16A29D18007018E9 /* SecureIO.h in Headers */,
|
||||
27DC4A9516A64EB800E9C084 /* Common.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
F6191F371B6C4694003DF396 /* SystemShims */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F6191F531B6C4694003DF396 /* Build configuration list for PBXNativeTarget "SystemShims" */;
|
||||
buildPhases = (
|
||||
F6191F331B6C4694003DF396 /* Sources */,
|
||||
F6191F341B6C4694003DF396 /* Frameworks */,
|
||||
F6191F351B6C4694003DF396 /* Headers */,
|
||||
F6191F361B6C4694003DF396 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SystemShims;
|
||||
productName = SystemShims;
|
||||
productReference = F6191F381B6C4694003DF396 /* SystemShims.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
F62417E214D52F3C003CE997 /* TestChat */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F62417FC14D52F3C003CE997 /* Build configuration list for PBXNativeTarget "TestChat" */;
|
||||
@ -310,10 +534,12 @@
|
||||
F62417DF14D52F3C003CE997 /* Sources */,
|
||||
F62417E014D52F3C003CE997 /* Frameworks */,
|
||||
F62417E114D52F3C003CE997 /* Resources */,
|
||||
F6191F541B6C4694003DF396 /* Embed Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
F6191F4C1B6C4694003DF396 /* PBXTargetDependency */,
|
||||
);
|
||||
name = TestChat;
|
||||
productName = TestChat;
|
||||
@ -338,6 +564,43 @@
|
||||
productReference = F668C880153E91210044DBAC /* SocketRocket.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
F69DAA131B6AEF6900B456D0 /* SocketRocketIO */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F69DAA291B6AEF6900B456D0 /* Build configuration list for PBXNativeTarget "SocketRocketIO" */;
|
||||
buildPhases = (
|
||||
F69DAA0F1B6AEF6900B456D0 /* Sources */,
|
||||
F69DAA101B6AEF6900B456D0 /* Frameworks */,
|
||||
F69DAA111B6AEF6900B456D0 /* Headers */,
|
||||
F69DAA121B6AEF6900B456D0 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
F6191F571B6C46AD003DF396 /* PBXTargetDependency */,
|
||||
);
|
||||
name = SocketRocketIO;
|
||||
productName = SocketRocketIO;
|
||||
productReference = F69DAA141B6AEF6900B456D0 /* SocketRocketIO.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
F69DAA1C1B6AEF6900B456D0 /* SocketRocketIOTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F69DAA2A1B6AEF6900B456D0 /* Build configuration list for PBXNativeTarget "SocketRocketIOTests" */;
|
||||
buildPhases = (
|
||||
F69DAA191B6AEF6900B456D0 /* Sources */,
|
||||
F69DAA1A1B6AEF6900B456D0 /* Frameworks */,
|
||||
F69DAA1B1B6AEF6900B456D0 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
F69DAA201B6AEF6900B456D0 /* PBXTargetDependency */,
|
||||
);
|
||||
name = SocketRocketIOTests;
|
||||
productName = SocketRocketIOTests;
|
||||
productReference = F69DAA1D1B6AEF6900B456D0 /* SocketRocketIOTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
F6B2082C1450F597009315AF /* SocketRocket */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F6B2083A1450F597009315AF /* Build configuration list for PBXNativeTarget "SocketRocket" */;
|
||||
@ -379,8 +642,20 @@
|
||||
F6B208241450F597009315AF /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastTestingUpgradeCheck = 0640;
|
||||
LastUpgradeCheck = 0640;
|
||||
LastUpgradeCheck = 0700;
|
||||
TargetAttributes = {
|
||||
F6191F371B6C4694003DF396 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
F69DAA131B6AEF6900B456D0 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
F69DAA1C1B6AEF6900B456D0 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = F6B208271450F597009315AF /* Build configuration list for PBXProject "SocketRocket" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@ -398,11 +673,21 @@
|
||||
F668C87F153E91210044DBAC /* SocketRocketOSX */,
|
||||
F6BDA801145900D200FE3253 /* SRWebSocketTests */,
|
||||
F62417E214D52F3C003CE997 /* TestChat */,
|
||||
F69DAA131B6AEF6900B456D0 /* SocketRocketIO */,
|
||||
F69DAA1C1B6AEF6900B456D0 /* SocketRocketIOTests */,
|
||||
F6191F371B6C4694003DF396 /* SystemShims */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
F6191F361B6C4694003DF396 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F62417E114D52F3C003CE997 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -420,6 +705,21 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA121B6AEF6900B456D0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA1B1B6AEF6900B456D0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6A2077C1B73E5B7002C359E /* Fixtures in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6BDA7FF145900D200FE3253 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -431,12 +731,20 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
F6191F331B6C4694003DF396 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6191F5A1B6C46D2003DF396 /* SystemShims.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F62417DF14D52F3C003CE997 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F62417F114D52F3C003CE997 /* main.m in Sources */,
|
||||
F62417F514D52F3C003CE997 /* TCAppDelegate.m in Sources */,
|
||||
F62417F514D52F3C003CE997 /* TCAppDelegate.mm in Sources */,
|
||||
F62417FB14D52F3C003CE997 /* TCViewController.m in Sources */,
|
||||
F624180114D5300C003CE997 /* TCChatCell.m in Sources */,
|
||||
);
|
||||
@ -446,7 +754,38 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */,
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA0F1B6AEF6900B456D0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6FC407E1B751F330007246E /* Concurrent.swift in Sources */,
|
||||
F69DAA2C1B6AF09B00B456D0 /* IO.swift in Sources */,
|
||||
F6E95FF01B72DA580019AAF0 /* QueueStreamable.swift in Sources */,
|
||||
F6AD27251B705DAB00756377 /* Lock.swift in Sources */,
|
||||
F69DAA2E1B6AF0CF00B456D0 /* Queue.swift in Sources */,
|
||||
F6AD27231B70550C00756377 /* ErrorOptional.swift in Sources */,
|
||||
F6AD27211B70547200756377 /* Promise.swift in Sources */,
|
||||
F6AD390B1B73FE52001D93F5 /* Extensions.swift in Sources */,
|
||||
F6B24CB61B75364100664E0B /* Error.swift in Sources */,
|
||||
F6FC407A1B74872D0007246E /* Unicode.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F69DAA191B6AEF6900B456D0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6191F5C1B6C5598003DF396 /* IOTests.swift in Sources */,
|
||||
F6A2077E1B73E5EA002C359E /* QueueStreamableTests.swift in Sources */,
|
||||
F69DAA231B6AEF6900B456D0 /* SocketRocketIOTests.swift in Sources */,
|
||||
F6FC407C1B7487630007246E /* UnicodeTests.swift in Sources */,
|
||||
F69DAA521B6AF53F00B456D0 /* QueueTests.swift in Sources */,
|
||||
F6AD27271B707EFA00756377 /* PromisesTests.swift in Sources */,
|
||||
F6FC40801B75244A0007246E /* ConcurrentTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -454,7 +793,10 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.m in Sources */,
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.mm in Sources */,
|
||||
27CA136116A21E4D00A35C2D /* DispatchIO.mm in Sources */,
|
||||
27CA136616A2243000A35C2D /* DispatchData.mm in Sources */,
|
||||
2725F85B16A29D18007018E9 /* SecureIO.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -465,17 +807,33 @@
|
||||
F6BDA8161459016900FE3253 /* SRTAutobahnTests.m in Sources */,
|
||||
F6AE4528145907D30022AF3C /* SenTestCase+SRTAdditions.m in Sources */,
|
||||
F60CC2A114D4EA0500A005E4 /* SRTWebSocketOperation.m in Sources */,
|
||||
27CA136A16A23AAE00A35C2D /* STRDispatchTest.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
F6191F4C1B6C4694003DF396 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F6191F371B6C4694003DF396 /* SystemShims */;
|
||||
targetProxy = F6191F4B1B6C4694003DF396 /* PBXContainerItemProxy */;
|
||||
};
|
||||
F6191F571B6C46AD003DF396 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F6191F371B6C4694003DF396 /* SystemShims */;
|
||||
targetProxy = F6191F561B6C46AD003DF396 /* PBXContainerItemProxy */;
|
||||
};
|
||||
F62417D614D50869003CE997 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F6B2082C1450F597009315AF /* SocketRocket */;
|
||||
targetProxy = F62417D514D50869003CE997 /* PBXContainerItemProxy */;
|
||||
};
|
||||
F69DAA201B6AEF6900B456D0 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F69DAA131B6AEF6900B456D0 /* SocketRocketIO */;
|
||||
targetProxy = F69DAA1F1B6AEF6900B456D0 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
@ -506,6 +864,75 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
F6191F4F1B6C4694003DF396 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
INFOPLIST_FILE = SystemShims/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.squareup.SystemShims;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F6191F501B6C4694003DF396 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
INFOPLIST_FILE = SystemShims/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.squareup.SystemShims;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F62417FD14D52F3C003CE997 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -517,8 +944,9 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "TestChat/TestChat-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestChat/TestChat-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.squareup.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WRAPPER_EXTENSION = app;
|
||||
@ -536,9 +964,10 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "TestChat/TestChat-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestChat/TestChat-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.squareup.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WRAPPER_EXTENSION = app;
|
||||
@ -564,6 +993,7 @@
|
||||
LD_DYLIB_INSTALL_NAME = "@executable_path/../Frameworks/$(EXECUTABLE_PATH)";
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.squareup.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = SocketRocket;
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
@ -589,12 +1019,133 @@
|
||||
INFOPLIST_FILE = "SocketRocketOSX/SocketRocketOSX-Info.plist";
|
||||
LD_DYLIB_INSTALL_NAME = "@executable_path/../Frameworks/$(EXECUTABLE_PATH)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.squareup.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = SocketRocket;
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F69DAA251B6AEF6900B456D0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
INFOPLIST_FILE = SocketRocketIO/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.squareup.SocketRocketIO;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F69DAA261B6AEF6900B456D0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
INFOPLIST_FILE = SocketRocketIO/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.squareup.SocketRocketIO;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F69DAA271B6AEF6900B456D0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
INFOPLIST_FILE = SocketRocketIOTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.squareup.SocketRocketIOTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F69DAA281B6AEF6900B456D0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
INFOPLIST_FILE = SocketRocketIOTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.squareup.SocketRocketIOTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F6B208381450F597009315AF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -610,6 +1161,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@ -726,6 +1278,7 @@
|
||||
"-framework",
|
||||
XCTest,
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.squareup.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
@ -746,6 +1299,7 @@
|
||||
"-framework",
|
||||
XCTest,
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.squareup.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
@ -753,6 +1307,15 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
F6191F531B6C4694003DF396 /* Build configuration list for PBXNativeTarget "SystemShims" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F6191F4F1B6C4694003DF396 /* Debug */,
|
||||
F6191F501B6C4694003DF396 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F62417FC14D52F3C003CE997 /* Build configuration list for PBXNativeTarget "TestChat" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
@ -771,6 +1334,24 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F69DAA291B6AEF6900B456D0 /* Build configuration list for PBXNativeTarget "SocketRocketIO" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F69DAA251B6AEF6900B456D0 /* Debug */,
|
||||
F69DAA261B6AEF6900B456D0 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F69DAA2A1B6AEF6900B456D0 /* Build configuration list for PBXNativeTarget "SocketRocketIOTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F69DAA271B6AEF6900B456D0 /* Debug */,
|
||||
F69DAA281B6AEF6900B456D0 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F6B208271450F597009315AF /* Build configuration list for PBXProject "SocketRocket" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
878
SocketRocket.xcodeproj/project.pbxproj.orig
Normal file
878
SocketRocket.xcodeproj/project.pbxproj.orig
Normal file
@ -0,0 +1,878 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
<<<<<<< HEAD
|
||||
2725F85B16A29D18007018E9 /* SecureIO.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2725F85916A29D18007018E9 /* SecureIO.mm */; };
|
||||
2725F85C16A29D18007018E9 /* SecureIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 2725F85A16A29D18007018E9 /* SecureIO.h */; };
|
||||
27CA136116A21E4D00A35C2D /* DispatchIO.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27CA135F16A21E4D00A35C2D /* DispatchIO.mm */; };
|
||||
27CA136216A21E4D00A35C2D /* DispatchIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 27CA136016A21E4D00A35C2D /* DispatchIO.h */; };
|
||||
27CA136616A2243000A35C2D /* DispatchData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27CA136416A2243000A35C2D /* DispatchData.mm */; };
|
||||
27CA136716A2243000A35C2D /* DispatchData.h in Headers */ = {isa = PBXBuildFile; fileRef = 27CA136516A2243000A35C2D /* DispatchData.h */; };
|
||||
27CA136A16A23AAE00A35C2D /* STRDispatchTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27CA136916A23AAE00A35C2D /* STRDispatchTest.mm */; };
|
||||
27DC4A9516A64EB800E9C084 /* Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 27DC4A9416A64EB800E9C084 /* Common.h */; };
|
||||
F6016C7C146124B20037BB3D /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = F6016C7B146124B20037BB3D /* base64.c */; };
|
||||
F6016C7F146124ED0037BB3D /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = F6016C7E146124ED0037BB3D /* base64.h */; };
|
||||
=======
|
||||
>>>>>>> origin/master
|
||||
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 */; };
|
||||
F60CC2A114D4EA0500A005E4 /* SRTWebSocketOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F60CC2A014D4EA0500A005E4 /* SRTWebSocketOperation.m */; };
|
||||
F61A0DC81625F44D00365EBD /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F61A0DC71625F44D00365EBD /* Default-568h@2x.png */; };
|
||||
F62417E614D52F3C003CE997 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F62417E514D52F3C003CE997 /* UIKit.framework */; };
|
||||
F62417E714D52F3C003CE997 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };
|
||||
F62417E914D52F3C003CE997 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F62417E814D52F3C003CE997 /* CoreGraphics.framework */; };
|
||||
F62417EF14D52F3C003CE997 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F62417ED14D52F3C003CE997 /* InfoPlist.strings */; };
|
||||
F62417F114D52F3C003CE997 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417F014D52F3C003CE997 /* main.m */; };
|
||||
F62417F514D52F3C003CE997 /* TCAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = F62417F414D52F3C003CE997 /* TCAppDelegate.mm */; };
|
||||
F62417F814D52F3C003CE997 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F62417F614D52F3C003CE997 /* MainStoryboard.storyboard */; };
|
||||
F62417FB14D52F3C003CE997 /* TCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417FA14D52F3C003CE997 /* TCViewController.m */; };
|
||||
F624180114D5300C003CE997 /* TCChatCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F624180014D5300C003CE997 /* TCChatCell.m */; };
|
||||
F624180214D532E0003CE997 /* libSocketRocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B2082D1450F597009315AF /* libSocketRocket.a */; };
|
||||
F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
|
||||
F624180414D53449003CE997 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };
|
||||
F624180614D53451003CE997 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C41C95145F7C4700641356 /* libicucore.dylib */; };
|
||||
<<<<<<< HEAD
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.mm */; };
|
||||
F6396B87153E67EC00345B5E /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = F6016C7B146124B20037BB3D /* base64.c */; };
|
||||
F6396B88153E67EC00345B5E /* NSData+SRB64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */; };
|
||||
F6572126146C7B6A00D6B8A9 /* NSData+SRB64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */; };
|
||||
=======
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };
|
||||
>>>>>>> origin/master
|
||||
F668C899153E923C0044DBAC /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396BA4153E6D7400345B5E /* CoreServices.framework */; };
|
||||
F668C89A153E923C0044DBAC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396BA1153E6D4800345B5E /* Foundation.framework */; };
|
||||
F668C89B153E923C0044DBAC /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396B9F153E6D3700345B5E /* Security.framework */; };
|
||||
F668C8AA153E92F90044DBAC /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
<<<<<<< HEAD
|
||||
F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; };
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.mm */; };
|
||||
=======
|
||||
F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };
|
||||
>>>>>>> origin/master
|
||||
F6AE451D145906A70022AF3C /* libSocketRocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B2082D1450F597009315AF /* libSocketRocket.a */; };
|
||||
F6AE4520145906B20022AF3C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };
|
||||
F6AE45241459071C0022AF3C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
|
||||
F6AE4528145907D30022AF3C /* SenTestCase+SRTAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6AE4527145907D30022AF3C /* SenTestCase+SRTAdditions.m */; };
|
||||
F6BDA806145900D200FE3253 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };
|
||||
F6BDA80C145900D200FE3253 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F6BDA80A145900D200FE3253 /* InfoPlist.strings */; };
|
||||
F6BDA8161459016900FE3253 /* SRTAutobahnTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F6BDA8151459016900FE3253 /* SRTAutobahnTests.m */; };
|
||||
F6C41C98145F7C6100641356 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C41C95145F7C4700641356 /* libicucore.dylib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
F62417D514D50869003CE997 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F6B208241450F597009315AF /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = F6B2082C1450F597009315AF;
|
||||
remoteInfo = SocketRocket;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
<<<<<<< HEAD
|
||||
2725F85916A29D18007018E9 /* SecureIO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SecureIO.mm; sourceTree = "<group>"; };
|
||||
2725F85A16A29D18007018E9 /* SecureIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecureIO.h; sourceTree = "<group>"; };
|
||||
27CA135F16A21E4D00A35C2D /* DispatchIO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatchIO.mm; sourceTree = "<group>"; };
|
||||
27CA136016A21E4D00A35C2D /* DispatchIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchIO.h; sourceTree = "<group>"; };
|
||||
27CA136416A2243000A35C2D /* DispatchData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatchData.mm; sourceTree = "<group>"; };
|
||||
27CA136516A2243000A35C2D /* DispatchData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchData.h; sourceTree = "<group>"; };
|
||||
27CA136916A23AAE00A35C2D /* STRDispatchTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = STRDispatchTest.mm; sourceTree = "<group>"; };
|
||||
27DC4A9416A64EB800E9C084 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = "<group>"; };
|
||||
F6016C7B146124B20037BB3D /* base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = base64.c; sourceTree = "<group>"; };
|
||||
F6016C7E146124ED0037BB3D /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base64.h; sourceTree = "<group>"; };
|
||||
=======
|
||||
>>>>>>> origin/master
|
||||
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>"; };
|
||||
F62417E314D52F3C003CE997 /* TestChat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestChat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F62417E514D52F3C003CE997 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
F62417E814D52F3C003CE997 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
F62417EC14D52F3C003CE997 /* TestChat-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TestChat-Info.plist"; sourceTree = "<group>"; };
|
||||
F62417EE14D52F3C003CE997 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
F62417F014D52F3C003CE997 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
F62417F214D52F3C003CE997 /* TestChat-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestChat-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F62417F314D52F3C003CE997 /* TCAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TCAppDelegate.h; sourceTree = "<group>"; };
|
||||
F62417F414D52F3C003CE997 /* TCAppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TCAppDelegate.mm; sourceTree = "<group>"; };
|
||||
F62417F714D52F3C003CE997 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
F62417F914D52F3C003CE997 /* TCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TCViewController.h; sourceTree = "<group>"; };
|
||||
F62417FA14D52F3C003CE997 /* TCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TCViewController.m; sourceTree = "<group>"; };
|
||||
F62417FF14D5300C003CE997 /* TCChatCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCChatCell.h; sourceTree = "<group>"; };
|
||||
F624180014D5300C003CE997 /* TCChatCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCChatCell.m; sourceTree = "<group>"; };
|
||||
F6396B9F153E6D3700345B5E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
|
||||
F6396BA1153E6D4800345B5E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
F6396BA4153E6D7400345B5E /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/CoreServices.framework; sourceTree = DEVELOPER_DIR; };
|
||||
F668C880153E91210044DBAC /* SocketRocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F668C884153E91210044DBAC /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
F668C885153E91210044DBAC /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
F668C886153E91210044DBAC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
F668C889153E91210044DBAC /* SocketRocketOSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SocketRocketOSX-Info.plist"; sourceTree = "<group>"; };
|
||||
F6A12CCF145119B700C1D980 /* SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRWebSocket.h; sourceTree = "<group>"; };
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SRWebSocket.mm; sourceTree = "<group>"; };
|
||||
F6A12CD3145122FC00C1D980 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
F6A12CD51451231B00C1D980 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
F6AE4526145907D30022AF3C /* SenTestCase+SRTAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SenTestCase+SRTAdditions.h"; sourceTree = "<group>"; };
|
||||
F6AE4527145907D30022AF3C /* SenTestCase+SRTAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SenTestCase+SRTAdditions.m"; sourceTree = "<group>"; };
|
||||
F6B2082D1450F597009315AF /* libSocketRocket.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSocketRocket.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F6B208301450F597009315AF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
F6B208341450F597009315AF /* SocketRocket-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SocketRocket-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F6BDA802145900D200FE3253 /* SRWebSocketTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SRWebSocketTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F6BDA809145900D200FE3253 /* SRWebSocketTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SRWebSocketTests-Info.plist"; sourceTree = "<group>"; };
|
||||
F6BDA80B145900D200FE3253 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
F6BDA810145900D200FE3253 /* SRWebSocketTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SRWebSocketTests-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F6BDA8151459016900FE3253 /* SRTAutobahnTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRTAutobahnTests.m; sourceTree = "<group>"; };
|
||||
F6C41C95145F7C4700641356 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = usr/lib/libicucore.dylib; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
F62417E014D52F3C003CE997 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F62417E614D52F3C003CE997 /* UIKit.framework in Frameworks */,
|
||||
F62417E714D52F3C003CE997 /* Foundation.framework in Frameworks */,
|
||||
F62417E914D52F3C003CE997 /* CoreGraphics.framework in Frameworks */,
|
||||
F624180214D532E0003CE997 /* libSocketRocket.a in Frameworks */,
|
||||
F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */,
|
||||
F624180414D53449003CE997 /* Security.framework in Frameworks */,
|
||||
F624180614D53451003CE997 /* libicucore.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F668C87C153E91210044DBAC /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F668C899153E923C0044DBAC /* CoreServices.framework in Frameworks */,
|
||||
F668C89A153E923C0044DBAC /* Foundation.framework in Frameworks */,
|
||||
F668C89B153E923C0044DBAC /* Security.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6B2082A1450F597009315AF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6AE4520145906B20022AF3C /* Foundation.framework in Frameworks */,
|
||||
F6016C8914620ECC0037BB3D /* Security.framework in Frameworks */,
|
||||
F6016C8A1462143C0037BB3D /* CFNetwork.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6BDA7FE145900D200FE3253 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6C41C98145F7C6100641356 /* libicucore.dylib in Frameworks */,
|
||||
F6BDA806145900D200FE3253 /* Foundation.framework in Frameworks */,
|
||||
F6AE451D145906A70022AF3C /* libSocketRocket.a in Frameworks */,
|
||||
F6AE45241459071C0022AF3C /* CFNetwork.framework in Frameworks */,
|
||||
F6016C8814620EC70037BB3D /* Security.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
F62417EA14D52F3C003CE997 /* TestChat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F62417EB14D52F3C003CE997 /* Supporting Files */,
|
||||
F62417F314D52F3C003CE997 /* TCAppDelegate.h */,
|
||||
F62417F414D52F3C003CE997 /* TCAppDelegate.mm */,
|
||||
F62417F614D52F3C003CE997 /* MainStoryboard.storyboard */,
|
||||
F62417F914D52F3C003CE997 /* TCViewController.h */,
|
||||
F62417FA14D52F3C003CE997 /* TCViewController.m */,
|
||||
F62417FF14D5300C003CE997 /* TCChatCell.h */,
|
||||
F624180014D5300C003CE997 /* TCChatCell.m */,
|
||||
);
|
||||
path = TestChat;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F62417EB14D52F3C003CE997 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F61A0DC71625F44D00365EBD /* Default-568h@2x.png */,
|
||||
F62417EC14D52F3C003CE997 /* TestChat-Info.plist */,
|
||||
F62417ED14D52F3C003CE997 /* InfoPlist.strings */,
|
||||
F62417F014D52F3C003CE997 /* main.m */,
|
||||
F62417F214D52F3C003CE997 /* TestChat-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6396BA3153E6D4D00345B5E /* OSX Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6396BA4153E6D7400345B5E /* CoreServices.framework */,
|
||||
F6396BA1153E6D4800345B5E /* Foundation.framework */,
|
||||
F6396B9F153E6D3700345B5E /* Security.framework */,
|
||||
);
|
||||
name = "OSX Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F668C883153E91210044DBAC /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F668C884153E91210044DBAC /* AppKit.framework */,
|
||||
F668C885153E91210044DBAC /* CoreData.framework */,
|
||||
F668C886153E91210044DBAC /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F668C887153E91210044DBAC /* SocketRocketOSX */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F668C889153E91210044DBAC /* SocketRocketOSX-Info.plist */,
|
||||
);
|
||||
path = SocketRocketOSX;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6B208221450F597009315AF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6B208321450F597009315AF /* SocketRocket */,
|
||||
F6BDA807145900D200FE3253 /* SRWebSocketTests */,
|
||||
F62417EA14D52F3C003CE997 /* TestChat */,
|
||||
F668C887153E91210044DBAC /* SocketRocketOSX */,
|
||||
F6B2082F1450F597009315AF /* Frameworks */,
|
||||
F6B2082E1450F597009315AF /* Products */,
|
||||
);
|
||||
indentWidth = 4;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 4;
|
||||
};
|
||||
F6B2082E1450F597009315AF /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6B2082D1450F597009315AF /* libSocketRocket.a */,
|
||||
F6BDA802145900D200FE3253 /* SRWebSocketTests.xctest */,
|
||||
F62417E314D52F3C003CE997 /* TestChat.app */,
|
||||
F668C880153E91210044DBAC /* SocketRocket.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6B2082F1450F597009315AF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6396BA3153E6D4D00345B5E /* OSX Frameworks */,
|
||||
F6C41C95145F7C4700641356 /* libicucore.dylib */,
|
||||
F6A12CD51451231B00C1D980 /* CFNetwork.framework */,
|
||||
F6A12CD3145122FC00C1D980 /* Security.framework */,
|
||||
F6B208301450F597009315AF /* Foundation.framework */,
|
||||
F62417E514D52F3C003CE997 /* UIKit.framework */,
|
||||
F62417E814D52F3C003CE997 /* CoreGraphics.framework */,
|
||||
F668C883153E91210044DBAC /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6B208321450F597009315AF /* SocketRocket */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6B208331450F597009315AF /* Supporting Files */,
|
||||
F6A12CCF145119B700C1D980 /* SRWebSocket.h */,
|
||||
<<<<<<< HEAD
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.mm */,
|
||||
F6572123146C7B6A00D6B8A9 /* NSData+SRB64Additions.h */,
|
||||
F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */,
|
||||
27CA135F16A21E4D00A35C2D /* DispatchIO.mm */,
|
||||
27CA136016A21E4D00A35C2D /* DispatchIO.h */,
|
||||
2725F85916A29D18007018E9 /* SecureIO.mm */,
|
||||
2725F85A16A29D18007018E9 /* SecureIO.h */,
|
||||
27CA136416A2243000A35C2D /* DispatchData.mm */,
|
||||
27CA136516A2243000A35C2D /* DispatchData.h */,
|
||||
27DC4A9416A64EB800E9C084 /* Common.h */,
|
||||
=======
|
||||
F6A12CD0145119B700C1D980 /* SRWebSocket.m */,
|
||||
>>>>>>> origin/master
|
||||
);
|
||||
path = SocketRocket;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6B208331450F597009315AF /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6B208341450F597009315AF /* SocketRocket-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6BDA807145900D200FE3253 /* SRWebSocketTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6BDA808145900D200FE3253 /* Supporting Files */,
|
||||
F6BDA8151459016900FE3253 /* SRTAutobahnTests.m */,
|
||||
F6BDA810145900D200FE3253 /* SRWebSocketTests-Prefix.pch */,
|
||||
F6AE4526145907D30022AF3C /* SenTestCase+SRTAdditions.h */,
|
||||
F6AE4527145907D30022AF3C /* SenTestCase+SRTAdditions.m */,
|
||||
F60CC29F14D4EA0500A005E4 /* SRTWebSocketOperation.h */,
|
||||
F60CC2A014D4EA0500A005E4 /* SRTWebSocketOperation.m */,
|
||||
27CA136916A23AAE00A35C2D /* STRDispatchTest.mm */,
|
||||
);
|
||||
path = SRWebSocketTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6BDA808145900D200FE3253 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F6BDA809145900D200FE3253 /* SRWebSocketTests-Info.plist */,
|
||||
F6BDA80A145900D200FE3253 /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
F668C87D153E91210044DBAC /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F668C8AA153E92F90044DBAC /* SRWebSocket.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6B2082B1450F597009315AF /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */,
|
||||
<<<<<<< HEAD
|
||||
F6016C7F146124ED0037BB3D /* base64.h in Headers */,
|
||||
27CA136216A21E4D00A35C2D /* DispatchIO.h in Headers */,
|
||||
27CA136716A2243000A35C2D /* DispatchData.h in Headers */,
|
||||
2725F85C16A29D18007018E9 /* SecureIO.h in Headers */,
|
||||
27DC4A9516A64EB800E9C084 /* Common.h in Headers */,
|
||||
=======
|
||||
>>>>>>> origin/master
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
F62417E214D52F3C003CE997 /* TestChat */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F62417FC14D52F3C003CE997 /* Build configuration list for PBXNativeTarget "TestChat" */;
|
||||
buildPhases = (
|
||||
F62417DF14D52F3C003CE997 /* Sources */,
|
||||
F62417E014D52F3C003CE997 /* Frameworks */,
|
||||
F62417E114D52F3C003CE997 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = TestChat;
|
||||
productName = TestChat;
|
||||
productReference = F62417E314D52F3C003CE997 /* TestChat.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
F668C87F153E91210044DBAC /* SocketRocketOSX */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F668C891153E91210044DBAC /* Build configuration list for PBXNativeTarget "SocketRocketOSX" */;
|
||||
buildPhases = (
|
||||
F6396B85153E67EC00345B5E /* Sources */,
|
||||
F668C87C153E91210044DBAC /* Frameworks */,
|
||||
F668C87D153E91210044DBAC /* Headers */,
|
||||
F668C87E153E91210044DBAC /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SocketRocketOSX;
|
||||
productName = SocketRocketOSX;
|
||||
productReference = F668C880153E91210044DBAC /* SocketRocket.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
F6B2082C1450F597009315AF /* SocketRocket */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F6B2083A1450F597009315AF /* Build configuration list for PBXNativeTarget "SocketRocket" */;
|
||||
buildPhases = (
|
||||
F6B208291450F597009315AF /* Sources */,
|
||||
F6B2082A1450F597009315AF /* Frameworks */,
|
||||
F6B2082B1450F597009315AF /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SocketRocket;
|
||||
productName = SocketRocket;
|
||||
productReference = F6B2082D1450F597009315AF /* libSocketRocket.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
F6BDA801145900D200FE3253 /* SRWebSocketTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F6BDA813145900D200FE3253 /* Build configuration list for PBXNativeTarget "SRWebSocketTests" */;
|
||||
buildPhases = (
|
||||
F6BDA7FD145900D200FE3253 /* Sources */,
|
||||
F6BDA7FE145900D200FE3253 /* Frameworks */,
|
||||
F6BDA7FF145900D200FE3253 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
F62417D614D50869003CE997 /* PBXTargetDependency */,
|
||||
);
|
||||
name = SRWebSocketTests;
|
||||
productName = SRWebSocketTests;
|
||||
productReference = F6BDA802145900D200FE3253 /* SRWebSocketTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
F6B208241450F597009315AF /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastTestingUpgradeCheck = 0640;
|
||||
LastUpgradeCheck = 0640;
|
||||
};
|
||||
buildConfigurationList = F6B208271450F597009315AF /* Build configuration list for PBXProject "SocketRocket" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = F6B208221450F597009315AF;
|
||||
productRefGroup = F6B2082E1450F597009315AF /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
F6B2082C1450F597009315AF /* SocketRocket */,
|
||||
F668C87F153E91210044DBAC /* SocketRocketOSX */,
|
||||
F6BDA801145900D200FE3253 /* SRWebSocketTests */,
|
||||
F62417E214D52F3C003CE997 /* TestChat */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
F62417E114D52F3C003CE997 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F62417EF14D52F3C003CE997 /* InfoPlist.strings in Resources */,
|
||||
F62417F814D52F3C003CE997 /* MainStoryboard.storyboard in Resources */,
|
||||
F61A0DC81625F44D00365EBD /* Default-568h@2x.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F668C87E153E91210044DBAC /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6BDA7FF145900D200FE3253 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6BDA80C145900D200FE3253 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
F62417DF14D52F3C003CE997 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F62417F114D52F3C003CE997 /* main.m in Sources */,
|
||||
F62417F514D52F3C003CE997 /* TCAppDelegate.mm in Sources */,
|
||||
F62417FB14D52F3C003CE997 /* TCViewController.m in Sources */,
|
||||
F624180114D5300C003CE997 /* TCChatCell.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6396B85153E67EC00345B5E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
<<<<<<< HEAD
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.mm in Sources */,
|
||||
F6396B87153E67EC00345B5E /* base64.c in Sources */,
|
||||
F6396B88153E67EC00345B5E /* NSData+SRB64Additions.m in Sources */,
|
||||
=======
|
||||
F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */,
|
||||
>>>>>>> origin/master
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6B208291450F597009315AF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
<<<<<<< HEAD
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.mm in Sources */,
|
||||
F6016C7C146124B20037BB3D /* base64.c in Sources */,
|
||||
F6572126146C7B6A00D6B8A9 /* NSData+SRB64Additions.m in Sources */,
|
||||
27CA136116A21E4D00A35C2D /* DispatchIO.mm in Sources */,
|
||||
27CA136616A2243000A35C2D /* DispatchData.mm in Sources */,
|
||||
2725F85B16A29D18007018E9 /* SecureIO.mm in Sources */,
|
||||
=======
|
||||
F6A12CD2145119B700C1D980 /* SRWebSocket.m in Sources */,
|
||||
>>>>>>> origin/master
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6BDA7FD145900D200FE3253 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F6BDA8161459016900FE3253 /* SRTAutobahnTests.m in Sources */,
|
||||
F6AE4528145907D30022AF3C /* SenTestCase+SRTAdditions.m in Sources */,
|
||||
F60CC2A114D4EA0500A005E4 /* SRTWebSocketOperation.m in Sources */,
|
||||
27CA136A16A23AAE00A35C2D /* STRDispatchTest.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
F62417D614D50869003CE997 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F6B2082C1450F597009315AF /* SocketRocket */;
|
||||
targetProxy = F62417D514D50869003CE997 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
F62417ED14D52F3C003CE997 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F62417EE14D52F3C003CE997 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F62417F614D52F3C003CE997 /* MainStoryboard.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F62417F714D52F3C003CE997 /* en */,
|
||||
);
|
||||
name = MainStoryboard.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6BDA80A145900D200FE3253 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F6BDA80B145900D200FE3253 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
F62417FD14D52F3C003CE997 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "TestChat/TestChat-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestChat/TestChat-Info.plist";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F62417FE14D52F3C003CE997 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "TestChat/TestChat-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestChat/TestChat-Info.plist";
|
||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F668C892153E91210044DBAC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
|
||||
);
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "SocketRocket/SocketRocket-Prefix.pch";
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
INFOPLIST_FILE = "SocketRocketOSX/SocketRocketOSX-Info.plist";
|
||||
LD_DYLIB_INSTALL_NAME = "@executable_path/../Frameworks/$(EXECUTABLE_PATH)";
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SocketRocket;
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F668C893153E91210044DBAC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
|
||||
);
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "SocketRocket/SocketRocket-Prefix.pch";
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
INFOPLIST_FILE = "SocketRocketOSX/SocketRocketOSX-Info.plist";
|
||||
LD_DYLIB_INSTALL_NAME = "@executable_path/../Frameworks/$(EXECUTABLE_PATH)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SocketRocket;
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F6B208381450F597009315AF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
SDKROOT = iphoneos6.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F6B208391450F597009315AF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
NDEBUG,
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
SDKROOT = iphoneos6.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F6B2083B1450F597009315AF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
DSTROOT = /tmp/SocketRocket.dst;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "SocketRocket/SocketRocket-Prefix.pch";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/lib/system\"",
|
||||
"\"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/lib\"",
|
||||
);
|
||||
OTHER_LDFLAGS = "-Licucore";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F6B2083C1450F597009315AF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
DSTROOT = /tmp/SocketRocket.dst;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "SocketRocket/SocketRocket-Prefix.pch";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/lib/system\"",
|
||||
"\"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/lib\"",
|
||||
);
|
||||
OTHER_LDFLAGS = "-Licucore";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F6BDA811145900D200FE3253 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "SRWebSocketTests/SRWebSocketTests-Prefix.pch";
|
||||
INFOPLIST_FILE = "SRWebSocketTests/SRWebSocketTests-Info.plist";
|
||||
OTHER_LDFLAGS = (
|
||||
"-all_load",
|
||||
"-ObjC",
|
||||
"-framework",
|
||||
XCTest,
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F6BDA812145900D200FE3253 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "SRWebSocketTests/SRWebSocketTests-Prefix.pch";
|
||||
INFOPLIST_FILE = "SRWebSocketTests/SRWebSocketTests-Info.plist";
|
||||
OTHER_LDFLAGS = (
|
||||
"-all_load",
|
||||
"-ObjC",
|
||||
"-framework",
|
||||
XCTest,
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
F62417FC14D52F3C003CE997 /* Build configuration list for PBXNativeTarget "TestChat" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F62417FD14D52F3C003CE997 /* Debug */,
|
||||
F62417FE14D52F3C003CE997 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F668C891153E91210044DBAC /* Build configuration list for PBXNativeTarget "SocketRocketOSX" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F668C892153E91210044DBAC /* Debug */,
|
||||
F668C893153E91210044DBAC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F6B208271450F597009315AF /* Build configuration list for PBXProject "SocketRocket" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F6B208381450F597009315AF /* Debug */,
|
||||
F6B208391450F597009315AF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F6B2083A1450F597009315AF /* Build configuration list for PBXNativeTarget "SocketRocket" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F6B2083B1450F597009315AF /* Debug */,
|
||||
F6B2083C1450F597009315AF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F6BDA813145900D200FE3253 /* Build configuration list for PBXNativeTarget "SRWebSocketTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F6BDA811145900D200FE3253 /* Debug */,
|
||||
F6BDA812145900D200FE3253 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = F6B208241450F597009315AF /* Project object */;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -37,10 +37,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "NO"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "NO">
|
||||
<PreActions>
|
||||
<ExecutionAction
|
||||
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
|
||||
@ -89,6 +89,17 @@
|
||||
BlueprintName = "SRWebSocketTests"
|
||||
ReferencedContainer = "container:SocketRocket.xcodeproj">
|
||||
</BuildableReference>
|
||||
<SkippedTests>
|
||||
<Test
|
||||
Identifier = "SRTAutobahnTests">
|
||||
</Test>
|
||||
<Test
|
||||
Identifier = "STRDispatchTest/testConnect">
|
||||
</Test>
|
||||
<Test
|
||||
Identifier = "STRDispatchTest/testSimpleDial">
|
||||
</Test>
|
||||
</SkippedTests>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
@ -107,15 +118,18 @@
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
@ -127,6 +141,11 @@
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
<AdditionalOption
|
||||
key = "DYLD_INSERT_LIBRARIES"
|
||||
value = "/usr/lib/libgmalloc.dylib"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "NSZombieEnabled"
|
||||
value = "YES"
|
||||
@ -150,10 +169,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -23,21 +23,24 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
@ -52,10 +55,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -23,10 +23,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "NO"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "NO">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@ -39,15 +39,18 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
@ -82,10 +85,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
@ -62,23 +62,12 @@
|
||||
<AdditionalOption
|
||||
key = "NSZombieEnabled"
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "OBJC_PRINT_EXCEPTIONS"
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "MallocGuardEdges"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "MallocScribble"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F62417E214D52F3C003CE997"
|
||||
BuildableName = "TestChat.app"
|
||||
BlueprintName = "TestChat"
|
||||
ReferencedContainer = "container:SocketRocket.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F62417E214D52F3C003CE997"
|
||||
BuildableName = "TestChat.app"
|
||||
BlueprintName = "TestChat"
|
||||
ReferencedContainer = "container:SocketRocket.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F62417E214D52F3C003CE997"
|
||||
BuildableName = "TestChat.app"
|
||||
BlueprintName = "TestChat"
|
||||
ReferencedContainer = "container:SocketRocket.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
<AdditionalOption
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
key = "NSZombieEnabled"
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
>>>>>>> origin/master
|
||||
key = "OBJC_PRINT_EXCEPTIONS"
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
<AdditionalOption
|
||||
key = "MallocGuardEdges"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "MallocScribble"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
>>>>>>> origin/master
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F62417E214D52F3C003CE997"
|
||||
BuildableName = "TestChat.app"
|
||||
BlueprintName = "TestChat"
|
||||
ReferencedContainer = "container:SocketRocket.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
32
SocketRocket/Common.h
Normal file
32
SocketRocket/Common.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Common.h
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/15/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef SocketRocket_Common_h
|
||||
#define SocketRocket_Common_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
#define sr_dispatch_retain(x)
|
||||
#define sr_dispatch_release(x)
|
||||
#define __sr_maybe_bridge__ __bridge
|
||||
#define __sr_maybe_strong__ __strong
|
||||
#else
|
||||
#define sr_dispatch_retain(x) dispatch_retain(x)
|
||||
#define sr_dispatch_release(x) dispatch_release(x)
|
||||
#define __sr_maybe_bridge__
|
||||
#define __sr_maybe_strong__
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
149
SocketRocket/DispatchData.h
Normal file
149
SocketRocket/DispatchData.h
Normal file
@ -0,0 +1,149 @@
|
||||
//
|
||||
// DispatchData.h
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __SocketRocket__DispatchData__
|
||||
#define __SocketRocket__DispatchData__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <deque>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
namespace squareup {
|
||||
namespace dispatch {
|
||||
class Data {
|
||||
__sr_maybe_strong__ dispatch_data_t _data;
|
||||
public:
|
||||
inline Data() : Data(dispatch_data_empty) {
|
||||
|
||||
}
|
||||
|
||||
// Initializes a new data. retains the data by default
|
||||
// Data always releases _data;
|
||||
inline Data(dispatch_data_t data, bool retain = true) : _data(data) {
|
||||
if (retain && _data) {
|
||||
sr_dispatch_retain(_data);
|
||||
}
|
||||
}
|
||||
|
||||
// Will copy the data
|
||||
inline Data(const char *str, dispatch_queue_t release_queue) :
|
||||
_data(dispatch_data_create(reinterpret_cast<const void *>(str), strlen(str), release_queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT)) {
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
inline Data(const Data &other) : Data(static_cast<dispatch_data_t>(other), true) {
|
||||
|
||||
}
|
||||
|
||||
inline Data(const void *bytes, size_t length, dispatch_queue_t release_queue) :
|
||||
_data(dispatch_data_create(bytes, length, release_queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT)) {
|
||||
}
|
||||
|
||||
|
||||
inline Data Concat(dispatch_data_t other) const {
|
||||
return Data(dispatch_data_create_concat(_data, other), false);
|
||||
}
|
||||
|
||||
|
||||
inline Data operator + (dispatch_data_t other) const {
|
||||
return Concat(other);
|
||||
}
|
||||
|
||||
inline Data Subrange(size_t offset, size_t length) const {
|
||||
return Data(dispatch_data_create_subrange(_data, offset, length), false);
|
||||
}
|
||||
|
||||
// copies bytes into the buffer, and returns the remaining.
|
||||
inline Data TakeInto(size_t length, void *bytes) const {
|
||||
size_t size = Size();
|
||||
assert(length <= size);
|
||||
|
||||
|
||||
Apply([&](dispatch_data_t region, size_t offset, const void *buffer, size_t size) -> bool {
|
||||
size_t numToCopy = std::min(size, length - offset);
|
||||
|
||||
memcpy(reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(bytes) + offset), buffer, numToCopy);
|
||||
|
||||
return size + offset <= length;
|
||||
});
|
||||
|
||||
if (length == size) {
|
||||
return dispatch_data_empty;
|
||||
}
|
||||
return Subrange(length, size - length);
|
||||
}
|
||||
|
||||
inline Data Map(const void **buffer_ptr, size_t *size_ptr) const {
|
||||
return Data(dispatch_data_create_map(_data, buffer_ptr, size_ptr), false);
|
||||
}
|
||||
|
||||
inline Data CopyRegion(size_t location, size_t *offset_ptr) const {
|
||||
return Data(dispatch_data_copy_region(_data, location, offset_ptr), false);
|
||||
}
|
||||
|
||||
inline bool Apply(dispatch_data_applier_t applier) const {
|
||||
return dispatch_data_apply(_data, applier);
|
||||
}
|
||||
|
||||
inline size_t Size() const {
|
||||
return dispatch_data_get_size(static_cast<dispatch_data_t>(*this));
|
||||
}
|
||||
|
||||
// This is a workaround since the memory gets quite fragmented if you use it as a stream
|
||||
inline void FlattenIfNecessary() {
|
||||
if (NumRegions() > 100) {
|
||||
size_t size;
|
||||
const void * buffer;
|
||||
(*this) = Data(Map(&buffer, &size));
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t NumRegions() {
|
||||
size_t ret = 0;
|
||||
Apply([&ret](dispatch_data_t region, size_t offset, const void *buffer, size_t size) -> bool {
|
||||
ret += 1;
|
||||
return true;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline operator dispatch_data_t() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
inline Data &operator = (const dispatch_data_t &other) {
|
||||
if (other) {
|
||||
sr_dispatch_retain(other);
|
||||
}
|
||||
if (_data) {
|
||||
sr_dispatch_release(_data);
|
||||
}
|
||||
_data = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Data &operator += (const Data &other) {
|
||||
return (*this = Concat(other));
|
||||
}
|
||||
|
||||
virtual ~Data() {
|
||||
if (_data) {
|
||||
sr_dispatch_release(_data);
|
||||
}
|
||||
}
|
||||
|
||||
static const Data empty;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(__SocketRocket__DispatchData__) */
|
||||
15
SocketRocket/DispatchData.mm
Normal file
15
SocketRocket/DispatchData.mm
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// DispatchData.cpp
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include "DispatchData.h"
|
||||
|
||||
namespace squareup {
|
||||
namespace dispatch {
|
||||
const Data Data::empty(dispatch_data_empty);
|
||||
}
|
||||
}
|
||||
91
SocketRocket/DispatchIO.h
Normal file
91
SocketRocket/DispatchIO.h
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// DispatchChannel.h
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __SocketRocket__DispatchChannel__
|
||||
#define __SocketRocket__DispatchChannel__
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include <netdb.h>
|
||||
}
|
||||
|
||||
namespace squareup {
|
||||
namespace dispatch {
|
||||
class RawIO;
|
||||
|
||||
|
||||
typedef void (^dial_callback)(dispatch_fd_t fd, int error_code, const char *error_message);
|
||||
|
||||
void Dial(dispatch_queue_t workQueue, const char *hostname, const char *servname, dispatch_queue_t callback_queue, dial_callback callback);
|
||||
|
||||
// You are responsible for removing inputStream and outputStream
|
||||
typedef void (^simple_dial_callback)(RawIO *io, int error, const char *error_message);
|
||||
|
||||
// callback_queue is what is sent to the clients but also
|
||||
// parent_io_queue can be a parallel queue. the
|
||||
// close_handler is passed to the RawIO
|
||||
void SimpleDial(const char *hostname, const char *servname, dispatch_queue_t callback_queue, dispatch_queue_t parent_io_queue, simple_dial_callback dial_callback, void(^close_handler)(int error) = nullptr);
|
||||
|
||||
class IO {
|
||||
public:
|
||||
virtual void Close(dispatch_io_close_flags_t flags) = 0;
|
||||
virtual void Read(size_t length, dispatch_queue_t queue, dispatch_io_handler_t handler) = 0;
|
||||
virtual void Write(dispatch_data_t data, dispatch_queue_t queue, dispatch_io_handler_t handler) = 0;
|
||||
virtual void Barrier(dispatch_block_t barrier) = 0;
|
||||
|
||||
|
||||
virtual void SetHighWater(size_t high_water) = 0;
|
||||
virtual void SetLowWater(size_t low_water) = 0;
|
||||
|
||||
virtual ~IO();
|
||||
};
|
||||
|
||||
class RawIO : public IO {
|
||||
dispatch_io_t _channel;
|
||||
public:
|
||||
|
||||
void Close(dispatch_io_close_flags_t flags);
|
||||
void Read(size_t length, dispatch_queue_t queue, dispatch_io_handler_t handler);
|
||||
void Write(dispatch_data_t data, dispatch_queue_t queue, dispatch_io_handler_t handler);
|
||||
void Barrier(dispatch_block_t barrier);
|
||||
|
||||
void SetHighWater(size_t high_water);
|
||||
void SetLowWater(size_t low_water);
|
||||
|
||||
RawIO(dispatch_fd_t fd,
|
||||
dispatch_queue_t cleanupQueue,
|
||||
dispatch_queue_t callbackQueue,
|
||||
dispatch_queue_t ioQueue,
|
||||
void (^cleanup_handler)(int error));
|
||||
|
||||
// Takes ownership of channel
|
||||
// retain is only for the channel
|
||||
RawIO(dispatch_io_t channel,
|
||||
dispatch_queue_t callbackQueue,
|
||||
bool retain = true);
|
||||
|
||||
// Clones an existing IO
|
||||
RawIO(dispatch_io_t otherIo,
|
||||
dispatch_queue_t queue,
|
||||
dispatch_queue_t callbackQueue,
|
||||
dispatch_queue_t ioQueue,
|
||||
void (^cleanup_handler)(int error));
|
||||
|
||||
inline operator dispatch_io_t () const {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
virtual ~RawIO();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(__SocketRocket__DispatchChannel__) */
|
||||
298
SocketRocket/DispatchIO.mm
Normal file
298
SocketRocket/DispatchIO.mm
Normal file
@ -0,0 +1,298 @@
|
||||
//
|
||||
// DispatchChannel.cpp
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include "DispatchIO.h"
|
||||
#include <Block.h>
|
||||
#include <string>
|
||||
#include "Common.h"
|
||||
|
||||
extern "C" {
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
}
|
||||
|
||||
// TODO: add deadlines
|
||||
namespace squareup {
|
||||
namespace dispatch {
|
||||
|
||||
IO::~IO() {};
|
||||
class Connector;
|
||||
|
||||
typedef void(^finish_callback)(Connector *connector, addrinfo *res0, dispatch_fd_t fd, int error_code, const char *error_message);
|
||||
|
||||
class Connector {
|
||||
addrinfo *_res;
|
||||
addrinfo *_res0;
|
||||
__strong finish_callback _finishCallback;
|
||||
dispatch_queue_t _workQueue;
|
||||
int _lastError;
|
||||
const char *_lastErrorMessage;
|
||||
bool _foundAddr = false;
|
||||
|
||||
public:
|
||||
// Takes ownership of res0;
|
||||
inline Connector(dispatch_queue_t workQueue, struct addrinfo *res0, finish_callback finishCallback) : _res(res0), _res0(res0), _finishCallback([finishCallback copy]), _workQueue(workQueue) {
|
||||
sr_dispatch_retain(_workQueue);
|
||||
}
|
||||
|
||||
virtual ~Connector() {
|
||||
sr_dispatch_release(_workQueue);
|
||||
}
|
||||
|
||||
inline void NextIter() {
|
||||
_res = _res->ai_next;
|
||||
dispatch_async(_workQueue, ^{
|
||||
DoNext();
|
||||
});
|
||||
}
|
||||
|
||||
inline void DoNext() {
|
||||
// We ran out of addresses
|
||||
if (!_res) {
|
||||
assert(!_foundAddr);
|
||||
_finishCallback(this, _res0, -1, _lastError, _lastErrorMessage);
|
||||
_finishCallback = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_fd_t fd = socket(_res->ai_family, _res->ai_socktype,
|
||||
_res->ai_protocol);
|
||||
|
||||
if (fd < 0) {
|
||||
_lastError = errno;
|
||||
_lastErrorMessage = strerror(_lastError);
|
||||
NextIter();
|
||||
return;
|
||||
}
|
||||
|
||||
int curflags = fcntl(fd, F_GETFL);
|
||||
if (curflags < 0) {
|
||||
_lastError = errno;
|
||||
_lastErrorMessage = strerror(_lastError);
|
||||
NextIter();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set it to be nonblocking
|
||||
int error = fcntl(fd, F_SETFL, curflags | O_NONBLOCK);
|
||||
if (error) {
|
||||
_lastError = errno;
|
||||
_lastErrorMessage = strerror(_lastError);
|
||||
NextIter();
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_source_t readSource = nullptr;
|
||||
|
||||
readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, fd, 0, _workQueue);
|
||||
|
||||
dispatch_resume(readSource);
|
||||
|
||||
dispatch_source_set_event_handler(readSource, [this, fd, readSource]{
|
||||
TryConnect(false, fd, readSource);
|
||||
});
|
||||
|
||||
dispatch_source_set_cancel_handler(readSource, [fd]{
|
||||
close(fd);
|
||||
});
|
||||
|
||||
TryConnect(true, fd, readSource);
|
||||
}
|
||||
|
||||
private:
|
||||
// returns true if it is done
|
||||
// if this is the first try we call connect. otherwise we check the status
|
||||
inline void TryConnect(bool firstTry, dispatch_fd_t fd, dispatch_source_t readSource) {
|
||||
// Now, set connection to be non-blocking
|
||||
|
||||
assert(!_foundAddr);
|
||||
|
||||
assert(fd != -1);
|
||||
|
||||
_lastError = 0;
|
||||
if (firstTry) {
|
||||
int error = connect(fd, _res->ai_addr, _res->ai_addrlen);
|
||||
if (error != 0) {
|
||||
_lastError = errno;
|
||||
}
|
||||
} else {
|
||||
socklen_t len = sizeof(_lastError);
|
||||
int sockErr = getsockopt(fd, SOL_SOCKET, SO_ERROR, &_lastError, &len);
|
||||
assert(sockErr == 0);
|
||||
}
|
||||
|
||||
if (_lastError != 0) {
|
||||
if (_lastError != EINPROGRESS) {
|
||||
_lastErrorMessage = strerror(_lastError);
|
||||
dispatch_source_cancel(readSource);
|
||||
sr_dispatch_release(readSource);
|
||||
readSource = nullptr;
|
||||
NextIter();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_foundAddr = true;
|
||||
|
||||
// We don't want to close the FD, so make the cancel handler a noop
|
||||
dispatch_suspend(readSource);
|
||||
dispatch_source_set_cancel_handler(readSource, ^{});
|
||||
dispatch_resume(readSource);
|
||||
dispatch_source_cancel(readSource);
|
||||
|
||||
// Dispose of it without canceling it
|
||||
sr_dispatch_release(readSource);
|
||||
|
||||
// Successful connections get here. Then we don't try anymore
|
||||
|
||||
// If we get this far, we're done
|
||||
dispatch_async(_workQueue, [this, fd]{
|
||||
_finishCallback(this, _res0, fd, 0, nullptr);
|
||||
_finishCallback = nullptr;
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
void Dial(dispatch_queue_t workQueue, const char *hostname, const char *servname, dispatch_queue_t callback_queue, dial_callback callback) {
|
||||
callback = [callback copy];
|
||||
sr_dispatch_retain(callback_queue);
|
||||
|
||||
// Does cleanup and whatnot
|
||||
dispatch_async(workQueue, ^{
|
||||
addrinfo *res0 = nullptr;
|
||||
int error;
|
||||
const char *cause = nullptr;
|
||||
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
error = getaddrinfo(hostname, servname, &hints, &res0);
|
||||
|
||||
auto finish = [callback_queue, callback, res0, workQueue](Connector *connector, addrinfo *res0, dispatch_fd_t fd, int error_code, const char *error_message){
|
||||
NSLog(@"Pew");
|
||||
dispatch_async(callback_queue, [fd, callback_queue, workQueue, error_message, callback, res0, connector, error_code]{
|
||||
callback(fd, error_code, error_message);
|
||||
|
||||
if (res0) {
|
||||
freeaddrinfo(res0);
|
||||
}
|
||||
|
||||
if (connector) {
|
||||
// Delete it after it doesn't reference this block anymore
|
||||
dispatch_async(callback_queue, [workQueue, connector, callback_queue]{
|
||||
delete connector;
|
||||
sr_dispatch_release(callback_queue);
|
||||
});
|
||||
} else {
|
||||
sr_dispatch_release(callback_queue);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (error) {
|
||||
cause = gai_strerror(error);
|
||||
finish(nullptr, res0, -1, error, cause);
|
||||
return;
|
||||
}
|
||||
|
||||
Connector *connector = new Connector(workQueue, res0, finish);
|
||||
connector->DoNext();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// callback_queue is what is sent to the clients but also
|
||||
// parent_io_queue can be a parallel queue. the
|
||||
void SimpleDial(const char *hostname, const char *servname, dispatch_queue_t callback_queue, dispatch_queue_t parent_io_queue, simple_dial_callback dial_callback, void (^close_handler)(int error)) {
|
||||
dispatch_queue_t io_queue = dispatch_queue_create("squareup.dispatch.SimpleDial IO Queue", DISPATCH_QUEUE_SERIAL);
|
||||
dispatch_set_target_queue(io_queue, parent_io_queue);
|
||||
|
||||
sr_dispatch_retain(callback_queue);
|
||||
if (close_handler != nullptr) {
|
||||
close_handler = [close_handler copy];
|
||||
}
|
||||
|
||||
Dial(callback_queue, hostname, servname, callback_queue, [=](dispatch_fd_t fd, int error_code, const char *error_message) {
|
||||
RawIO *io = nullptr;
|
||||
|
||||
if (error_code == 0) {
|
||||
// Going to make the writer the primary.
|
||||
// The write stream is also appropriate for closing
|
||||
io = new RawIO(fd, callback_queue, callback_queue, io_queue, [fd, close_handler](int error) {
|
||||
close(fd);
|
||||
if (close_handler != nullptr) {
|
||||
close_handler(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dial_callback(io, error_code, error_message);
|
||||
|
||||
sr_dispatch_release(io_queue);
|
||||
sr_dispatch_release(parent_io_queue);
|
||||
});
|
||||
}
|
||||
|
||||
RawIO::RawIO(dispatch_fd_t fd,
|
||||
dispatch_queue_t cleanupQueue,
|
||||
dispatch_queue_t callbackQueue,
|
||||
dispatch_queue_t ioQueue,
|
||||
void (^cleanup_handler)(int error)) {
|
||||
_channel = dispatch_io_create(DISPATCH_IO_STREAM, fd, cleanupQueue, cleanup_handler);
|
||||
dispatch_set_target_queue(_channel, ioQueue);
|
||||
}
|
||||
|
||||
// Takes ownership of channel
|
||||
// retain is only for the channel
|
||||
RawIO::RawIO(dispatch_io_t channel, dispatch_queue_t callbackQueue, bool retain) : _channel(channel) {
|
||||
if (retain) {
|
||||
sr_dispatch_retain(_channel);
|
||||
}
|
||||
};
|
||||
|
||||
// Clones an existing IO
|
||||
RawIO::RawIO(dispatch_io_t otherIo, dispatch_queue_t queue, dispatch_queue_t callbackQueue, dispatch_queue_t ioQueue, void (^cleanup_handler)(int error)) :
|
||||
RawIO(dispatch_io_create_with_io(DISPATCH_IO_STREAM, otherIo, queue, cleanup_handler), false) {
|
||||
dispatch_set_target_queue(_channel, ioQueue);
|
||||
}
|
||||
|
||||
RawIO::~RawIO() {
|
||||
sr_dispatch_release(_channel);
|
||||
_channel = nullptr;
|
||||
}
|
||||
|
||||
void RawIO::Close(dispatch_io_close_flags_t flags) {
|
||||
dispatch_io_close(_channel, flags);
|
||||
}
|
||||
|
||||
void RawIO::Read(size_t length, dispatch_queue_t queue, dispatch_io_handler_t handler) {
|
||||
dispatch_io_read(_channel, 0, length, queue, handler);
|
||||
}
|
||||
|
||||
void RawIO::Write(dispatch_data_t data, dispatch_queue_t queue, dispatch_io_handler_t handler) {
|
||||
dispatch_io_write(_channel, 0, data, queue, handler);
|
||||
}
|
||||
|
||||
void RawIO::Barrier(dispatch_block_t barrier) {
|
||||
dispatch_io_barrier(_channel, barrier);
|
||||
}
|
||||
|
||||
void RawIO::SetHighWater(size_t high_water) {
|
||||
dispatch_io_set_high_water(_channel, high_water);
|
||||
}
|
||||
|
||||
void RawIO::SetLowWater(size_t low_water) {
|
||||
dispatch_io_set_low_water(_channel, low_water);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
extern "C" {
|
||||
|
||||
#import "SRWebSocket.h"
|
||||
|
||||
@ -34,20 +34,13 @@
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import <Security/SecRandom.h>
|
||||
|
||||
#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
#define sr_dispatch_retain(x)
|
||||
#define sr_dispatch_release(x)
|
||||
#define maybe_bridge(x) ((__bridge void *) x)
|
||||
#else
|
||||
#define sr_dispatch_retain(x) dispatch_retain(x)
|
||||
#define sr_dispatch_release(x) dispatch_release(x)
|
||||
#define maybe_bridge(x) (x)
|
||||
#endif
|
||||
#import "Common.h"
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error SocketRocket must be compiled with ARC enabled
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
SROpCodeTextFrame = 0x1,
|
||||
@ -104,7 +97,7 @@ static inline void SRFastLog(NSString *format, ...);
|
||||
@end
|
||||
|
||||
|
||||
static NSString *newSHA1String(const char *bytes, size_t length) {
|
||||
static NSString *newSHA1String(const void *bytes, size_t length) {
|
||||
uint8_t md[CC_SHA1_DIGEST_LENGTH];
|
||||
|
||||
assert(length >= 0);
|
||||
@ -305,7 +298,7 @@ static __strong NSData *CRLFCRLF;
|
||||
_workQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
// Going to set a specific on the queue so we can validate we're on the work queue
|
||||
dispatch_queue_set_specific(_workQueue, (__bridge void *)self, maybe_bridge(_workQueue), NULL);
|
||||
dispatch_queue_set_specific(_workQueue, (__bridge void *)self, (__sr_maybe_bridge__ void *)(_workQueue), NULL);
|
||||
|
||||
_delegateDispatchQueue = dispatch_get_main_queue();
|
||||
sr_dispatch_retain(_delegateDispatchQueue);
|
||||
@ -328,7 +321,7 @@ static __strong NSData *CRLFCRLF;
|
||||
|
||||
- (void)assertOnWorkQueue;
|
||||
{
|
||||
assert(dispatch_get_specific((__bridge void *)self) == maybe_bridge(_workQueue));
|
||||
assert(dispatch_get_specific((__bridge void *)self) == (__sr_maybe_bridge__ void*)(_workQueue));
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
@ -480,7 +473,7 @@ static __strong NSData *CRLFCRLF;
|
||||
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Host"), (__bridge CFStringRef)(_url.port ? [NSString stringWithFormat:@"%@:%@", _url.host, _url.port] : _url.host));
|
||||
|
||||
NSMutableData *keyBytes = [[NSMutableData alloc] initWithLength:16];
|
||||
SecRandomCopyBytes(kSecRandomDefault, keyBytes.length, keyBytes.mutableBytes);
|
||||
SecRandomCopyBytes(kSecRandomDefault, keyBytes.length, (uint8_t *)keyBytes.mutableBytes);
|
||||
|
||||
if ([keyBytes respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
|
||||
_secKey = [keyBytes base64EncodedStringWithOptions:0];
|
||||
@ -957,7 +950,7 @@ static const uint8_t SRPayloadLenMask = 0x7F;
|
||||
[self _addConsumerWithDataLength:2 callback:^(SRWebSocket *self, NSData *data) {
|
||||
__block frame_header header = {0};
|
||||
|
||||
const uint8_t *headerBuffer = data.bytes;
|
||||
const uint8_t *headerBuffer = reinterpret_cast<const uint8_t *>(data.bytes);
|
||||
assert(data.length >= 2);
|
||||
|
||||
if (headerBuffer[0] & SRRsvMask) {
|
||||
@ -1054,7 +1047,7 @@ static const uint8_t SRPayloadLenMask = 0x7F;
|
||||
|
||||
NSUInteger dataLength = _outputBuffer.length;
|
||||
if (dataLength - _outputBufferOffset > 0 && _outputStream.hasSpaceAvailable) {
|
||||
NSInteger bytesWritten = [_outputStream write:_outputBuffer.bytes + _outputBufferOffset maxLength:dataLength - _outputBufferOffset];
|
||||
NSInteger bytesWritten = [_outputStream write:reinterpret_cast<const uint8_t *>(_outputBuffer.bytes) + _outputBufferOffset maxLength:dataLength - _outputBufferOffset];
|
||||
if (bytesWritten == -1) {
|
||||
[self _failWithError:[NSError errorWithDomain:SRWebSocketErrorDomain code:2145 userInfo:[NSDictionary dictionaryWithObject:@"Error writing to stream" forKey:NSLocalizedDescriptionKey]]];
|
||||
return;
|
||||
@ -1063,7 +1056,7 @@ static const uint8_t SRPayloadLenMask = 0x7F;
|
||||
_outputBufferOffset += bytesWritten;
|
||||
|
||||
if (_outputBufferOffset > 4096 && _outputBufferOffset > (_outputBuffer.length >> 1)) {
|
||||
_outputBuffer = [[NSMutableData alloc] initWithBytes:(char *)_outputBuffer.bytes + _outputBufferOffset length:_outputBuffer.length - _outputBufferOffset];
|
||||
_outputBuffer = [[NSMutableData alloc] initWithBytes:reinterpret_cast<const void *>(reinterpret_cast<const char *>(_outputBuffer.bytes) + _outputBufferOffset) length:_outputBuffer.length - _outputBufferOffset];
|
||||
_outputBufferOffset = 0;
|
||||
}
|
||||
}
|
||||
@ -1133,7 +1126,7 @@ static const char CRLFCRLFBytes[] = {'\r', '\n', '\r', '\n'};
|
||||
__block size_t match_count = 0;
|
||||
|
||||
size_t size = data.length;
|
||||
const unsigned char *buffer = data.bytes;
|
||||
const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.bytes);
|
||||
for (size_t i = 0; i < size; i++ ) {
|
||||
if (((const unsigned char *)buffer)[i] == ((const unsigned char *)bytes)[match_count]) {
|
||||
match_count += 1;
|
||||
@ -1201,7 +1194,7 @@ static const char CRLFCRLFBytes[] = {'\r', '\n', '\r', '\n'};
|
||||
NSMutableData *mutableSlice = [slice mutableCopy];
|
||||
|
||||
NSUInteger len = mutableSlice.length;
|
||||
uint8_t *bytes = mutableSlice.mutableBytes;
|
||||
uint8_t *bytes = reinterpret_cast<uint8_t *>(mutableSlice.mutableBytes);
|
||||
|
||||
for (NSUInteger i = 0; i < len; i++) {
|
||||
bytes[i] = bytes[i] ^ _currentReadMaskKey[_currentReadMaskOffset % sizeof(_currentReadMaskKey)];
|
||||
1768
SocketRocket/SRWebSocket.mm.orig
Normal file
1768
SocketRocket/SRWebSocket.mm.orig
Normal file
File diff suppressed because it is too large
Load Diff
176
SocketRocket/SecureIO.h
Normal file
176
SocketRocket/SecureIO.h
Normal file
@ -0,0 +1,176 @@
|
||||
//
|
||||
// SecureIO.h
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __SocketRocket__SecureIO__
|
||||
#define __SocketRocket__SecureIO__
|
||||
|
||||
#include "DispatchIO.h"
|
||||
#include "DispatchData.h"
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
struct SSLContext;
|
||||
|
||||
namespace squareup {
|
||||
namespace dispatch {
|
||||
class SecureIO;
|
||||
|
||||
// You are responsible for removing inputStream and outputStream
|
||||
typedef void (^dial_tls_callback)(SecureIO *io, int error, const char *error_message);
|
||||
|
||||
void DialTLS(const char *hostname, const char *servname, SSLContextRef ssl_context, dispatch_queue_t callback_queue, dispatch_queue_t work_queue, dispatch_queue_t parent_io_queue, dial_tls_callback dial_callback, void(^close_handler)(int error) = nullptr);
|
||||
|
||||
|
||||
template <typename FuncType>
|
||||
class QueuedHandle {
|
||||
private:
|
||||
__strong FuncType _handler = nullptr;
|
||||
__sr_maybe_strong__ dispatch_queue_t _queue = nullptr;
|
||||
public:
|
||||
inline QueuedHandle() {
|
||||
}
|
||||
|
||||
inline QueuedHandle(dispatch_queue_t queue, FuncType handler) {
|
||||
_handler = [handler copy];
|
||||
_queue = queue;
|
||||
sr_dispatch_retain(_queue);
|
||||
}
|
||||
|
||||
inline QueuedHandle(const QueuedHandle<FuncType> &other) : QueuedHandle(other._queue, other._handler){
|
||||
}
|
||||
|
||||
|
||||
inline QueuedHandle &operator=(const QueuedHandle &other){
|
||||
_handler = other._handler;
|
||||
_queue = other._queue;
|
||||
sr_dispatch_release(_queue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ~QueuedHandle() {
|
||||
if (_queue) {
|
||||
sr_dispatch_release(_queue);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Valid() const {
|
||||
return _handler != nullptr;
|
||||
}
|
||||
|
||||
inline void Invalidate() {
|
||||
_handler = nullptr;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void operator () (Args... args) const {
|
||||
assert(Valid());
|
||||
FuncType handler = _handler;
|
||||
dispatch_async(_queue, [handler, args...]{
|
||||
handler(args...);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
typedef QueuedHandle<dispatch_io_handler_t> DispatchHandler;
|
||||
|
||||
struct WriteJob {
|
||||
bool isLast;
|
||||
size_t rawBytes = 0;
|
||||
size_t cryptedBytes = 0;
|
||||
DispatchHandler handler;
|
||||
};
|
||||
|
||||
struct ReadRequest {
|
||||
// How many rawBytes we're expecting to read.
|
||||
// This is populated in SSLRead.
|
||||
size_t rawBytesRemaining = 0;
|
||||
|
||||
DispatchHandler handler;
|
||||
};
|
||||
|
||||
class SecureIO : public IO {
|
||||
IO *_io;
|
||||
SSLContext *_context;
|
||||
dispatch_queue_t _workQueue;
|
||||
|
||||
std::deque<WriteJob> _writeJobs;
|
||||
std::deque<ReadRequest> _readRequests;
|
||||
|
||||
Data _waitingCryptedData;
|
||||
size_t _cryptedBytesRequested = 0;
|
||||
size_t _rawBytesRequested = 0;
|
||||
|
||||
size_t _highWater = SIZE_MAX;
|
||||
size_t _lowWater = 1024 * 8;
|
||||
|
||||
bool _cancelled = false;
|
||||
bool _closing = false;
|
||||
|
||||
// Set when we're inside of HandleSSLRead
|
||||
// If we're reading and get a call to our SSLWriteHandler, the connection is probably being closed
|
||||
bool _handlingRead = false;
|
||||
|
||||
// presence of this means handshake is in progress
|
||||
DispatchHandler _handshakeHandler;
|
||||
|
||||
// This is set to true when we send a NULL data ptr. This is so we can request data we need.
|
||||
bool _calculatingRequestSize = false;
|
||||
|
||||
std::vector<uint8_t> _sslReadBuffer;
|
||||
|
||||
public:
|
||||
// Takes ownership of IO and delete it when done
|
||||
SecureIO(IO *io, SSLContextRef context, dispatch_queue_t workQueue);
|
||||
~SecureIO();
|
||||
|
||||
// This performs the handshake.
|
||||
// There will be no data sent back to handler, but it will be called on completion
|
||||
void Handshake(dispatch_queue_t queue, dispatch_io_handler_t handler);
|
||||
|
||||
void Close(dispatch_io_close_flags_t flags);
|
||||
void Read(size_t length, dispatch_queue_t queue, dispatch_io_handler_t handler);
|
||||
void Write(dispatch_data_t data, dispatch_queue_t queue, dispatch_io_handler_t handler);
|
||||
void Barrier(dispatch_block_t barrier);
|
||||
|
||||
|
||||
inline void SetHighWater(size_t high_water) {
|
||||
_highWater = high_water;
|
||||
}
|
||||
|
||||
void SetLowWater(size_t low_water) {
|
||||
_lowWater = low_water;
|
||||
}
|
||||
|
||||
private:
|
||||
// Requests will ask the underlying stream for lenght - _rawBytesRequested
|
||||
void RequestBytes(size_t length);
|
||||
|
||||
void Cancel(dispatch_io_close_flags_t flags, int error);
|
||||
|
||||
void CheckHandshake();
|
||||
void InnerWrite(dispatch_data_t data, const DispatchHandler &handler);
|
||||
|
||||
// These really should be private
|
||||
public:
|
||||
OSStatus SSLReadHandler(void *data, size_t *dataLength);
|
||||
OSStatus SSLWriteHandler(const void *data, size_t *dataLength);
|
||||
|
||||
|
||||
private:
|
||||
void HandleSSLWrite(bool done, size_t requestedLength, int error);
|
||||
void HandleSSLRead(bool done, dispatch_data_t data, int error);
|
||||
|
||||
void PumpSSLRead();
|
||||
void DoSSLRead();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(__SocketRocket__SecureIO__) */
|
||||
475
SocketRocket/SecureIO.mm
Normal file
475
SocketRocket/SecureIO.mm
Normal file
@ -0,0 +1,475 @@
|
||||
//
|
||||
// SecureIO.cpp
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Michael Lewis on 1/12/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include <Security/SecureTransport.h>
|
||||
|
||||
#include "SecureIO.h"
|
||||
#include "DispatchData.h"
|
||||
|
||||
#define ALLOW_INSECURE_SSL 1
|
||||
|
||||
namespace squareup {
|
||||
namespace dispatch {
|
||||
static OSStatus readFunc(SSLConnectionRef connection, void *data, size_t *dataLength);
|
||||
static OSStatus writeFunc(SSLConnectionRef connection, const void *data, size_t *dataLength);
|
||||
|
||||
void DialTLS(const char *hostname,
|
||||
const char *servname,
|
||||
SSLContextRef ssl_context,
|
||||
dispatch_queue_t callback_queue,
|
||||
dispatch_queue_t work_queue,
|
||||
dispatch_queue_t parent_io_queue,
|
||||
dial_tls_callback dial_callback,
|
||||
void(^close_handler)(int error)) {
|
||||
|
||||
if (close_handler != nullptr) {
|
||||
close_handler = [close_handler copy];
|
||||
}
|
||||
|
||||
dial_callback = [dial_callback copy];
|
||||
sr_dispatch_retain(callback_queue);
|
||||
|
||||
// The work queue is the outer ones callback_queue
|
||||
SimpleDial(hostname, servname, work_queue, parent_io_queue, [=](squareup::dispatch::RawIO *io, int error, const char *error_message) {
|
||||
if (error != 0 || io == nullptr) {
|
||||
dispatch_async(callback_queue, ^{
|
||||
dial_callback(nullptr, error, error_message);
|
||||
});
|
||||
sr_dispatch_release(callback_queue);
|
||||
return;
|
||||
}
|
||||
|
||||
SecureIO *newIO = new SecureIO(io, ssl_context, work_queue);
|
||||
|
||||
sr_dispatch_release(callback_queue);
|
||||
|
||||
newIO->Handshake(callback_queue, [newIO, dial_callback](bool done, dispatch_data_t data, int error) {
|
||||
SecureIO *io = newIO;
|
||||
if (error) {
|
||||
delete io;
|
||||
io = nullptr;
|
||||
}
|
||||
|
||||
// TODO: maybe add message?
|
||||
dial_callback(io, error, nullptr);
|
||||
});
|
||||
|
||||
}, close_handler);
|
||||
}
|
||||
|
||||
|
||||
SecureIO::SecureIO(IO *io, SSLContextRef context, dispatch_queue_t workQueue) :
|
||||
_io(io), _context(context), _workQueue(workQueue) {
|
||||
sr_dispatch_retain(_workQueue);
|
||||
CFRetain(_context);
|
||||
|
||||
SSLSetConnection(_context, reinterpret_cast<const void *>(this));
|
||||
SSLSetIOFuncs(_context, readFunc, writeFunc);
|
||||
|
||||
// TODO: delegate certificate authentication
|
||||
#if ALLOW_INSECURE_SSL
|
||||
SSLSetSessionOption(_context, kSSLSessionOptionBreakOnServerAuth, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
SecureIO::~SecureIO() {
|
||||
sr_dispatch_release(_workQueue);
|
||||
CFRelease(_context);
|
||||
|
||||
// make sure things closed before we delete the io
|
||||
assert(!_io);
|
||||
}
|
||||
|
||||
void SecureIO::Handshake(dispatch_queue_t queue, dispatch_io_handler_t handler) {
|
||||
_handshakeHandler = DispatchHandler(queue, handler);
|
||||
dispatch_async(_workQueue, [this]{
|
||||
CheckHandshake();
|
||||
});
|
||||
}
|
||||
|
||||
void SecureIO::Close(dispatch_io_close_flags_t flags) {
|
||||
assert(!_closing);
|
||||
dispatch_async(_workQueue, [this, flags]{
|
||||
assert(!_closing);
|
||||
_closing = true;
|
||||
OSStatus status = SSLClose(_context);
|
||||
|
||||
// This shouldn't be a blocking operation
|
||||
assert(status != errSSLWouldBlock);
|
||||
|
||||
Cancel(flags, status);
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
void SecureIO::Read(size_t length, dispatch_queue_t queue, dispatch_io_handler_t handler) {
|
||||
DispatchHandler dispatchHandler(queue, [handler copy]);
|
||||
|
||||
dispatch_async(_workQueue, [length, dispatchHandler, this]{
|
||||
if (_cancelled) {
|
||||
dispatchHandler(true, (dispatch_data_t)nullptr, ECANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
ReadRequest readRequest;
|
||||
readRequest.handler = dispatchHandler;
|
||||
readRequest.rawBytesRemaining += length;
|
||||
|
||||
|
||||
_readRequests.push_back(readRequest);
|
||||
// TODO: run on queue
|
||||
_rawBytesRequested += length;
|
||||
PumpSSLRead();
|
||||
});
|
||||
}
|
||||
|
||||
void SecureIO::PumpSSLRead() {
|
||||
|
||||
size_t buffSize = SIZE_MAX;
|
||||
|
||||
// This can happen if we have leftover data and haven't requested more.
|
||||
while (buffSize > 0) {
|
||||
// Make sure we are requesting enough;
|
||||
OSStatus status = SSLGetBufferedReadSize(_context, &buffSize);
|
||||
assert(status == 0);
|
||||
if (buffSize > 0) {
|
||||
if (_readRequests.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
DoSSLRead();
|
||||
}
|
||||
}
|
||||
|
||||
_calculatingRequestSize = true;
|
||||
|
||||
const size_t maxBufferSize = 32 * 1024;
|
||||
|
||||
// We don't actually want to read anything into the _sslReadBuffer, howevr there's a bug when we go through 2g of data we have a memory issue
|
||||
|
||||
_sslReadBuffer.resize(std::max(_sslReadBuffer.capacity(), std::min(_rawBytesRequested, maxBufferSize)));
|
||||
|
||||
size_t dummyProcessed;
|
||||
|
||||
assert(buffSize == 0);
|
||||
OSStatus status = ::SSLRead(_context, _sslReadBuffer.data(), _sslReadBuffer.size(), &dummyProcessed);
|
||||
assert(dummyProcessed == 0);
|
||||
_calculatingRequestSize = false;
|
||||
|
||||
if (status == errSSLClosedGraceful) {
|
||||
if (!_closing) {
|
||||
_closing = true;
|
||||
Cancel(0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(status == errSSLWouldBlock);
|
||||
|
||||
}
|
||||
|
||||
void SecureIO::Write(dispatch_data_t data, dispatch_queue_t queue, dispatch_io_handler_t handler) {
|
||||
sr_dispatch_retain(data);
|
||||
DispatchHandler dispatchHandler(queue, handler);
|
||||
|
||||
Data(data).Apply(^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
|
||||
return true;
|
||||
});
|
||||
|
||||
dispatch_async(_workQueue, [data, dispatchHandler, this]{
|
||||
InnerWrite(data, dispatchHandler);
|
||||
sr_dispatch_release(data);
|
||||
});
|
||||
}
|
||||
|
||||
void SecureIO::InnerWrite(dispatch_data_t data, const DispatchHandler &handler) {
|
||||
if (_cancelled) {
|
||||
handler(true, (dispatch_data_t)nullptr, ECANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
OSStatus result = 0;
|
||||
|
||||
size_t totalSize = dispatch_data_get_size(data);
|
||||
|
||||
dispatch_data_apply(data, [&](dispatch_data_t region, size_t offset, const void *buffer, size_t size) -> bool {
|
||||
WriteJob newJob;
|
||||
newJob.handler = handler;
|
||||
newJob.rawBytes = size;
|
||||
newJob.isLast = offset + size == totalSize;
|
||||
newJob.cryptedBytes = 0;
|
||||
|
||||
_writeJobs.push_back(newJob);
|
||||
|
||||
// WriteSSL will fill in the crypted bytes
|
||||
// isLast will be set to True for the last one
|
||||
size_t sizeWritten = 0;
|
||||
result = ::SSLWrite(_context, buffer, size, &sizeWritten);
|
||||
|
||||
// I think we can make this assumption since we don't block at all in our handler.
|
||||
|
||||
if (result != 0) {
|
||||
return false;
|
||||
};
|
||||
|
||||
// We should be able to make this assumptions since our write func never blocks
|
||||
assert(sizeWritten == size);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (result) {
|
||||
Cancel(0, result);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SecureIO::RequestBytes(size_t bytesWanted) {
|
||||
if (bytesWanted > _cryptedBytesRequested) {
|
||||
size_t requestSize = bytesWanted - _cryptedBytesRequested;
|
||||
|
||||
_cryptedBytesRequested += requestSize;
|
||||
|
||||
_io->Read(requestSize, _workQueue, [this](bool done, dispatch_data_t data, int error) {
|
||||
HandleSSLRead(done, data, error);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
OSStatus SecureIO::SSLReadHandler(void *data, size_t *dataLength) {
|
||||
if (_calculatingRequestSize) {
|
||||
RequestBytes(*dataLength);
|
||||
*dataLength = 0;
|
||||
return errSSLWouldBlock;
|
||||
}
|
||||
|
||||
size_t bytesRequested = *dataLength;
|
||||
|
||||
// If _calculatingRequestSize is true, always return errSSLWouldBlock and pretend we don't have any data
|
||||
|
||||
size_t bytesToCopy = std::min(_waitingCryptedData.Size(), bytesRequested);
|
||||
|
||||
*dataLength = bytesToCopy;
|
||||
|
||||
if (bytesToCopy > 0) {
|
||||
// Advance it forward
|
||||
_waitingCryptedData = _waitingCryptedData.TakeInto(bytesToCopy, data);
|
||||
|
||||
_waitingCryptedData.FlattenIfNecessary();
|
||||
}
|
||||
|
||||
if (bytesToCopy < bytesRequested) {
|
||||
RequestBytes(bytesRequested - bytesToCopy);
|
||||
return errSSLWouldBlock;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus SecureIO::SSLWriteHandler(const void *data, size_t *dataLength) {
|
||||
size_t requestedLength = *dataLength;
|
||||
|
||||
if (!_handshakeHandler.Valid() && !_closing && !_handlingRead) {
|
||||
assert(_writeJobs.size() > 0);
|
||||
_writeJobs.back().cryptedBytes += requestedLength;
|
||||
}
|
||||
|
||||
_io->Write(Data(data, requestedLength, _workQueue), _workQueue, [this, requestedLength](bool done, dispatch_data_t data, int error) {
|
||||
HandleSSLWrite(done, requestedLength, error);
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SecureIO::HandleSSLRead(bool done, dispatch_data_t data, int error) {
|
||||
if (!_handshakeHandler.Valid() && _readRequests.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error != 0) {
|
||||
if (_handshakeHandler.Valid()) {
|
||||
_handshakeHandler(done, (dispatch_data_t)nullptr, error);
|
||||
_handshakeHandler.Invalidate();
|
||||
} else {
|
||||
assert(_readRequests.size() > 0);
|
||||
Cancel(0, error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// We got some data, so append it
|
||||
Data d(data);
|
||||
_cryptedBytesRequested -= d.Size();
|
||||
_waitingCryptedData += d;
|
||||
|
||||
if (_handshakeHandler.Valid()) {
|
||||
CheckHandshake();
|
||||
return;
|
||||
}
|
||||
|
||||
DoSSLRead();
|
||||
PumpSSLRead();
|
||||
}
|
||||
|
||||
void SecureIO::DoSSLRead() {
|
||||
assert(_readRequests.size() > 0);
|
||||
|
||||
ReadRequest *frontRead = &_readRequests.front();
|
||||
const DispatchHandler &handler = frontRead->handler;
|
||||
|
||||
size_t length = frontRead->rawBytesRemaining;
|
||||
|
||||
// Let's cap length at 2x the bytes we have available. probably won't use all of it (it will probably be less than 1x)
|
||||
length = std::min(length, 2 * _waitingCryptedData.Size());
|
||||
length = std::min(length, _highWater);
|
||||
|
||||
size_t buffSize = 0;
|
||||
SSLGetBufferedReadSize(_context, &buffSize);
|
||||
length = std::max(buffSize, length);
|
||||
|
||||
size_t sizeRead = 0;
|
||||
|
||||
void *buffer = malloc(length);
|
||||
assert(buffer);
|
||||
|
||||
// TODO: optimize this and not malloc memory each time
|
||||
assert(_calculatingRequestSize == false);
|
||||
|
||||
assert(_handlingRead == false);
|
||||
_handlingRead = true;
|
||||
OSStatus status = ::SSLRead(_context, buffer, length, &sizeRead);
|
||||
_handlingRead = false;
|
||||
|
||||
if (status != 0 && status != errSSLWouldBlock && status != errSSLClosedGraceful) {
|
||||
free(buffer);
|
||||
buffer = nullptr;
|
||||
// TODO: handle error better
|
||||
Cancel(0, status);
|
||||
return;
|
||||
}
|
||||
|
||||
Data rawData(dispatch_data_create(buffer, sizeRead, _workQueue, DISPATCH_DATA_DESTRUCTOR_FREE), false);
|
||||
|
||||
frontRead->rawBytesRemaining -= sizeRead;
|
||||
|
||||
bool isDone = (frontRead->rawBytesRemaining == 0);
|
||||
|
||||
// TODO: honor watermarks
|
||||
handler(isDone, rawData, 0);
|
||||
|
||||
if (status == errSSLClosedGraceful) {
|
||||
// TODO: handle close
|
||||
}
|
||||
|
||||
if (isDone) {
|
||||
_readRequests.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void SecureIO::HandleSSLWrite(bool done, size_t requestedLength, int error) {
|
||||
if (_handshakeHandler.Valid()) {
|
||||
CheckHandshake();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_closing) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(_writeJobs.size() > 0);
|
||||
|
||||
// TODO(lewis): handle rest of errors better
|
||||
if (error != 0) {
|
||||
_writeJobs.front().handler(true, dispatch_data_empty, error);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(_writeJobs.size());
|
||||
|
||||
// We only want to call the handlers when we are "done".
|
||||
// This way we can approximate the bytes that are written
|
||||
if (done) {
|
||||
// if we're an error we want to go to the last one
|
||||
if (error) {
|
||||
Cancel(0, error);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(_writeJobs.size());
|
||||
|
||||
_writeJobs.front().cryptedBytes -= requestedLength;
|
||||
|
||||
WriteJob writeJob = _writeJobs.front();
|
||||
|
||||
// Only call them when we're "done" for now, because we don't want to do bookkeeping of remaining data to consume
|
||||
// TODO: probably change this
|
||||
|
||||
if (writeJob.cryptedBytes == 0) {
|
||||
_writeJobs.pop_front();
|
||||
if (writeJob.isLast) {
|
||||
writeJob.handler(true, dispatch_data_empty, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SecureIO::CheckHandshake() {
|
||||
assert(_handshakeHandler.Valid());
|
||||
OSStatus status = ::SSLHandshake(_context);
|
||||
// If it would block we got nothing to do
|
||||
if (status == errSSLWouldBlock) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if ALLOW_INSECURE_SSL
|
||||
|
||||
// TODO: make this better
|
||||
if (status == errSSLPeerAuthCompleted) {
|
||||
CheckHandshake();
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_handshakeHandler(true, (dispatch_data_t)nullptr, status);
|
||||
_handshakeHandler.Invalidate();
|
||||
}
|
||||
|
||||
void SecureIO::Cancel(dispatch_io_close_flags_t flags, int error) {
|
||||
_cancelled = true;
|
||||
|
||||
for (const ReadRequest &req : _readRequests) {
|
||||
req.handler(true, (dispatch_data_t)nullptr, ECANCELED);
|
||||
}
|
||||
|
||||
for (const WriteJob &job : _writeJobs) {
|
||||
job.handler(true, (dispatch_data_t)nullptr, ECANCELED);
|
||||
}
|
||||
|
||||
_readRequests.clear();
|
||||
_writeJobs.clear();
|
||||
|
||||
_io->Close(flags);
|
||||
delete _io;
|
||||
_io = nullptr;
|
||||
}
|
||||
|
||||
void SecureIO::Barrier(dispatch_block_t barrier) {
|
||||
_io->Barrier(barrier);
|
||||
}
|
||||
|
||||
OSStatus readFunc(SSLConnectionRef connection, void *data, size_t *dataLength) {
|
||||
return reinterpret_cast<SecureIO *>((void *)connection)->SSLReadHandler(data, dataLength);
|
||||
};
|
||||
|
||||
OSStatus writeFunc(SSLConnectionRef connection, const void *data, size_t *dataLength) {
|
||||
return reinterpret_cast<SecureIO *>((void *)connection)->SSLWriteHandler(data, dataLength);
|
||||
};
|
||||
}
|
||||
}
|
||||
142
SocketRocketIO/Concurrent.swift
Normal file
142
SocketRocketIO/Concurrent.swift
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// Concurrent.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/7/15.
|
||||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// This is a nonblocking once. THis means that the once block
|
||||
/// may fire after the callers that don't get it succeed
|
||||
/// This is unlike the behavior of dispatch_once
|
||||
struct Once {
|
||||
var count: Int32 = 0
|
||||
|
||||
/// If this is the first one to call this, will invoke the block
|
||||
///
|
||||
/// :param: bit This structure can be used for more than one bit. We allow the first 16 bits to be used
|
||||
///
|
||||
/// :return: true if the block is ecuted
|
||||
mutating func doMaybe(bit: Int = 0, block: () -> ()) -> Bool {
|
||||
precondition(bit < 16)
|
||||
|
||||
guard !count.atomicTestAndSet(bit) else {
|
||||
return false
|
||||
}
|
||||
|
||||
block()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Int32 {
|
||||
mutating func atomicTestAndSet(bit: Int) -> Bool {
|
||||
return withUnsafeMutablePointer(&self) { ptr in
|
||||
return OSAtomicTestAndSet(UInt32(bit), ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Building block for a
|
||||
enum PState<V> {
|
||||
case Pending
|
||||
case Fulfilled(V)
|
||||
case Rejected(ErrorType)
|
||||
}
|
||||
|
||||
struct PGroup<T> {
|
||||
/// TODO: remove locking somehow
|
||||
typealias LockType = OSSpinLock
|
||||
|
||||
typealias Handler = (ErrorOptional<T>) -> ()
|
||||
|
||||
private var lock = LockType()
|
||||
|
||||
// These should only be mutated inside a lock
|
||||
private var result: ErrorOptional<T>? = nil
|
||||
|
||||
// these are blocks enqueued while we don't have a result. Should be called when we actually fulfill
|
||||
private var pendingHandlers = [Handler]()
|
||||
|
||||
var state = PState<T>.Pending
|
||||
|
||||
mutating func cancel() -> Bool {
|
||||
return reject(Error.Canceled)
|
||||
}
|
||||
|
||||
mutating func reject(e: ErrorType) -> Bool {
|
||||
return fulfill(.Error(e))
|
||||
}
|
||||
|
||||
mutating func fulfill(v: ErrorOptional<T>) -> Bool {
|
||||
guard result == nil else {
|
||||
return false
|
||||
}
|
||||
|
||||
let blocksToRun: [Handler]? = lock.withLock() {
|
||||
guard self.result == nil else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.result = v
|
||||
|
||||
let ret = self.pendingHandlers
|
||||
self.pendingHandlers.removeAll()
|
||||
return ret
|
||||
}
|
||||
|
||||
guard let b = blocksToRun else {
|
||||
return false
|
||||
}
|
||||
|
||||
for bl in b {
|
||||
bl(v)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/// Adds a handler. Called immediately if result is set. Otherwise it will enqueue
|
||||
mutating func then(h: Handler) -> Void {
|
||||
// If we have a result, return it
|
||||
if let v = self.result {
|
||||
h(v)
|
||||
return
|
||||
}
|
||||
|
||||
let valueAgain: ErrorOptional<T>? = lock.withLock {
|
||||
if let r = result {
|
||||
return r
|
||||
}
|
||||
|
||||
self.pendingHandlers.append(h)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if let v = valueAgain {
|
||||
h(v)
|
||||
}
|
||||
}
|
||||
|
||||
init () {
|
||||
|
||||
}
|
||||
|
||||
private init(result: ErrorOptional<T>) {
|
||||
self.result = result
|
||||
}
|
||||
|
||||
static func resolve<T>(v: T) -> PGroup<T> {
|
||||
return PGroup<T>(result: ErrorOptional<T>(v))
|
||||
}
|
||||
|
||||
static func reject<T>(error: ErrorType) -> PGroup<T> {
|
||||
return PGroup<T>(result: ErrorOptional<T>(error))
|
||||
}
|
||||
}
|
||||
49
SocketRocketIO/Error.swift
Normal file
49
SocketRocketIO/Error.swift
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Error.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/7/15.
|
||||
//
|
||||
//
|
||||
|
||||
/// Wraps errors. Has an uknown type if it cant resolve to an oserror
|
||||
enum Error: ErrorType {
|
||||
case Unknown(status: Int32)
|
||||
case CodecError
|
||||
case UTF8DecodeError
|
||||
case Canceled
|
||||
|
||||
/// For functions that return negative value on error and expect errno to be set
|
||||
static func checkReturnCode(returnCode: Int32) -> ErrorType? {
|
||||
guard returnCode < 0 else {
|
||||
return nil
|
||||
}
|
||||
return errorFromStatusCode(errno)
|
||||
}
|
||||
|
||||
/// Returns an error type based on status code
|
||||
static func errorFromStatusCode(status: Int32) -> ErrorType? {
|
||||
guard status != 0 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let e = POSIXError(rawValue: status) {
|
||||
return e
|
||||
}
|
||||
|
||||
return Error.Unknown(status: status)
|
||||
}
|
||||
|
||||
static func throwIfNotSuccess(status: Int32) throws {
|
||||
if let e = errorFromStatusCode(status) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
// Same as above, but checks if less than 0, and uses errno as the varaible
|
||||
static func throwIfNotSuccessLessThan0(returnCode: Int32) throws {
|
||||
if let e = checkReturnCode(returnCode) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
71
SocketRocketIO/ErrorOptional.swift
Normal file
71
SocketRocketIO/ErrorOptional.swift
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// ErrorOptional.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/3/15.
|
||||
//
|
||||
//
|
||||
|
||||
// Like optional but instead of None, it can take a nil
|
||||
public enum ErrorOptional<T> {
|
||||
case Error(ErrorType)
|
||||
case Some(T)
|
||||
|
||||
/// Returns nil if ierrored. Using checkedGet is recommended
|
||||
var orNil: T? {
|
||||
get {
|
||||
switch self {
|
||||
case let Some(some):
|
||||
return some
|
||||
case Error:
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var hasError: Bool {
|
||||
get {
|
||||
switch self {
|
||||
case Some:
|
||||
return false
|
||||
case Error:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkedGet() throws -> T {
|
||||
switch self {
|
||||
case let Some(some):
|
||||
return some
|
||||
case let Error(e):
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a non-`nil` instance that stores `some`.
|
||||
init(_ some: T) {
|
||||
self = Some(some)
|
||||
}
|
||||
|
||||
init(_ error: ErrorType) {
|
||||
self = Error(error)
|
||||
}
|
||||
|
||||
// Will catch the first error and return with error wrapped in error optinal
|
||||
static func attempt(block: () throws -> T) -> ErrorOptional<T> {
|
||||
do {
|
||||
return .Some(try block())
|
||||
} catch let e {
|
||||
return .Error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum Errors: ErrorType {
|
||||
case MultiError([ErrorType])
|
||||
}
|
||||
|
||||
|
||||
44
SocketRocketIO/Extensions.swift
Normal file
44
SocketRocketIO/Extensions.swift
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Extensions.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/6/15.
|
||||
//
|
||||
//
|
||||
|
||||
import Dispatch
|
||||
|
||||
extension dispatch_data_t {
|
||||
func apply(applier: UnsafeBufferPointer<UInt8> -> Bool) -> Bool {
|
||||
return dispatch_data_apply(self) { (_, offset, buffer, size) -> Bool in
|
||||
let mappedBuffer = unsafeBitCast(buffer, UnsafePointer<UInt8>.self)
|
||||
let buffer = UnsafeBufferPointer(start: mappedBuffer.advancedBy(offset), count: size - offset)
|
||||
return applier(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
func apply(applier: UnsafeBufferPointer<UInt8> -> ()) -> Bool {
|
||||
return self.apply { d -> Bool in
|
||||
applier(d)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func apply(applier: UnsafeBufferPointer<UInt8> throws -> ()) throws -> Bool {
|
||||
var error: ErrorType? = nil
|
||||
let ret = self.apply { d -> Bool in
|
||||
do {
|
||||
try applier(d)
|
||||
return true
|
||||
} catch let e {
|
||||
error = e
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if let e = error {
|
||||
throw e
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
}
|
||||
319
SocketRocketIO/IO.swift
Normal file
319
SocketRocketIO/IO.swift
Normal file
@ -0,0 +1,319 @@
|
||||
//
|
||||
// IO.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 7/30/15.
|
||||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SystemShims
|
||||
|
||||
public struct CloseFlags : OptionSetType {
|
||||
public init(rawValue: UInt) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
public let rawValue: UInt
|
||||
public static let Stop = CloseFlags(rawValue: DISPATCH_IO_STOP)
|
||||
}
|
||||
|
||||
public typealias DataHandler = (done: Bool, data: dispatch_data_t, error: ErrorType?) -> Void
|
||||
public typealias ErrorHandler = (error: ErrorType?) -> Void
|
||||
|
||||
public protocol IO {
|
||||
// Closes the IO. the callback will be called when finished. IO can only be closed once
|
||||
// I/Os only exist once they're open.
|
||||
func read(length: size_t, queue: Queue, handler: DataHandler)
|
||||
|
||||
func write(data: dispatch_data_t, queue: Queue, handler: DataHandler)
|
||||
|
||||
func close(queue: Queue, flags: CloseFlags)
|
||||
}
|
||||
|
||||
|
||||
public class RawIO: IO {
|
||||
private let channel: dispatch_io_t
|
||||
|
||||
public init(channel: dispatch_io_t) {
|
||||
self.channel = channel
|
||||
}
|
||||
|
||||
public convenience init(fd: dispatch_fd_t,
|
||||
cleanupQueue: Queue,
|
||||
callbackQueue: Queue,
|
||||
ioQueue: Queue,
|
||||
cleanupHandler: ErrorHandler) {
|
||||
let channel = dispatch_io_create(DISPATCH_IO_STREAM, fd, cleanupQueue.queue) { errorCode in
|
||||
cleanupHandler(error: NSError.fromErrorCode(errorCode))
|
||||
}
|
||||
|
||||
dispatch_set_target_queue(channel, ioQueue.queue);
|
||||
|
||||
self.init(channel: channel)
|
||||
}
|
||||
|
||||
public func read(length: Int, queue: Queue, handler: DataHandler) {
|
||||
dispatch_io_read(channel, 0, length, queue.queue, dataHandlerToIoHandler(handler))
|
||||
}
|
||||
|
||||
public func write(data: dispatch_data_t, queue: Queue, handler: DataHandler) {
|
||||
dispatch_io_write(channel, 0, data, queue.queue, dataHandlerToIoHandler(handler))
|
||||
}
|
||||
|
||||
public func close(queue: Queue, flags: CloseFlags) {
|
||||
dispatch_io_close(channel, flags.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typealias IOFactory = (fd: dispatch_fd_t) -> IO
|
||||
|
||||
public class Listener {
|
||||
let workQueue: Queue
|
||||
let ioFactory: IOFactory
|
||||
var eventSource: dispatch_source_t!
|
||||
|
||||
var closeHandler: ErrorHandler!
|
||||
|
||||
private init(workQueue: Queue, ioFactory: IOFactory) {
|
||||
self.workQueue = workQueue
|
||||
self.ioFactory = ioFactory
|
||||
}
|
||||
|
||||
|
||||
/// Starts listening
|
||||
///
|
||||
/// :param: queue queue callback is called on
|
||||
/// :param: callback Called when listening starts. AN error if it failed
|
||||
static func startListening(port: UInt16, address: String, workQueue: Queue, ioFactory: IOFactory, queue: Queue, callback: ErrorHandler) -> Listener {
|
||||
|
||||
let l = Listener(workQueue: workQueue, ioFactory: ioFactory)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
public func close(queue: Queue, handler: ErrorHandler) {
|
||||
workQueue.dispatchAsync {
|
||||
self.closeHandler = handler
|
||||
dispatch_source_cancel(self.eventSource)
|
||||
self.eventSource = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NSError {
|
||||
convenience init(osError: Int32) {
|
||||
self.init(domain: NSPOSIXErrorDomain, code: Int(osError), userInfo: nil)
|
||||
}
|
||||
|
||||
static func fromErrorCode(osError: Int32) -> NSError? {
|
||||
if osError == 0 {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return NSError(osError: osError)
|
||||
}
|
||||
}
|
||||
|
||||
private func dataHandlerToIoHandler(handler: DataHandler) -> dispatch_io_handler_t {
|
||||
return { done, data, errorCode in
|
||||
handler(done: done, data: data, error: NSError.fromErrorCode(errorCode))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public protocol SockAddr {
|
||||
init()
|
||||
|
||||
mutating func setup(listenAddr: Address, listenPort: UInt16) throws
|
||||
|
||||
static var size : Int {get}
|
||||
static var addressFamily: Int32 { get }
|
||||
}
|
||||
|
||||
public enum Address {
|
||||
case Loopback
|
||||
case Any
|
||||
case IPV6Addr(address: String)
|
||||
case IPV4Addr(address: String)
|
||||
}
|
||||
extension sockaddr_in6: SockAddr {
|
||||
public mutating func setup(listenAddr: Address, listenPort: UInt16) throws {
|
||||
switch listenAddr {
|
||||
case .Any:
|
||||
self.sin6_addr = in6addr_any
|
||||
case let .IPV6Addr(address: address):
|
||||
try Error.throwIfNotSuccess(inet_pton(self.dynamicType.addressFamily, address, &self.sin6_addr))
|
||||
case .IPV4Addr:
|
||||
fatalError("Cannot listen to IPV4Address in an ipv6 socket")
|
||||
case .Loopback:
|
||||
self.sin6_addr = in6addr_loopback
|
||||
}
|
||||
|
||||
self.sin6_port = listenPort.bigEndian
|
||||
self.sin6_family = sa_family_t(self.dynamicType.addressFamily)
|
||||
self.sin6_len = UInt8(self.dynamicType.size)
|
||||
}
|
||||
|
||||
public static let size = sizeof(sockaddr_in6)
|
||||
public static let addressFamily = AF_INET6
|
||||
}
|
||||
|
||||
let INADDR_ANY = in_addr(s_addr: 0x00000000)
|
||||
let INADDR_LOOPBACK4 = in_addr(s_addr: UInt32(0x7f000001).bigEndian)
|
||||
|
||||
extension sockaddr_in: SockAddr {
|
||||
public static let size = sizeof(sockaddr_in)
|
||||
public static let addressFamily = AF_INET
|
||||
|
||||
public mutating func setup(listenAddr: Address, listenPort: UInt16) throws {
|
||||
switch listenAddr {
|
||||
case .Any:
|
||||
self.sin_addr = INADDR_ANY
|
||||
case let .IPV4Addr(address: address):
|
||||
try Error.throwIfNotSuccess(inet_pton(self.dynamicType.addressFamily, address, &self.sin_addr))
|
||||
case .IPV6Addr:
|
||||
fatalError("Cannot listen to IPV6Address in an ipv4 socket")
|
||||
case .Loopback:
|
||||
self.sin_addr = INADDR_LOOPBACK4
|
||||
}
|
||||
|
||||
self.sin_port = listenPort.bigEndian
|
||||
self.sin_family = sa_family_t(self.dynamicType.addressFamily)
|
||||
self.sin_len = UInt8(self.dynamicType.size)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension SockAddr {
|
||||
// func connect() {
|
||||
// AF_INET
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
let defaultBacklog: Int32 = 5
|
||||
|
||||
// Wrapper around a raw socket. Can do ipv6 or ipv4
|
||||
public class Socket<T: SockAddr> {
|
||||
var addr = T()
|
||||
|
||||
var fd: dispatch_fd_t = -1
|
||||
|
||||
// Initializes as a nonblocking socket and starts listening. DOes not create a dispatch source
|
||||
public init(address: Address, port: UInt16) throws {
|
||||
fd = socket(T.addressFamily, SOCK_STREAM, IPPROTO_TCP)
|
||||
try Error.throwIfNotSuccessLessThan0(fd)
|
||||
do {
|
||||
let flags = shim_fcntl(fd, F_GETFL, 0);
|
||||
try Error.throwIfNotSuccessLessThan0(shim_fcntl(fd, F_SETFL, flags | O_NONBLOCK))
|
||||
|
||||
|
||||
var val: Int32 = 1;
|
||||
|
||||
try Error.throwIfNotSuccessLessThan0(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, socklen_t(sizeofValue(val))))
|
||||
|
||||
try Error.throwIfNotSuccessLessThan0(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, socklen_t(sizeofValue(val))))
|
||||
|
||||
try addr.setup(address, listenPort: port)
|
||||
|
||||
try Error.throwIfNotSuccessLessThan0(shim_bind(fd, &addr, addr.dynamicType.size))
|
||||
|
||||
try Error.throwIfNotSuccessLessThan0(listen(fd, defaultBacklog))
|
||||
} catch let e {
|
||||
close(fd)
|
||||
self.fd = -1
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/// Cancel handler isn't guaranteed to dispatch on a specific queue
|
||||
/// Returns a block that starts the cancel
|
||||
public func startAccepting(workQueue: Queue, cancelHandler: () -> Void, acceptHandler:(fd: dispatch_fd_t) -> Void) -> (() -> Void) {
|
||||
precondition(fd >= 0)
|
||||
|
||||
let eventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, UInt(fd), 0, workQueue.queue)
|
||||
dispatch_source_set_event_handler(eventSource) {
|
||||
var remoteAddress = T()
|
||||
var len = socklen_t(remoteAddress.dynamicType.size);
|
||||
|
||||
let native: dispatch_fd_t = shim_accept(self.fd, &remoteAddress, &len)
|
||||
if native == -1 {
|
||||
return;
|
||||
}
|
||||
|
||||
acceptHandler(fd: native)
|
||||
}
|
||||
|
||||
dispatch_source_set_cancel_handler(eventSource) {
|
||||
precondition(self.fd >= 0)
|
||||
close(self.fd);
|
||||
self.fd = -1
|
||||
|
||||
cancelHandler()
|
||||
}
|
||||
|
||||
dispatch_resume(eventSource);
|
||||
|
||||
return {
|
||||
dispatch_source_cancel(eventSource)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension dispatch_data_t {
|
||||
var empty: Bool {
|
||||
get {
|
||||
return dispatch_data_empty === self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var hints: addrinfo = {
|
||||
var hints = addrinfo()
|
||||
hints.ai_family = PF_UNSPEC
|
||||
hints.ai_socktype = SOCK_STREAM
|
||||
return hints
|
||||
}()
|
||||
|
||||
|
||||
extension Queue {
|
||||
/// Used to dispatch synchronous operations on a specific queue
|
||||
func blockingPromise<T>(blockingFn: () throws -> T) -> Promise<T> {
|
||||
let (r, p) = Promise<T>.resolver()
|
||||
|
||||
self.dispatchAsync {
|
||||
r.attemptResolve { return try blockingFn()}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
public func getaddrinfoAsync(hostname: String, servname: String, workQueue: Queue = Queue.defaultGlobalQueue) -> Promise<[addrinfo]> {
|
||||
return workQueue.blockingPromise {
|
||||
var ai: UnsafeMutablePointer<addrinfo> = nil
|
||||
defer {
|
||||
if ai != nil {
|
||||
freeaddrinfo(ai)
|
||||
}
|
||||
}
|
||||
|
||||
// ai won't be set if it doesn't work
|
||||
// TODO(lewis) propagate error up
|
||||
try Error.throwIfNotSuccess(getaddrinfo(hostname, servname, &hints, &ai))
|
||||
var ret = [addrinfo]()
|
||||
|
||||
var curAi = ai
|
||||
while curAi != nil {
|
||||
var mutatedAI = curAi.memory
|
||||
let next = mutatedAI.ai_next
|
||||
mutatedAI.ai_next = nil
|
||||
ret.append(mutatedAI)
|
||||
curAi = next
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
26
SocketRocketIO/Info.plist
Normal file
26
SocketRocketIO/Info.plist
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
34
SocketRocketIO/Lock.swift
Normal file
34
SocketRocketIO/Lock.swift
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Lock.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/3/15.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
protocol Lock {
|
||||
mutating func lock()
|
||||
mutating func unlock()
|
||||
}
|
||||
|
||||
extension Lock {
|
||||
mutating func withLock<Result>(@noescape fn: () throws -> Result) rethrows -> Result {
|
||||
lock()
|
||||
defer {
|
||||
unlock()
|
||||
}
|
||||
return try fn()
|
||||
}
|
||||
}
|
||||
|
||||
extension OSSpinLock: Lock {
|
||||
mutating func lock() {
|
||||
withUnsafeMutablePointer(&self, OSSpinLockLock)
|
||||
}
|
||||
|
||||
mutating func unlock() {
|
||||
withUnsafeMutablePointer(&self, OSSpinLockUnlock)
|
||||
}
|
||||
}
|
||||
188
SocketRocketIO/Promise.swift
Normal file
188
SocketRocketIO/Promise.swift
Normal file
@ -0,0 +1,188 @@
|
||||
//
|
||||
// Promise.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/3/15.
|
||||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
// Only part of a promise protocol. It defines that it can be terminated
|
||||
|
||||
|
||||
// Represents a return type that can either be a promise or a value
|
||||
public enum PromiseOrValue<V> {
|
||||
public typealias P = Promise<V>
|
||||
|
||||
case Promised(P)
|
||||
case Value(P.ET)
|
||||
|
||||
static func of<V>(val: V) -> PromiseOrValue<V> {
|
||||
return .Value(ErrorOptional<V>(val))
|
||||
}
|
||||
}
|
||||
|
||||
func wrap<T>(queue: Queue?, fn:(T) -> ()) -> (T) -> () {
|
||||
if let q = queue {
|
||||
return q.wrap(fn)
|
||||
}
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
extension Queue {
|
||||
/// wraps a void function and returns a new one. When
|
||||
/// the new one is called it will be dispatched on the sender
|
||||
func wrap<T>(fn:(T) -> ()) -> (T) -> () {
|
||||
return { v in
|
||||
self.dispatchAsync {
|
||||
fn(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct Resolver<T> {
|
||||
public typealias ET = ErrorOptional<T>
|
||||
|
||||
typealias P = Promise<T>
|
||||
private let promise: P
|
||||
|
||||
init(promise: P) {
|
||||
self.promise = promise
|
||||
}
|
||||
|
||||
public func resolve(value: T) {
|
||||
fulfill(ET(value))
|
||||
}
|
||||
|
||||
public func reject(error: ErrorType) {
|
||||
fulfill(ET(error))
|
||||
}
|
||||
|
||||
/// resolves with the return value. Otherwise if it throws, it will return as an error type
|
||||
public func attemptResolve(block: () throws -> T) {
|
||||
fulfill(ET.attempt { return try block() })
|
||||
}
|
||||
|
||||
public func fulfill(v: ET) {
|
||||
promise.fulfill(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Useful for stuff that can only succeed and not return any errors
|
||||
public typealias VoidPromiseType = Promise<Void>
|
||||
public typealias VoidResolverType = Resolver<Void>
|
||||
|
||||
public class Promise<T> {
|
||||
/// Error optional type
|
||||
public typealias ET = ErrorOptional<T>
|
||||
|
||||
typealias PG = PGroup<T>
|
||||
|
||||
var pgroup: PG
|
||||
|
||||
typealias PV = PromiseOrValue<T>
|
||||
|
||||
typealias ValueType = T
|
||||
|
||||
private init(pgroup: PG) {
|
||||
self.pgroup = pgroup
|
||||
}
|
||||
|
||||
public class func resolve(value: T) -> Promise<T> {
|
||||
return Promise<T>(pgroup: PGroup<T>.resolve(value))
|
||||
}
|
||||
|
||||
public class func reject(error: ErrorType) -> Promise<T> {
|
||||
return Promise<T>(pgroup: PGroup<T>.reject(error))
|
||||
}
|
||||
|
||||
// Returns a promise and the resolver for it
|
||||
public class func resolver() -> (Resolver<T>, Promise<T>) {
|
||||
let p = Promise<T>()
|
||||
let r = Resolver(promise: p)
|
||||
return (r, p)
|
||||
}
|
||||
|
||||
// An uninitialized one
|
||||
init() {
|
||||
pgroup = PG()
|
||||
}
|
||||
|
||||
// splits the call based one rror or success
|
||||
public func thenSplit<R>(queue: Queue? = nil, error: ((ErrorType) -> ())? = nil, success: T -> PromiseOrValue<R>) -> Promise<R> {
|
||||
return self.then { (r:ET) -> PromiseOrValue<R> in
|
||||
switch r {
|
||||
case let .Error(e):
|
||||
error?(e)
|
||||
// TODO: improve this .Not very efficient
|
||||
return PromiseOrValue.Value(Promise<R>.ET(e))
|
||||
case let .Some(val):
|
||||
return success(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func then<R>(queue: Queue? = nil, handler: ET -> PromiseOrValue<R>) -> Promise<R> {
|
||||
let (r, p) = Promise<R>.resolver()
|
||||
|
||||
self.then(queue) { v -> Void in
|
||||
switch handler(v) {
|
||||
case let .Promised(prom):
|
||||
prom.then(handler: r.fulfill)
|
||||
case let .Value(val):
|
||||
r.fulfill(val)
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/// Terminating
|
||||
func then(queue: Queue? = nil, handler: ET -> Void) {
|
||||
self.pgroup.then(wrap(queue, fn: handler))
|
||||
}
|
||||
|
||||
public func then<R>(queue: Queue? = nil, handler: ET -> Promise<R>.ET) -> Promise<R> {
|
||||
let (r, p) = Promise<R>.resolver()
|
||||
|
||||
self.then(queue) { v -> Void in
|
||||
r.fulfill(handler(v))
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/// Catches an error and propagates it in the optitional
|
||||
///
|
||||
/// Callers of this should use the .checkedGet on the input type to make it easy to propagate errors
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// p.thenChecked{ v throws in
|
||||
/// return try v.checkedGet() + 3
|
||||
/// }
|
||||
public func thenChecked<R>(queue: Queue? = nil, handler: ET throws -> R) -> Promise<R> {
|
||||
typealias RP = Promise<R>
|
||||
typealias RET = RP.ET
|
||||
|
||||
return self.then(queue) { val -> ErrorOptional<R> in
|
||||
do {
|
||||
return RET(try handler(val))
|
||||
} catch let e {
|
||||
return RET(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func fulfill(value: ET) {
|
||||
pgroup.fulfill(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
58
SocketRocketIO/Queue.swift
Normal file
58
SocketRocketIO/Queue.swift
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// Queue.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 7/30/15.
|
||||
//
|
||||
// Wrappers areound dispatch_queue_t
|
||||
|
||||
import Foundation
|
||||
import Dispatch
|
||||
|
||||
/// Simple wrapper around dispatch_queue_t
|
||||
public class Queue {
|
||||
let queue: dispatch_queue_t
|
||||
|
||||
// used to check current queue
|
||||
private var ctxKeyValue: UnsafeMutablePointer<Void> = nil
|
||||
|
||||
/// same as dispatch_get_main_queue()
|
||||
public static let mainQueue = Queue(queue: dispatch_get_main_queue())
|
||||
|
||||
public static let defaultGlobalQueue = Queue(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
|
||||
|
||||
public required init(queue: dispatch_queue_t) {
|
||||
self.queue = queue
|
||||
|
||||
withUnsafeMutablePointer(&self.ctxKeyValue) { ptr in
|
||||
self.ctxKeyValue = unsafeBitCast(ptr, UnsafeMutablePointer<Void>.self);
|
||||
}
|
||||
|
||||
let destructor: dispatch_function_t! = nil
|
||||
dispatch_queue_set_specific(self.queue, ctxKeyValue, ctxKeyValue, destructor)
|
||||
}
|
||||
|
||||
public convenience init(label: String, attr: dispatch_queue_attr_t? = DISPATCH_QUEUE_SERIAL) {
|
||||
self.init(queue: dispatch_queue_create(label, attr))
|
||||
}
|
||||
|
||||
deinit {
|
||||
let destructor: dispatch_function_t! = nil
|
||||
dispatch_queue_set_specific(self.queue, ctxKeyValue, nil, destructor)
|
||||
}
|
||||
|
||||
public func dispatchAsync(block: () -> Void) {
|
||||
dispatch_async(queue, block)
|
||||
}
|
||||
|
||||
/// Returns true if we're on the current queue
|
||||
public func isCurrentQueue() -> Bool {
|
||||
let currentContext = dispatch_get_specific(ctxKeyValue)
|
||||
return currentContext == ctxKeyValue
|
||||
}
|
||||
|
||||
public func checkIsCurrentQueue() {
|
||||
precondition(isCurrentQueue(), "Expected to be current queue")
|
||||
}
|
||||
}
|
||||
|
||||
18
SocketRocketIO/SocketRocketIO.h
Normal file
18
SocketRocketIO/SocketRocketIO.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// SocketRocketIO.h
|
||||
// SocketRocketIO
|
||||
//
|
||||
// Created by Mike Lewis on 7/30/15.
|
||||
//
|
||||
//
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for SocketRocketIO.
|
||||
FOUNDATION_EXPORT double SocketRocketIOVersionNumber;
|
||||
|
||||
//! Project version string for SocketRocketIO.
|
||||
FOUNDATION_EXPORT const unsigned char SocketRocketIOVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <SocketRocketIO/PublicHeader.h>
|
||||
|
||||
|
||||
168
SocketRocketIO/Unicode.swift
Normal file
168
SocketRocketIO/Unicode.swift
Normal file
@ -0,0 +1,168 @@
|
||||
//
|
||||
// Unicode.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/6/15.
|
||||
//
|
||||
//
|
||||
|
||||
extension UTF8 {
|
||||
/// Returns number of code units. Throws if its not the first bite of a unicode charactser
|
||||
/// result includes selve
|
||||
static func numCodeUnits(first: CodeUnit) throws -> Int {
|
||||
guard first & 0b1100_0000 != 0b1000_0000 else {
|
||||
throw Error.UTF8DecodeError
|
||||
}
|
||||
|
||||
// If the first bit is 0, its a single code-point
|
||||
if first & 0b1000_0000 == 0b0000_0000 {
|
||||
return 1
|
||||
}
|
||||
|
||||
if first & 0b1110_0000 == 0b1100_0000 {
|
||||
return 2
|
||||
}
|
||||
|
||||
if first & 0b1111_0000 == 0b1110_0000 {
|
||||
return 3
|
||||
}
|
||||
|
||||
if first & 0b1111_1000 == 0b1111_0000 {
|
||||
return 4
|
||||
}
|
||||
|
||||
throw Error.UTF8DecodeError
|
||||
}
|
||||
|
||||
/// Returns the number of valid codeunits from the generator
|
||||
static func numValidCodeUnits<G: GeneratorType where G.Element == CodeUnit>(var g: G) throws -> Int {
|
||||
var numValidCodeUnits = 0
|
||||
outOfCharacters:
|
||||
for var c = g.next(); c != nil; c = g.next() {
|
||||
let numCodeUnits = try UTF8.numCodeUnits(c!)
|
||||
for _ in 0..<(numCodeUnits - 1) {
|
||||
if let c = g.next() {
|
||||
guard UTF8.isContinuation(c) else {
|
||||
throw Error.UTF8DecodeError
|
||||
}
|
||||
} else {
|
||||
break outOfCharacters
|
||||
}
|
||||
}
|
||||
numValidCodeUnits += numCodeUnits
|
||||
}
|
||||
|
||||
return numValidCodeUnits
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct RawUTF8Codec<CT: CollectionType, GT: GeneratorType where CT.Generator == GT, GT.Element == UInt8, CT.Index.Distance == Int, CT.Index: RandomAccessIndexType, CT.Generator.Element == UInt8, CT.SubSequence.Generator.Element == UInt8> : Codec {
|
||||
typealias InType = CT
|
||||
typealias OutType = String.UnicodeScalarView
|
||||
|
||||
typealias CodeUnit = UInt8
|
||||
|
||||
typealias UnicodeCodec = UTF8
|
||||
|
||||
|
||||
var outputBuffer = String()
|
||||
|
||||
/// Used to buffer unfinished UTF8 Sequences
|
||||
var inputBuffer = [CodeUnit]()
|
||||
|
||||
/// Consumes to our outputbuffer
|
||||
mutating func consume<G: GeneratorType where G.Element == CodeUnit>(var g: G) throws {
|
||||
var uc = UTF8()
|
||||
|
||||
while true {
|
||||
switch uc.decode(&g) {
|
||||
case .EmptyInput:
|
||||
return
|
||||
case .Error:
|
||||
throw Error.UTF8DecodeError
|
||||
case let .Result(scalar):
|
||||
outputBuffer.append(scalar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mutating func code(input: ValueOrEnd<AnyRandomAccessCollection<InType.Generator.Element>>) throws -> OutType {
|
||||
defer {
|
||||
outputBuffer.removeAll(keepCapacity: true)
|
||||
}
|
||||
|
||||
switch input {
|
||||
case .End:
|
||||
if inputBuffer.isEmpty {
|
||||
return "".unicodeScalars
|
||||
} else {
|
||||
throw Error.UTF8DecodeError
|
||||
}
|
||||
case let .Value(v):
|
||||
let totalSize = inputBuffer.count + v.count
|
||||
|
||||
outputBuffer.reserveCapacity(Int(totalSize))
|
||||
|
||||
let numValidCodeUnits = try UTF8.numValidCodeUnits(inputBuffer.generate() + v.generate())
|
||||
|
||||
let numUnfinished = totalSize - numValidCodeUnits
|
||||
|
||||
|
||||
// If this happens, we didn't get enough for even one character
|
||||
if numUnfinished == totalSize {
|
||||
inputBuffer += v
|
||||
return "".unicodeScalars
|
||||
}
|
||||
|
||||
if numUnfinished > 0 {
|
||||
let truncatedG = v[v.startIndex..<v.endIndex.advancedBy(-numUnfinished)].generate()
|
||||
let g = inputBuffer.generate() + truncatedG
|
||||
|
||||
try consume(g)
|
||||
} else {
|
||||
try consume(inputBuffer.generate() + v.generate())
|
||||
}
|
||||
|
||||
inputBuffer.removeAll(keepCapacity: true)
|
||||
if numUnfinished > 0 {
|
||||
inputBuffer += v[v.endIndex.advancedBy(-numUnfinished)..<v.endIndex]
|
||||
}
|
||||
|
||||
return outputBuffer.unicodeScalars
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DispatchIO: AsyncReadable {
|
||||
typealias Collection = UnsafeBufferPointer<UInt8>
|
||||
|
||||
func read(size: Collection.Index.Distance, queue: Queue, handler: (AnyRandomAccessCollection<Collection.Generator.Element>) throws -> ()) -> VoidPromiseType {
|
||||
let (r, p) = VoidPromiseType.resolver()
|
||||
|
||||
dispatch_io_read(io, 0, size, queue.queue) { finished, data, error in
|
||||
guard error == 0 else {
|
||||
r.reject(Error.errorFromStatusCode(error)!)
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
try data.apply { d in
|
||||
try handler(AnyRandomAccessCollection(d))
|
||||
}
|
||||
} catch let e {
|
||||
// TODO(don't double-call this error)
|
||||
r.reject(e)
|
||||
return
|
||||
}
|
||||
|
||||
if finished {
|
||||
r.resolve(Void())
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
135
SocketRocketIOTests/ConcurrentTests.swift
Normal file
135
SocketRocketIOTests/ConcurrentTests.swift
Normal file
@ -0,0 +1,135 @@
|
||||
//
|
||||
// ConcurrentTests.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/7/15.
|
||||
//
|
||||
//
|
||||
|
||||
@testable import SocketRocketIO
|
||||
import XCTest
|
||||
|
||||
class ConcurrentTests: XCTestCase {
|
||||
func testOnce_simple() {
|
||||
var once = Once()
|
||||
|
||||
let e2 = expectationWithDescription("All done")
|
||||
|
||||
let g = dispatch_group_create()
|
||||
let g2 = dispatch_group_create()
|
||||
|
||||
dispatch_group_enter(g)
|
||||
dispatch_group_notify(g2, Queue.defaultGlobalQueue.queue) {
|
||||
e2.fulfill()
|
||||
}
|
||||
|
||||
for bit in 0..<8 {
|
||||
let e = expectationWithDescription("Once filled")
|
||||
for _ in 0..<1000 {
|
||||
dispatch_group_enter(g2)
|
||||
dispatch_group_notify(g, Queue.defaultGlobalQueue.queue) {
|
||||
once.doMaybe(bit, block: {
|
||||
e.fulfill()
|
||||
})
|
||||
dispatch_group_leave(g2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_group_leave(g)
|
||||
waitForExpectations()
|
||||
}
|
||||
|
||||
func testPerformanceExample() {
|
||||
// This is an example of a performance test case.
|
||||
self.measureBlock {
|
||||
// Put the code you want to measure the time of here.
|
||||
}
|
||||
}
|
||||
|
||||
func testPGroup_noerr() {
|
||||
var p = PGroup<Int>()
|
||||
|
||||
p.fulfill(ErrorOptional(3))
|
||||
|
||||
for i in 0..<20 {
|
||||
let e = self.expectationWithDescription("e \(i)")
|
||||
p.then { v in
|
||||
XCTAssertFalse(v.hasError)
|
||||
e.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
func testPGroup_after() {
|
||||
var p = PGroup<Int>()
|
||||
|
||||
for i in 0..<20 {
|
||||
let e = self.expectationWithDescription("e \(i)")
|
||||
p.then { v in
|
||||
XCTAssertFalse(v.hasError)
|
||||
e.fulfill()
|
||||
switch v {
|
||||
case let .Some(val):
|
||||
XCTAssertEqual(val, 3)
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.fulfill(ErrorOptional(3))
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
func testPGroup_calledOnce() {
|
||||
var p = PGroup<Int>()
|
||||
|
||||
for i in 0..<20 {
|
||||
let e = self.expectationWithDescription("e \(i)")
|
||||
p.then { v in
|
||||
switch v {
|
||||
case let .Some(val):
|
||||
XCTAssertEqual(val, 3)
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
e.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p.fulfill(ErrorOptional(3))
|
||||
p.fulfill(ErrorOptional(4))
|
||||
p.fulfill(ErrorOptional(Error.Canceled))
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
func testPGroup_canceled() {
|
||||
var p = PGroup<Int>()
|
||||
|
||||
for i in 0..<20 {
|
||||
let e = self.expectationWithDescription("e \(i)")
|
||||
p.then { v in
|
||||
switch v {
|
||||
case .Error(Error.Canceled):
|
||||
break
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
e.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
p.cancel()
|
||||
p.fulfill(ErrorOptional(3))
|
||||
p.fulfill(ErrorOptional(4))
|
||||
p.fulfill(ErrorOptional(Error.Canceled))
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
}
|
||||
5
SocketRocketIOTests/Fixtures/FileToReadFrom.txt
Normal file
5
SocketRocketIOTests/Fixtures/FileToReadFrom.txt
Normal file
@ -0,0 +1,5 @@
|
||||
hello
|
||||
this
|
||||
is a file
|
||||
|
||||
I like to read from it
|
||||
212
SocketRocketIOTests/Fixtures/UTF8Sample.txt
Normal file
212
SocketRocketIOTests/Fixtures/UTF8Sample.txt
Normal file
@ -0,0 +1,212 @@
|
||||
|
||||
UTF-8 encoded sample plain-text file
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25
|
||||
|
||||
|
||||
The ASCII compatible UTF-8 encoding used in this plain-text file
|
||||
is defined in Unicode, ISO 10646-1, and RFC 2279.
|
||||
|
||||
|
||||
Using Unicode/UTF-8, you can write in emails and source code things such as
|
||||
|
||||
Mathematics and sciences:
|
||||
|
||||
∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
|
||||
⎪⎢⎜│a²+b³ ⎟⎥⎪
|
||||
∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
|
||||
⎪⎢⎜⎷ c₈ ⎟⎥⎪
|
||||
ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
|
||||
⎪⎢⎜ ∞ ⎟⎥⎪
|
||||
⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
|
||||
⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
|
||||
2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭
|
||||
|
||||
Linguistics and dictionaries:
|
||||
|
||||
ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
|
||||
Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
|
||||
|
||||
APL:
|
||||
|
||||
((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
|
||||
|
||||
Nicer typography in plain text files:
|
||||
|
||||
╔══════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ • ‘single’ and “double” quotes ║
|
||||
║ ║
|
||||
║ • Curly apostrophes: “We’ve been here” ║
|
||||
║ ║
|
||||
║ • Latin-1 apostrophe and accents: '´` ║
|
||||
║ ║
|
||||
║ • ‚deutsche‘ „Anführungszeichen“ ║
|
||||
║ ║
|
||||
║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
|
||||
║ ║
|
||||
║ • ASCII safety test: 1lI|, 0OD, 8B ║
|
||||
║ ╭─────────╮ ║
|
||||
║ • the euro symbol: │ 14.95 € │ ║
|
||||
║ ╰─────────╯ ║
|
||||
╚══════════════════════════════════════════╝
|
||||
|
||||
Combining characters:
|
||||
|
||||
STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
|
||||
|
||||
Greek (in Polytonic):
|
||||
|
||||
The Greek anthem:
|
||||
|
||||
Σὲ γνωρίζω ἀπὸ τὴν κόψη
|
||||
τοῦ σπαθιοῦ τὴν τρομερή,
|
||||
σὲ γνωρίζω ἀπὸ τὴν ὄψη
|
||||
ποὺ μὲ βία μετράει τὴ γῆ.
|
||||
|
||||
᾿Απ᾿ τὰ κόκκαλα βγαλμένη
|
||||
τῶν ῾Ελλήνων τὰ ἱερά
|
||||
καὶ σὰν πρῶτα ἀνδρειωμένη
|
||||
χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
|
||||
|
||||
From a speech of Demosthenes in the 4th century BC:
|
||||
|
||||
Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
|
||||
ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
|
||||
λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
|
||||
τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
|
||||
εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
|
||||
πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
|
||||
οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
|
||||
οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
|
||||
ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
|
||||
τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
|
||||
γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
|
||||
προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
|
||||
σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
|
||||
τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
|
||||
τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
|
||||
τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
|
||||
|
||||
Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
|
||||
|
||||
Georgian:
|
||||
|
||||
From a Unicode conference invitation:
|
||||
|
||||
გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
|
||||
კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
|
||||
ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
|
||||
ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
|
||||
ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
|
||||
ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
|
||||
ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
|
||||
|
||||
Russian:
|
||||
|
||||
From a Unicode conference invitation:
|
||||
|
||||
Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
|
||||
Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
|
||||
Конференция соберет широкий круг экспертов по вопросам глобального
|
||||
Интернета и Unicode, локализации и интернационализации, воплощению и
|
||||
применению Unicode в различных операционных системах и программных
|
||||
приложениях, шрифтах, верстке и многоязычных компьютерных системах.
|
||||
|
||||
Thai (UCS Level 2):
|
||||
|
||||
Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
|
||||
classic 'San Gua'):
|
||||
|
||||
[----------------------------|------------------------]
|
||||
๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
|
||||
สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
|
||||
ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
|
||||
โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
|
||||
เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
|
||||
ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
|
||||
พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
|
||||
ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
|
||||
|
||||
(The above is a two-column text. If combining characters are handled
|
||||
correctly, the lines of the second column should be aligned with the
|
||||
| character above.)
|
||||
|
||||
Ethiopian:
|
||||
|
||||
Proverbs in the Amharic language:
|
||||
|
||||
ሰማይ አይታረስ ንጉሥ አይከሰስ።
|
||||
ብላ ካለኝ እንደአባቴ በቆመጠኝ።
|
||||
ጌጥ ያለቤቱ ቁምጥና ነው።
|
||||
ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
|
||||
የአፍ ወለምታ በቅቤ አይታሽም።
|
||||
አይጥ በበላ ዳዋ ተመታ።
|
||||
ሲተረጉሙ ይደረግሙ።
|
||||
ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
|
||||
ድር ቢያብር አንበሳ ያስር።
|
||||
ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
|
||||
እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
|
||||
የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
|
||||
ሥራ ከመፍታት ልጄን ላፋታት።
|
||||
ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
|
||||
የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
|
||||
ተንጋሎ ቢተፉ ተመልሶ ባፉ።
|
||||
ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
|
||||
እግርህን በፍራሽህ ልክ ዘርጋ።
|
||||
|
||||
Runes:
|
||||
|
||||
ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
|
||||
|
||||
(Old English, which transcribed into Latin reads 'He cwaeth that he
|
||||
bude thaem lande northweardum with tha Westsae.' and means 'He said
|
||||
that he lived in the northern land near the Western Sea.')
|
||||
|
||||
Braille:
|
||||
|
||||
⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
|
||||
|
||||
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
|
||||
⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
|
||||
⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
|
||||
⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
|
||||
⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
|
||||
⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
|
||||
|
||||
⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
|
||||
|
||||
⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
|
||||
⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
|
||||
⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
|
||||
⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
|
||||
⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
|
||||
⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
|
||||
⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
|
||||
⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
|
||||
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
|
||||
|
||||
(The first couple of paragraphs of "A Christmas Carol" by Dickens)
|
||||
|
||||
Compact font selection example text:
|
||||
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
|
||||
abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
|
||||
–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
|
||||
∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi<>⑀₂ἠḂӥẄɐː⍎אԱა
|
||||
|
||||
Greetings in various languages:
|
||||
|
||||
Hello world, Καλημέρα κόσμε, コンニチハ
|
||||
|
||||
Box drawing alignment tests: █
|
||||
▉
|
||||
╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
|
||||
║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
|
||||
║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
|
||||
╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
|
||||
║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
|
||||
║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
|
||||
╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
|
||||
▝▀▘▙▄▟
|
||||
74
SocketRocketIOTests/IOTests.swift
Normal file
74
SocketRocketIOTests/IOTests.swift
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// IOTests.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 7/31/15.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
enum FailureError: ErrorType {
|
||||
case Failure
|
||||
}
|
||||
|
||||
import XCTest
|
||||
@testable import SocketRocketIO
|
||||
|
||||
class IOTests: XCTestCase {
|
||||
func testGetAddrInfoAsync() {
|
||||
let promise: Promise<[addrinfo]> = getaddrinfoAsync("squareup.com", servname: "443")
|
||||
.thenChecked { v in
|
||||
let v = try v.checkedGet()
|
||||
XCTAssertGreaterThan(v.count, 0)
|
||||
return v
|
||||
}
|
||||
.thenChecked(Queue.mainQueue) { (v: ErrorOptional<[addrinfo]>) throws in
|
||||
guard Queue.mainQueue.isCurrentQueue() else {
|
||||
throw FailureError.Failure
|
||||
}
|
||||
return try v.checkedGet()
|
||||
}
|
||||
|
||||
|
||||
self.expectationWithPromise(promise)
|
||||
}
|
||||
|
||||
func testGetAddrInfoAsyncFailure() {
|
||||
let promise: Promise<[addrinfo]> = getaddrinfoAsync("", servname: "")
|
||||
self.expectationWithFailingPromise(promise)
|
||||
}
|
||||
|
||||
func testListen() {
|
||||
return
|
||||
do {
|
||||
let acceptExpectation = expectationWithDescription("waiting")
|
||||
|
||||
let cancelGroup = dispatch_group_create()
|
||||
dispatch_group_enter(cancelGroup)
|
||||
let s = try Socket<sockaddr_in>(address: .Loopback, port: 9231)
|
||||
let canceler = s.startAccepting(
|
||||
Queue.mainQueue,
|
||||
cancelHandler: {
|
||||
dispatch_group_leave(cancelGroup)
|
||||
},
|
||||
acceptHandler: {
|
||||
(fd) -> Void in
|
||||
close(fd)
|
||||
acceptExpectation.fulfill()
|
||||
})
|
||||
|
||||
|
||||
waitForExpectations()
|
||||
|
||||
let cancelExpection = expectationWithDescription("Canceled")
|
||||
|
||||
dispatch_group_notify(cancelGroup, dispatch_get_main_queue()) {
|
||||
cancelExpection.fulfill()
|
||||
}
|
||||
canceler()
|
||||
waitForExpectations()
|
||||
} catch let e {
|
||||
XCTFail("\(e)")
|
||||
}
|
||||
}
|
||||
}
|
||||
24
SocketRocketIOTests/Info.plist
Normal file
24
SocketRocketIOTests/Info.plist
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
230
SocketRocketIOTests/PromisesTests.swift
Normal file
230
SocketRocketIOTests/PromisesTests.swift
Normal file
@ -0,0 +1,230 @@
|
||||
//
|
||||
// PromisesTests.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/3/15.
|
||||
//
|
||||
//
|
||||
|
||||
@testable import SocketRocketIO
|
||||
import XCTest
|
||||
|
||||
|
||||
class PromisesTests: XCTestCase {
|
||||
func testAlreadyReady() {
|
||||
let firstPromise = Promise.resolve(3)
|
||||
|
||||
let lastPromise = firstPromise
|
||||
|
||||
self.expectationWithPromise(lastPromise) { v in v == 3 }
|
||||
}
|
||||
|
||||
func testAlreadyReady_chained() {
|
||||
let lastPromise = Promise.resolve(3)
|
||||
.thenSplit(success: { x in return .Promised(.resolve(x + 4)) })
|
||||
.thenSplit(success: { v in return .of(v + 5) })
|
||||
|
||||
self.expectationWithPromise(lastPromise) { v in v == 12 }
|
||||
}
|
||||
|
||||
func testNotReady_chained() {
|
||||
let (r, p) = Promise<Int>.resolver()
|
||||
|
||||
let lastPromise = p
|
||||
.thenSplit(success: { v in return .Promised(.resolve(v + 4)) })
|
||||
.thenSplit(success: { v in return .of(v + 5) })
|
||||
|
||||
self.expectationWithPromise(lastPromise, wait: false) { v in v == 12 }
|
||||
|
||||
r.resolve(3)
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
|
||||
func testNotReady_chained2() {
|
||||
let (r, p) = Promise<Int>.resolver()
|
||||
|
||||
let lastPromise = p
|
||||
.thenSplit(success: { v in return .of(v + 4) })
|
||||
.thenSplit(success: { v in return .of(v + 5) })
|
||||
.then { val -> ErrorOptional<Int> in
|
||||
switch val {
|
||||
case .Error:
|
||||
preconditionFailure("Should not get here")
|
||||
case let .Some(v):
|
||||
return .Some(v + 5)
|
||||
}
|
||||
}
|
||||
|
||||
self.expectationWithPromise(lastPromise, wait: false) { v in v == 17 }
|
||||
|
||||
r.resolve(3)
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
|
||||
func testDispatchesOnQueue_dispatchesOnQue() {
|
||||
let (r, p) = Promise<Int>.resolver()
|
||||
|
||||
let e1 = self.expectationWithDescription("1")
|
||||
let e2 = self.expectationWithDescription("2")
|
||||
|
||||
let q1 = Queue.defaultGlobalQueue
|
||||
let q2 = Queue(label: "random queue")
|
||||
|
||||
|
||||
let lastPromise = p
|
||||
.thenChecked(q1) { v throws -> Int in
|
||||
XCTAssertTrue(q1.isCurrentQueue())
|
||||
e1.fulfill()
|
||||
return try v.checkedGet() + 2
|
||||
}
|
||||
.thenChecked(q2) { v throws -> Int in
|
||||
XCTAssertTrue(q2.isCurrentQueue())
|
||||
e2.fulfill()
|
||||
return try v.checkedGet() + 2
|
||||
}
|
||||
|
||||
self.expectationWithPromise(lastPromise, wait: false) { v in v == 7 }
|
||||
|
||||
r.resolve(3)
|
||||
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
func testErrorHandling() {
|
||||
self.expectationWithFailingPromise(Promise<Int>.reject(POSIXError.ENOEXEC)) { v in
|
||||
switch v {
|
||||
case POSIXError.ENOEXEC:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let lastPromise = Promise.resolve(3)
|
||||
.thenSplit { v in return .of(v + 4) }
|
||||
.thenSplit { v in return .of(v + 5) }
|
||||
.then { val -> ErrorOptional<Int> in
|
||||
return .Error(POSIXError.ENODATA)
|
||||
}
|
||||
|
||||
self.expectationWithFailingPromise(lastPromise)
|
||||
|
||||
}
|
||||
|
||||
func testOkChecked() {
|
||||
let lastPromise = Promise.resolve(3)
|
||||
.thenSplit { v in return .of(v + 4) }
|
||||
.thenSplit { v in return .of(v + 5) }
|
||||
.thenChecked { v throws in
|
||||
return try v.checkedGet() + 3
|
||||
}
|
||||
|
||||
self.expectationWithPromise(lastPromise) { v in
|
||||
return v == 15
|
||||
}
|
||||
}
|
||||
|
||||
func testFailedChecked() {
|
||||
let lastPromise = Promise.resolve(3)
|
||||
.thenSplit { v in return .of(v + 4) }
|
||||
.thenSplit { v in return .of(v + 5) }
|
||||
.thenChecked { _ throws -> Int in
|
||||
throw POSIXError.ENOENT
|
||||
}
|
||||
|
||||
self.expectationWithFailingPromise(lastPromise) { v in
|
||||
switch v {
|
||||
case POSIXError.ENOENT:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testFailedCascade() {
|
||||
let lastPromise = Promise.resolve(3)
|
||||
.thenChecked { _ throws -> Int in
|
||||
throw POSIXError.ECANCELED
|
||||
}
|
||||
.thenSplit { v in return .of(v + 4) }
|
||||
.thenSplit { v in return .of(v + 5) }
|
||||
.thenChecked { v throws -> Int in
|
||||
try v.checkedGet()
|
||||
throw POSIXError.ENOENT
|
||||
}
|
||||
|
||||
self.expectationWithFailingPromise(lastPromise) { v in
|
||||
switch v {
|
||||
case POSIXError.ECANCELED:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension XCTestCase {
|
||||
// Terminates a promise and returns an XCTestExpectation for it
|
||||
func expectationWithPromise<T>(promise: Promise<T>, wait: Bool = true, file: String = __FILE__, line: UInt = __LINE__, predicate: (T) -> Bool = { _ in true}) -> XCTestExpectation {
|
||||
|
||||
let description = "Waiting for promise \(promise) to fulfill"
|
||||
|
||||
|
||||
let expectation = self.expectationWithDescription(description)
|
||||
|
||||
promise.then { v in
|
||||
switch v {
|
||||
case .Error:
|
||||
XCTFail("Promise failed for promise \(promise) for value \(v)", file:file, line:line)
|
||||
case let .Some(newV):
|
||||
if !predicate(newV) {
|
||||
XCTFail("Predicate failed for promise \(promise) for value \(v)", file:file, line:line)
|
||||
}
|
||||
|
||||
}
|
||||
expectation.fulfill()
|
||||
}
|
||||
|
||||
if wait {
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
return expectation
|
||||
}
|
||||
|
||||
// Terminates a promise and returns an XCTestExpectation for it
|
||||
func expectationWithFailingPromise<T>(promise: Promise<T>, wait: Bool = true, file: String = __FILE__, line: UInt = __LINE__, predicate: (ErrorType) -> Bool = { _ in true}) -> XCTestExpectation {
|
||||
|
||||
let description = "Waiting for promise \(promise) to fulfill"
|
||||
|
||||
|
||||
let expectation = self.expectationWithDescription(description)
|
||||
|
||||
promise.then { v in
|
||||
switch v {
|
||||
case let .Error(e):
|
||||
if !predicate(e) {
|
||||
XCTFail("Predicate failed for promise \(promise) for value \(v)", file:file, line:line)
|
||||
}
|
||||
case .Some:
|
||||
XCTFail("Expected error for promise, but got value promise \(promise) for value \(v)", file:file, line:line)
|
||||
|
||||
}
|
||||
expectation.fulfill()
|
||||
}
|
||||
|
||||
if wait {
|
||||
self.waitForExpectations()
|
||||
}
|
||||
|
||||
return expectation
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
258
SocketRocketIOTests/QueueStreamable.swift
Normal file
258
SocketRocketIOTests/QueueStreamable.swift
Normal file
@ -0,0 +1,258 @@
|
||||
//
|
||||
// QueueStreamable.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/5/15.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
public protocol AsyncBaseStream {
|
||||
/// The type we operate on
|
||||
typealias Collection: CollectionType
|
||||
}
|
||||
|
||||
public protocol AsyncReadable : AsyncBaseStream {
|
||||
|
||||
/// reads data until eof or size is reached. handler is invoked on the queue in order (and non-reentrant)
|
||||
///
|
||||
/// The return value of this indicates when the operation is done or if it failed
|
||||
mutating func read(size: Collection.Index.Distance, queue: Queue, handler: (AnyRandomAccessCollection<Collection.Generator.Element>) throws -> ()) -> VoidPromiseType
|
||||
}
|
||||
|
||||
public protocol AsyncWritable : AsyncBaseStream {
|
||||
/// Writes data to the stream
|
||||
///
|
||||
/// THe return value of this indicates when the operation is done or if it failed
|
||||
mutating func write<C: CollectionType where C.Generator.Element == Collection.Generator.Element>(data: C) -> VoidPromiseType
|
||||
|
||||
/// Closes the stream
|
||||
mutating func close() -> VoidPromiseType
|
||||
|
||||
}
|
||||
|
||||
public extension AsyncReadable where Collection: RangeReplaceableCollectionType, Collection.Index.Distance == Int {
|
||||
/// Buffers everything into one result
|
||||
mutating func readAll(size: Collection.Index.Distance = Collection.Index.Distance.max , queue: Queue) -> Promise<Collection> {
|
||||
var buffer = Collection()
|
||||
|
||||
let vp = read(size, queue: queue) { (v) -> () in
|
||||
buffer.extend(v)
|
||||
}
|
||||
|
||||
let (r, p) = Promise<Collection>.resolver()
|
||||
|
||||
vp.then { (voidP: ErrorOptional<Void>) -> () in
|
||||
r.attemptResolve {
|
||||
try voidP.checkedGet()
|
||||
return buffer
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Wraps an io since it is a protocol
|
||||
struct DispatchIO {
|
||||
let io: dispatch_io_t
|
||||
}
|
||||
|
||||
|
||||
enum ValueOrEnd<V> {
|
||||
/// :param consumed: the size of the input stream consumed
|
||||
/// :param value: result value for the coded
|
||||
case Value(V)
|
||||
|
||||
/// If we're out of data
|
||||
case End
|
||||
}
|
||||
|
||||
protocol Codec {
|
||||
typealias InType: CollectionType
|
||||
typealias OutType: CollectionType
|
||||
|
||||
// TODO(lewis): Maybe make this take chunks more for input
|
||||
mutating func code(input: ValueOrEnd<AnyRandomAccessCollection<InType.Generator.Element>>) throws -> OutType
|
||||
}
|
||||
|
||||
extension Codec where InType.Index : RandomAccessIndexType, InType: CollectionType {
|
||||
mutating func code(input: ValueOrEnd<InType>) throws -> OutType {
|
||||
switch input {
|
||||
case let .Value(v):
|
||||
let cc = AnyRandomAccessCollection<InType.Generator.Element>(v)
|
||||
return try self.code(ValueOrEnd<AnyRandomAccessCollection<InType.Generator.Element>>.Value(cc))
|
||||
case .End:
|
||||
return try self.code(ValueOrEnd<AnyRandomAccessCollection<InType.Generator.Element>>.End)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
struct EncodedReadable<C: Codec,
|
||||
R: AsyncReadable
|
||||
where R.Collection == C.InType,
|
||||
C.InType.Index.Distance == C.OutType.Index.Distance,
|
||||
C.OutType.Index: RandomAccessIndexType
|
||||
>: AsyncReadable {
|
||||
typealias Collection = C.OutType
|
||||
|
||||
private var input: R
|
||||
private var codec: C
|
||||
|
||||
mutating func read(size: Collection.Index.Distance, queue: Queue, handler: (AnyRandomAccessCollection<Collection.Generator.Element>) throws -> ()) -> VoidPromiseType {
|
||||
return input.read(size, queue: queue) { (e) -> () in
|
||||
let coded = try self.codec.code(ValueOrEnd.Value(e))
|
||||
try handler(AnyRandomAccessCollection(coded))
|
||||
}.thenChecked { (vo: ErrorOptional<Void>) -> Void in
|
||||
try handler(AnyRandomAccessCollection(self.codec.code(.End)))
|
||||
try vo.checkedGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// For testing
|
||||
/// Probably not super efficient
|
||||
public class Loopback<T: RangeReplaceableCollectionType
|
||||
where
|
||||
T.Index: RandomAccessIndexType,
|
||||
T.Index.Distance == Int,
|
||||
T.SubSequence.Generator.Element == T.Generator.Element,
|
||||
T.SubSequence.Index : RandomAccessIndexType,
|
||||
T.SubSequence: CollectionType
|
||||
> : AsyncReadable, AsyncWritable {
|
||||
public typealias Collection = T
|
||||
public typealias ResultPromise = VoidPromiseType
|
||||
public typealias Handler = (AnyRandomAccessCollection<T.Generator.Element>) throws -> ()
|
||||
|
||||
public typealias Distance = Collection.Index.Distance
|
||||
|
||||
let queue: Queue
|
||||
|
||||
var closed = false
|
||||
|
||||
var buffer = Collection()
|
||||
|
||||
var neededPromsises = [(size: Distance, resolver: Resolver<Void>, handler: Handler)]()
|
||||
|
||||
public init(queue: Queue) {
|
||||
self.queue = queue
|
||||
}
|
||||
|
||||
public func read(size: Collection.Index.Distance, queue: Queue, handler: (AnyRandomAccessCollection<Collection.Generator.Element>) throws -> ()) -> VoidPromiseType {
|
||||
let (r, p) = VoidPromiseType.resolver()
|
||||
|
||||
queue.dispatchAsync {
|
||||
self.neededPromsises.append((size: size, resolver: r, handler: handler))
|
||||
self.produce()
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
public func write<C: CollectionType where C.Generator.Element == Collection.Generator.Element>(data: C) -> VoidPromiseType {
|
||||
let (r, p) = VoidPromiseType.resolver()
|
||||
|
||||
let data = Collection() + data
|
||||
queue.dispatchAsync {
|
||||
precondition(!self.closed)
|
||||
self.buffer.extend(data)
|
||||
r.resolve()
|
||||
self.queue.dispatchAsync {
|
||||
self.produce()
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func produce() {
|
||||
do {
|
||||
while neededPromsises.count > 0 && buffer.count > 0 {
|
||||
let (size, resolver, handler) = neededPromsises[0]
|
||||
|
||||
let numBytes = min(size, buffer.count)
|
||||
|
||||
let newSize = size - numBytes
|
||||
|
||||
let usedRange = buffer.startIndex..<buffer.startIndex.advancedBy(numBytes)
|
||||
let slice = buffer[usedRange]
|
||||
let newC = AnyRandomAccessCollection<T.SubSequence.Generator.Element>(slice)
|
||||
precondition(slice.count > 0)
|
||||
precondition(newC.count > 0)
|
||||
try handler(newC)
|
||||
|
||||
buffer.replaceRange(usedRange, with: Collection())
|
||||
|
||||
if newSize == 0 {
|
||||
resolver.resolve()
|
||||
neededPromsises.removeAtIndex(0)
|
||||
} else {
|
||||
neededPromsises[0] = (newSize, resolver, handler)
|
||||
}
|
||||
}
|
||||
|
||||
if closed && buffer.isEmpty {
|
||||
for p in self.neededPromsises {
|
||||
p.resolver.resolve()
|
||||
}
|
||||
self.neededPromsises.removeAll()
|
||||
}
|
||||
} catch let e {
|
||||
for p in self.neededPromsises {
|
||||
p.resolver.reject(e)
|
||||
}
|
||||
self.neededPromsises.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
public func close() -> ResultPromise {
|
||||
let (r, p) = VoidPromiseType.resolver()
|
||||
|
||||
queue.dispatchAsync {
|
||||
self.closed = true
|
||||
self.produce()
|
||||
r.resolve()
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
extension Queue {
|
||||
static let defaultCleanupQueue = Queue.defaultGlobalQueue
|
||||
}
|
||||
|
||||
/// Chains two generators together
|
||||
struct ChainedGenerator<L: GeneratorType, R: GeneratorType, T where L.Element == R.Element, T == L.Element>: GeneratorType, SequenceType {
|
||||
typealias Element = T
|
||||
|
||||
typealias Generator = ChainedGenerator<L, R, T>
|
||||
|
||||
var l: L
|
||||
var r: R
|
||||
|
||||
var onfirst = true
|
||||
|
||||
init(lhs: L, rhs: R) {
|
||||
l = lhs
|
||||
r = rhs
|
||||
}
|
||||
|
||||
mutating func next() -> Element? {
|
||||
if onfirst {
|
||||
if let v = l.next() {
|
||||
return v
|
||||
} else {
|
||||
onfirst = false
|
||||
}
|
||||
}
|
||||
|
||||
return r.next()
|
||||
}
|
||||
}
|
||||
|
||||
func + <L: GeneratorType, R: GeneratorType, T where L.Element == R.Element, T == L.Element >(lhs: L, rhs: R) -> ChainedGenerator<L, R, T> {
|
||||
return ChainedGenerator(lhs: lhs, rhs: rhs)
|
||||
}
|
||||
99
SocketRocketIOTests/QueueStreamableTests.swift
Normal file
99
SocketRocketIOTests/QueueStreamableTests.swift
Normal file
@ -0,0 +1,99 @@
|
||||
//
|
||||
// QueueStreamableTests.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/6/15.
|
||||
//
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SocketRocketIO
|
||||
|
||||
class QueueStreamableTests: XCTestCase {
|
||||
static let filePath = NSBundle(forClass: QueueStreamableTests.self).pathForResource("FileToReadFrom", ofType: "txt", inDirectory: "Fixtures")!
|
||||
|
||||
func testManualAccumulating() {
|
||||
let io = dispatch_io_create_with_path(DISPATCH_IO_STREAM, QueueStreamableTests.filePath, O_RDONLY, 0, Queue.mainQueue.queue) { _ in }
|
||||
|
||||
let streamer = DispatchIO(io: io)
|
||||
|
||||
var accumulated = [UInt8]()
|
||||
|
||||
let readQueue = Queue(label: "Read queue")
|
||||
|
||||
let p = streamer.read(Int.max, queue: readQueue) { data in
|
||||
accumulated += data
|
||||
}
|
||||
|
||||
expectationWithPromise(p)
|
||||
|
||||
dispatch_io_close(io, 0)
|
||||
|
||||
let readData = String(bytes:accumulated, encoding: NSUTF8StringEncoding)
|
||||
|
||||
XCTAssertEqual(readData!, "hello\nthis\nis a file\n\nI like to read from it")
|
||||
}
|
||||
|
||||
|
||||
func testErrorHandling() {
|
||||
let io = dispatch_io_create_with_path(DISPATCH_IO_STREAM, QueueStreamableTests.filePath, O_RDONLY, 0, Queue.mainQueue.queue) { _ in }
|
||||
|
||||
let streamer = DispatchIO(io: io)
|
||||
|
||||
let readQueue = Queue(label: "Read queue")
|
||||
|
||||
dispatch_suspend(readQueue.queue)
|
||||
|
||||
let f = streamer.read(Int.max, queue: readQueue) { v in
|
||||
|
||||
}
|
||||
|
||||
dispatch_io_close(streamer.io, DISPATCH_IO_STOP)
|
||||
|
||||
dispatch_resume(readQueue.queue)
|
||||
|
||||
expectationWithFailingPromise(f)
|
||||
}
|
||||
|
||||
func testLoopback() {
|
||||
let q = Queue(label: "loopbackQueue")
|
||||
|
||||
var l = Loopback<[UInt8]>(queue: q)
|
||||
|
||||
let p = l.readAll(queue: q).thenChecked { v in
|
||||
let v = try v.checkedGet()
|
||||
XCTAssertEqual(v, [UInt8]("OMG PONIESI LIKE TO EAT PONIES".utf8))
|
||||
}
|
||||
|
||||
l.write([UInt8]("OMG PONIES".utf8))
|
||||
l.write([UInt8]("I LIKE TO EAT PONIES".utf8))
|
||||
|
||||
expectationWithPromise(l.close(), wait: false)
|
||||
|
||||
expectationWithPromise(p)
|
||||
}
|
||||
}
|
||||
|
||||
extension POSIXError: CustomDebugStringConvertible {
|
||||
public var debugDescription: String {
|
||||
get {
|
||||
var buffer = [CChar](count: 1024, repeatedValue: 0)
|
||||
|
||||
guard strerror_r(rawValue, &buffer, buffer.count) == 0 else {
|
||||
return "Unknown!!"
|
||||
}
|
||||
|
||||
return "Posix Error \(rawValue) " + (String.fromCString(&buffer) ?? "Issue converting to cstring")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func XCTAssertEqualT<T : Equatable>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () -> T, _ message: String = "", file: String = __FILE__, line: UInt = __LINE__)
|
||||
{
|
||||
do {
|
||||
let v = try expression1()
|
||||
XCTAssertEqual(v, expression2(), line: line, file:file)
|
||||
} catch let e {
|
||||
XCTFail("\(e)", line: line, file:file)
|
||||
}
|
||||
}
|
||||
61
SocketRocketIOTests/QueueTests.swift
Normal file
61
SocketRocketIOTests/QueueTests.swift
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// QueueTests.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 7/30/15.
|
||||
//
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import SocketRocketIO
|
||||
|
||||
class QueueTests: XCTestCase {
|
||||
func testMainQueue() {
|
||||
let queue = Queue.mainQueue
|
||||
|
||||
let expectation = expectationWithDescription("Should dispatch")
|
||||
queue.dispatchAsync {
|
||||
expectation.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations()
|
||||
}
|
||||
|
||||
func testMainQueueRecognizesSelf() {
|
||||
|
||||
let expectation = expectationWithDescription("Should dispatch")
|
||||
let queue = Queue.mainQueue
|
||||
|
||||
queue.dispatchAsync {
|
||||
XCTAssertTrue(Queue.mainQueue.isCurrentQueue())
|
||||
expectation.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations()
|
||||
}
|
||||
|
||||
|
||||
func testCheckIsCurrentQueue() {
|
||||
let expectation = expectationWithDescription("Should dispatch")
|
||||
let queue = Queue(label: "queueLabel")
|
||||
|
||||
queue.dispatchAsync {
|
||||
XCTAssertTrue(queue.isCurrentQueue())
|
||||
queue.checkIsCurrentQueue()
|
||||
expectation.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations()
|
||||
|
||||
|
||||
XCTAssertFalse(queue.isCurrentQueue())
|
||||
}
|
||||
}
|
||||
|
||||
let defaultTimeout: NSTimeInterval = 10
|
||||
|
||||
extension XCTestCase {
|
||||
func waitForExpectations() -> Void {
|
||||
waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
|
||||
}
|
||||
}
|
||||
35
SocketRocketIOTests/SocketRocketIOTests.swift
Normal file
35
SocketRocketIOTests/SocketRocketIOTests.swift
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// SocketRocketIOTests.swift
|
||||
// SocketRocketIOTests
|
||||
//
|
||||
// Created by Mike Lewis on 7/30/15.
|
||||
//
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SocketRocketIO
|
||||
|
||||
class SocketRocketIOTests: XCTestCase {
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testExample() {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
}
|
||||
|
||||
func testPerformanceExample() {
|
||||
// This is an example of a performance test case.
|
||||
self.measureBlock {
|
||||
// Put the code you want to measure the time of here.
|
||||
}
|
||||
}
|
||||
}
|
||||
183
SocketRocketIOTests/UnicodeTests.swift
Normal file
183
SocketRocketIOTests/UnicodeTests.swift
Normal file
@ -0,0 +1,183 @@
|
||||
//
|
||||
// UnicodeTests.swift
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 8/6/15.
|
||||
//
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SocketRocketIO
|
||||
|
||||
struct SourceInfo {
|
||||
let line: UInt
|
||||
let file: String
|
||||
|
||||
init(line: UInt = __LINE__, file: String = __FILE__) {
|
||||
self.line = line
|
||||
self.file = file
|
||||
}
|
||||
}
|
||||
|
||||
typealias SI = SourceInfo
|
||||
|
||||
class UnicodeTests: XCTestCase {
|
||||
func testCodeUnits() {
|
||||
let s = "💩1💩"
|
||||
|
||||
|
||||
var data = [UInt8]()
|
||||
|
||||
for s in s.unicodeScalars {
|
||||
UTF8.encode(s) { (cu) -> () in
|
||||
data.append(cu)
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertEqualT(try UTF8.numValidCodeUnits(data.generate()), 9)
|
||||
XCTAssertEqualT(try UTF8.numValidCodeUnits(data[0..<8].generate()), 5)
|
||||
XCTAssertEqualT(try UTF8.numValidCodeUnits(data[0..<5].generate()), 5)
|
||||
XCTAssertEqualT(try UTF8.numValidCodeUnits(data[0..<4].generate()), 4)
|
||||
XCTAssertEqualT(try UTF8.numValidCodeUnits(data[0..<3].generate()), 0)
|
||||
}
|
||||
|
||||
|
||||
func testDecoding() {
|
||||
var uc = UTF8()
|
||||
|
||||
let s = "💩1💩"
|
||||
|
||||
var data = [UInt8]()
|
||||
|
||||
for s in s.unicodeScalars {
|
||||
UTF8.encode(s) { (cu) -> () in
|
||||
data.append(cu)
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertEqual(data.count, 9)
|
||||
|
||||
var c = RawUTF8Codec<ArraySlice<UInt8>, ArraySlice<UInt8>.Generator>()
|
||||
|
||||
var buff = String()
|
||||
|
||||
func accumulate(slice: ArraySlice<UInt8>, line: UInt = __LINE__, file: String = __FILE__) {
|
||||
do {
|
||||
buff.unicodeScalars.extend(try c.code(ValueOrEnd.Value(slice)))
|
||||
} catch let e {
|
||||
XCTFail("\(e)", line:line, file:file)
|
||||
}
|
||||
}
|
||||
|
||||
accumulate(data[0..<2])
|
||||
accumulate(data[2..<3])
|
||||
accumulate(data[3..<8])
|
||||
accumulate(data[8..<9])
|
||||
|
||||
do {
|
||||
let r = try c.code(.End)
|
||||
XCTAssertEqual("", String(r))
|
||||
} catch let e {
|
||||
XCTFail("\(e)")
|
||||
}
|
||||
|
||||
XCTAssertEqual(buff, s)
|
||||
}
|
||||
|
||||
|
||||
func testDecoding_errorHandling() {
|
||||
var uc = UTF8()
|
||||
|
||||
let s = "💩1💩"
|
||||
|
||||
var data = [UInt8]()
|
||||
|
||||
for s in s.unicodeScalars {
|
||||
UTF8.encode(s) { (cu) -> () in
|
||||
data.append(cu)
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertEqual(data.count, 9)
|
||||
|
||||
var c = RawUTF8Codec<ArraySlice<UInt8>, ArraySlice<UInt8>.Generator>()
|
||||
|
||||
var buff = String()
|
||||
|
||||
func accumulate(slice: ArraySlice<UInt8>, line: UInt = __LINE__, file: String = __FILE__) {
|
||||
do {
|
||||
let v = try c.code(ValueOrEnd.Value(slice))
|
||||
buff.unicodeScalars.extend(v)
|
||||
} catch let e {
|
||||
XCTFail("\(e)", line:line, file:file)
|
||||
}
|
||||
}
|
||||
|
||||
accumulate(data[0..<2])
|
||||
accumulate(data[2..<3])
|
||||
accumulate(data[3..<8])
|
||||
|
||||
do {
|
||||
try c.code(.End)
|
||||
XCTFail("Should except")
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
func testDecoding_Smoke() {
|
||||
let filePath = NSBundle(forClass: QueueStreamableTests.self).pathForResource("UTF8Sample", ofType: "txt", inDirectory: "Fixtures")!
|
||||
let s = NSData(contentsOfFile: filePath)!
|
||||
|
||||
let nominalString = NSString(data: s, encoding: NSUTF8StringEncoding) as! String
|
||||
|
||||
doTestAccumulateSplit(nominalString, splitPoints: [Int](0..<(s.length - 1)))
|
||||
|
||||
doTestAccumulateSplit(nominalString, splitPoints: [])
|
||||
doTestAccumulateSplit(nominalString, splitPoints: [Int](0..<((s.length - 1) / 2)).map({e in return e / 2}))
|
||||
}
|
||||
|
||||
func doTestAccumulateSplit(data: [UInt8], var splitPoints: [Int], si: SI = SI()) -> String {
|
||||
var c = RawUTF8Codec<ArraySlice<UInt8>, ArraySlice<UInt8>.Generator>()
|
||||
|
||||
var buff = String()
|
||||
|
||||
func accumulate(slice: ArraySlice<UInt8>, si: SI) {
|
||||
do {
|
||||
let v = try c.code(ValueOrEnd.Value(slice))
|
||||
buff.unicodeScalars.extend(v)
|
||||
} catch let e {
|
||||
XCTFail("\(e)")
|
||||
XCTFail("\(e) (from here)", line:si.line, file:si.file)
|
||||
}
|
||||
}
|
||||
|
||||
splitPoints.sortInPlace()
|
||||
|
||||
var lastIdx = data.startIndex
|
||||
|
||||
for sp in splitPoints {
|
||||
let newIdx = data.startIndex.advancedBy(sp)
|
||||
accumulate(data[lastIdx..<newIdx], si: si)
|
||||
lastIdx = newIdx
|
||||
}
|
||||
accumulate(data[lastIdx..<data.endIndex], si: si)
|
||||
|
||||
do {
|
||||
try c.code(.End)
|
||||
} catch let e {
|
||||
XCTFail("Should not except \(e)")
|
||||
}
|
||||
return buff
|
||||
}
|
||||
|
||||
func doTestAccumulateSplit(string: String, splitPoints: [Int], si: SI = SI()) {
|
||||
var data = [UInt8]()
|
||||
for s in string.unicodeScalars {
|
||||
UTF8.encode(s) { (cu) -> () in
|
||||
data.append(cu)
|
||||
}
|
||||
}
|
||||
let r = doTestAccumulateSplit(data, splitPoints: splitPoints, si: si)
|
||||
XCTAssertEqual(string, r, line:si.line, file:si.file)
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.squareup.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
26
SystemShims/Info.plist
Normal file
26
SystemShims/Info.plist
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
23
SystemShims/SystemShims.h
Normal file
23
SystemShims/SystemShims.h
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// SystemShims.h
|
||||
// SystemShims
|
||||
//
|
||||
// Created by Mike Lewis on 7/31/15.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! Project version number for SystemShims.
|
||||
FOUNDATION_EXPORT double SystemShimsVersionNumber;
|
||||
|
||||
//! Project version string for SystemShims.
|
||||
FOUNDATION_EXPORT const unsigned char SystemShimsVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <SystemShims/PublicHeader.h>
|
||||
|
||||
|
||||
extern int shim_fcntl(int fildes, int cmd, int flags);
|
||||
extern int shim_bind(int fildes, const void *addr, size_t size);
|
||||
extern int shim_accept(int fildes, void *addr, socklen_t *size);
|
||||
24
SystemShims/SystemShims.m
Normal file
24
SystemShims/SystemShims.m
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// SystemShims.c
|
||||
// SocketRocket
|
||||
//
|
||||
// Created by Mike Lewis on 7/31/15.
|
||||
//
|
||||
//
|
||||
|
||||
#import "SystemShims.h"
|
||||
|
||||
#import <sys/fcntl.h>
|
||||
#import <sys/socket.h>
|
||||
|
||||
extern int shim_fcntl(int fildes, int cmd, int flags) {
|
||||
return fcntl(fildes, cmd, flags);
|
||||
}
|
||||
|
||||
extern int shim_bind(int fildes, const void *addr, size_t size) {
|
||||
return bind(fildes, addr, (socklen_t)size);
|
||||
}
|
||||
|
||||
extern int shim_accept(int fildes, void *addr, socklen_t *size) {
|
||||
return accept(fildes, addr, size);
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
//
|
||||
// TCAppDelegate.m
|
||||
// TestChat
|
||||
//
|
||||
// Created by Mike Lewis on 1/28/12.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TCAppDelegate.h"
|
||||
|
||||
|
||||
@implementation TCAppDelegate
|
||||
|
||||
@synthesize window = _window;
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
// Override point for customization after application launch.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Called when the application is about to terminate.
|
||||
Save data if appropriate.
|
||||
See also applicationDidEnterBackground:.
|
||||
*/
|
||||
}
|
||||
|
||||
@end
|
||||
130
TestChat/TCAppDelegate.mm
Normal file
130
TestChat/TCAppDelegate.mm
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// TCAppDelegate.m
|
||||
// TestChat
|
||||
//
|
||||
// Created by Mike Lewis on 1/28/12.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TCAppDelegate.h"
|
||||
#import <Security/SecureTransport.h>
|
||||
|
||||
#import "SecureIO.h"
|
||||
#import <string>
|
||||
|
||||
using namespace squareup::dispatch;
|
||||
|
||||
@implementation TCAppDelegate {
|
||||
SecureIO *_io;
|
||||
}
|
||||
|
||||
@synthesize window = _window;
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
// Override point for customization after application launch.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
SSLContextRef ctx = SSLCreateContext(CFAllocatorGetDefault(), kSSLClientSide, kSSLStreamType);
|
||||
|
||||
auto finishBlock = [self](int error) {
|
||||
NSLog(@"Done");
|
||||
};
|
||||
|
||||
dispatch_queue_t workQueue = dispatch_queue_create("squareup.dispatch work queue", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
DialTLS("localhost", "10248", ctx, dispatch_get_main_queue(), workQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [self, _cmd](squareup::dispatch::SecureIO *io, int error, const char *error_message) {
|
||||
|
||||
NSAssert(error == 0, @"Should not have errored, but got %s", error_message);
|
||||
NSAssert(io != nullptr, @"io should be valid");
|
||||
|
||||
if (!io) {
|
||||
return;
|
||||
}
|
||||
|
||||
_io = io;
|
||||
|
||||
__block bool seenInner = false;
|
||||
__block bool seenOuter = false;
|
||||
|
||||
// _io->Write(Data("HELLO THERE!\n", dispatch_get_main_queue()), ^(bool done, dispatch_data_t data, int error) {
|
||||
// STAssertEquals(error, 0, @"Error should == 0");
|
||||
// STAssertFalse(seenOuter, @"Should only see the outer once");
|
||||
// if (done) {
|
||||
// seenOuter = true;
|
||||
// }
|
||||
// if (done && !error) {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// _io->Write(Data("HELLO THERE2!\n", dispatch_get_main_queue()), ^(bool done, dispatch_data_t data, int error) {
|
||||
// STAssertFalse(seenInner, @"Shouldn't have seen inner yet");
|
||||
// if (done) {
|
||||
// seenInner = done;
|
||||
// }
|
||||
// STAssertEquals(error, 0, @"Error should == 0");
|
||||
// STAssertFalse(finished, @"Shouldn't have finished");
|
||||
// });
|
||||
|
||||
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
|
||||
_io->Read(1024 * 1024* 13, dispatch_get_main_queue(), [self, _cmd, i](bool readDone, dispatch_data_t data, int error) {
|
||||
if (!error) {
|
||||
|
||||
_io->Write(data, dispatch_get_main_queue(), [self, readDone, i](bool done, dispatch_data_t data, int error) {
|
||||
});
|
||||
} else {
|
||||
NSAssert(error == ECANCELED, @"Server should terminate");
|
||||
|
||||
if (readDone && !error) {
|
||||
_io->Close(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, finishBlock);
|
||||
|
||||
/*
|
||||
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
/*
|
||||
Called when the application is about to terminate.
|
||||
Save data if appropriate.
|
||||
See also applicationDidEnterBackground:.
|
||||
*/
|
||||
}
|
||||
|
||||
@end
|
||||
@ -11,7 +11,7 @@
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array/>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.squareup.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
96
TestHarness/test_harness.go
Normal file
96
TestHarness/test_harness.go
Normal file
@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
func main() {
|
||||
keyPair, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cfg := &tls.Config{
|
||||
Certificates: []tls.Certificate{keyPair},
|
||||
}
|
||||
|
||||
listener, err := tls.Listen("tcp", ":10248", cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for conn, err := listener.Accept(); err == nil; conn, err = listener.Accept() {
|
||||
go func(conn net.Conn) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Println("Something failed:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
ch := make(chan bool, 1)
|
||||
maxPending := make(chan bool, 2)
|
||||
|
||||
chunkSize := int64(1024 * 1024)
|
||||
buff2 := bytes.NewBuffer(make([]byte, 0, chunkSize))
|
||||
|
||||
randBytes := make([]byte, chunkSize)
|
||||
_, err := rand.Read(randBytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
randReader := bytes.NewReader(randBytes)
|
||||
|
||||
ch <- true
|
||||
go func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Println("Something failed:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
<-ch
|
||||
}()
|
||||
|
||||
for i := 0; ; i++ {
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Println("Something failed:", err)
|
||||
}
|
||||
}()
|
||||
_, err := io.CopyN(ioutil.Discard, conn, chunkSize)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
<-maxPending
|
||||
|
||||
log.Println("Chunk read back (", i, ")")
|
||||
}
|
||||
|
||||
buff2.Reset()
|
||||
}()
|
||||
|
||||
for {
|
||||
maxPending <- true
|
||||
randReader.Seek(0, 0)
|
||||
_, err := io.CopyN(conn, randReader, chunkSize)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
ch <- true
|
||||
conn.Close()
|
||||
}(conn)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user