diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index 3b93fe8..435b094 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -26,7 +26,7 @@ import Foundation extension String { private var length:Int { - return countElements(self) + return count(self) } } @@ -69,7 +69,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { var connected:Bool { return self._connected } - + weak var client:SocketEngineClient? var cookies:[NSHTTPCookie]? var pingInterval:Int? @@ -83,7 +83,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { return self._websocket } var ws:WebSocket? - + public init(client:SocketEngineClient, forcePolling:Bool, forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?) { self.client = client @@ -93,19 +93,19 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(), delegate: nil, delegateQueue: self.workQueue) } - + public func close(#fast:Bool) { self.pingTimer?.invalidate() self.closed = true - + self.write("", withType: PacketType.CLOSE, withData: nil) self.ws?.disconnect() - + if fast || self.polling { self.client?.didForceClose("Disconnect") } } - + private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) { if self.websocket { var byteArray = [UInt8](count: 1, repeatedValue: 0x0) @@ -117,20 +117,20 @@ public class SocketEngine: NSObject, WebSocketDelegate { var str = "b4" str += data.base64EncodedStringWithOptions( NSDataBase64EncodingOptions.Encoding64CharacterLineLength) - + return (nil, str) } } - + private func createURLs(params:[String: AnyObject]?) -> (String, String) { if self.client == nil { return ("", "") } - + var url = "\(self.client!.socketURL)/socket.io/?transport=" var urlPolling:String var urlWebSocket:String - + if self.client!.secure { urlPolling = "https://" + url + "polling" urlWebSocket = "wss://" + url + "websocket" @@ -138,16 +138,16 @@ public class SocketEngine: NSObject, WebSocketDelegate { urlPolling = "http://" + url + "polling" urlWebSocket = "ws://" + url + "websocket" } - + if params != nil { for (key, value) in params! { let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLHostAllowedCharacterSet())! urlPolling += "&\(keyEsc)=" urlWebSocket += "&\(keyEsc)=" - + if value is String { - let valueEsc = (value as String).stringByAddingPercentEncodingWithAllowedCharacters( + let valueEsc = (value as! String).stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLHostAllowedCharacterSet())! urlPolling += "\(valueEsc)" urlWebSocket += "\(valueEsc)" @@ -157,26 +157,26 @@ public class SocketEngine: NSObject, WebSocketDelegate { } } } - + return (urlPolling, urlWebSocket) } - + private func createWebsocket(andConnect connect:Bool) { self.ws = WebSocket(url: NSURL(string: self.urlWebSocket! + "&sid=\(self.sid)")!) self.ws?.queue = self.handleQueue self.ws?.delegate = self - + if connect { self.ws?.connect() } } - + private func doFastUpgrade() { if self.waitingForPoll { NSLog("Outstanding poll when switched to websockets," + "we'll probably disconnect soon. You should report this.") } - + self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil) self._websocket = true self._polling = false @@ -184,25 +184,25 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.probing = false self.flushProbeWait() } - + private func doPoll() { if self.websocket || self.waitingForPoll || !self.connected { return } - + self.waitingForPoll = true let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)&b64=1")!) - + self.doRequest(req) } - + private func doRequest(req:NSMutableURLRequest) { if !self.polling { return } - + req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData - + // NSLog("Doing request: \(req)") self.session.dataTaskWithRequest(req) {[weak self] data, res, err in if self == nil { @@ -213,20 +213,21 @@ public class SocketEngine: NSObject, WebSocketDelegate { } else { NSLog(err.localizedDescription) } - + return } - + // NSLog("Got response: \(res)") - + if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String { dispatch_async(self!.parseQueue) { self?.parsePollingMessage(str) return } } - + self?.waitingForPoll = false + if self!.fastUpgrade { self?.doFastUpgrade() return @@ -235,26 +236,26 @@ public class SocketEngine: NSObject, WebSocketDelegate { } }.resume() } - + private func flushProbeWait() { // NSLog("flushing probe wait") dispatch_async(self.emitQueue) {[weak self] in if self == nil { return } - + for waiter in self!.probeWait { self?.write(waiter.msg, withType: waiter.type, withData: waiter.data) } - + self?.probeWait.removeAll(keepCapacity: false) - + if self?.postWait.count != 0 { self?.flushWaitingForPostToWebSocket() } } } - + private func flushWaitingForPost() { if self.postWait.count == 0 || !self.connected { return @@ -262,33 +263,33 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.flushWaitingForPostToWebSocket() return } - + var postStr = "" - + for packet in self.postWait { - let len = countElements(packet) - + let len = count(packet) + postStr += "\(len):\(packet)" } - + self.postWait.removeAll(keepCapacity: false) - + let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)")!) - + req.HTTPMethod = "POST" req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type") - + let postData = postStr.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! - + req.HTTPBody = postData req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length") - + self.waitingForPost = true - + // NSLog("posting: \(postStr)") // NSLog("Posting with WS status of: \(self.websocket)") - + self.session.dataTaskWithRequest(req) {[weak self] data, res, err in if self == nil { return @@ -299,7 +300,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { NSLog(err.localizedDescription) return } - + self?.waitingForPost = false dispatch_async(self!.emitQueue) { if !self!.fastUpgrade { @@ -308,89 +309,90 @@ public class SocketEngine: NSObject, WebSocketDelegate { } }}.resume() } - + // We had packets waiting for send when we upgraded // Send them raw private func flushWaitingForPostToWebSocket() { for msg in self.postWait { self.ws?.writeString(msg) } - + self.postWait.removeAll(keepCapacity: true) } - + // A poll failed, tell the client about it + private func handlePollingFailed(reason:String) { self._connected = false self.ws?.disconnect() self.pingTimer?.invalidate() self.waitingForPoll = false self.waitingForPost = false - + if self.client == nil { return } - + if !self.closed && !self.client!.reconnecting { self.client?.pollingDidFail(reason) } else if !self.client!.reconnecting { self.client?.didForceClose(reason) } } - + public func open(opts:[String: AnyObject]? = nil) { if self.connected { fatalError("Engine tried to open while connected") } - + self.closed = false let (urlPolling, urlWebSocket) = self.createURLs(opts) self.urlPolling = urlPolling self.urlWebSocket = urlWebSocket - + if self.forceWebsockets { self._polling = false self._websocket = true self.createWebsocket(andConnect: true) return } - + let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&b64=1")!) - + if self.cookies != nil { let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(self.cookies!) reqPolling.allHTTPHeaderFields = headers } - + self.doRequest(reqPolling) } - + // Translatation of engine.io-parser#decodePayload private func parsePollingMessage(str:String) { if str.length == 1 { return } - + // println(str) - + let strArray = Array(str) var length = "" var n = 0 var msg = "" - + func testLength(length:String, inout n:Int) -> Bool { if let num = length.toInt() { n = num } else { return true } - + return false } - + for var i = 0, l = str.length; i < l; i = i &+ 1 { let chr = String(strArray[i]) - + if chr != ":" { length += chr } else { @@ -399,16 +401,16 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.handlePollingFailed("Error parsing XHR message") return } - + msg = String(strArray[i&+1...i&+n]) - + if let lengthInt = length.toInt() { if lengthInt != msg.length { NSLog("parsing error: \(str)") return } } - + if msg.length != 0 { // Be sure to capture the value of the msg dispatch_async(self.handleQueue) {[weak self, msg] in @@ -416,54 +418,54 @@ public class SocketEngine: NSObject, WebSocketDelegate { return } } - + i += n length = "" } } } - + private func parseEngineData(data:NSData) { if self.client == nil { return } - + dispatch_async(self.client!.handleQueue) {[weak self] in self?.client?.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1))) return } } - + private func parseEngineMessage(var message:String, fromPolling:Bool) { // NSLog("Engine got message: \(message)") if fromPolling { fixDoubleUTF8(&message) } - + let type = message["^(\\d)"].groups()?[1] - + if type != PacketType.MESSAGE.rawValue { // TODO Handle other packets if message.hasPrefix("b4") { // binary in base64 string - + message.removeRange(Range(start: message.startIndex, end: advance(message.startIndex, 2))) - + if let data = NSData(base64EncodedString: message, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) { // println("sending \(data)") - + if self.client == nil { return } - + dispatch_async(self.client!.handleQueue) {[weak self] in self?.client?.parseBinaryData(data) return } } - + return } else if type == PacketType.NOOP.rawValue { self.doPoll() @@ -474,14 +476,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.upgradeTransport() return } - + return } else if type == PacketType.OPEN.rawValue { var err:NSError? - + message.removeAtIndex(message.startIndex) let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! - + if let json = NSJSONSerialization.JSONObjectWithData(mesData, options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary { if let sid = json["sid"] as? String { @@ -495,55 +497,55 @@ public class SocketEngine: NSObject, WebSocketDelegate { NSLog("Error handshaking") return } - + if let pingInterval = json["pingInterval"] as? Int { self.pingInterval = pingInterval / 1000 } } else { fatalError("Error parsing engine connect") } - + self.startPingTimer() - + if !self.forceWebsockets { self.doPoll() } - + return } else if type == PacketType.CLOSE.rawValue { if self.client == nil { return } - + if self.polling { self.client!.didForceClose("Disconnect") } - + return } // println("Got something idk what to do with") // println(messageString) } - + // Remove message type message.removeAtIndex(message.startIndex) - + if self.client == nil { return } - + dispatch_async(self.client!.handleQueue) {[weak self] in self?.client?.parseSocketMessage(message) return } } - + private func probeWebSocket() { if self.websocketConnected { self.sendWebSocketMessage("probe", withType: PacketType.PING) } } - + /// Send an engine message (4) public func send(msg:String, withData datas:ContiguousArray?) { if self.probing { @@ -552,11 +554,11 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.write(msg, withType: PacketType.MESSAGE, withData: datas) } } - + func sendPing() { self.write("", withType: PacketType.PING, withData: nil) } - + /// Send polling message. /// Only call on emitQueue private func sendPollMessage(var msg:String, withType type:PacketType, @@ -564,29 +566,29 @@ public class SocketEngine: NSObject, WebSocketDelegate { // println("Sending poll: \(msg) as type: \(type.rawValue)") doubleEncodeUTF8(&msg) let strMsg = "\(type.rawValue)\(msg)" - + self.postWait.append(strMsg) - + if datas != nil { for data in datas! { let (nilData, b64Data) = self.createBinaryDataForSend(data) - + self.postWait.append(b64Data!) } } - + if !self.waitingForPost { self.flushWaitingForPost() } } - + /// Send message on WebSockets /// Only call on emitQueue private func sendWebSocketMessage(str:String, withType type:PacketType, datas:ContiguousArray? = nil) { // println("Sending ws: \(str) as type: \(type.rawValue)") self.ws?.writeString("\(type.rawValue)\(str)") - + if datas != nil { for data in datas! { let (data, nilString) = self.createBinaryDataForSend(data) @@ -596,13 +598,13 @@ public class SocketEngine: NSObject, WebSocketDelegate { } } } - + // Starts the ping timer private func startPingTimer() { if self.pingInterval == nil { return } - + self.pingTimer?.invalidate() dispatch_async(dispatch_get_main_queue()) { self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(self.pingInterval!), @@ -610,7 +612,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { selector: Selector("sendPing"), userInfo: nil, repeats: true) } } - + private func upgradeTransport() { if self.websocketConnected { // NSLog("Doing fast upgrade") @@ -620,13 +622,13 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.sendPollMessage("", withType: PacketType.NOOP) } } - + public func write(msg:String, withType type:PacketType, withData data:ContiguousArray?) { dispatch_async(self.emitQueue) {[weak self] in if self == nil || !self!.connected { return } - + if self!.websocket { // NSLog("writing ws: \(msg):\(data)") self?.sendWebSocketMessage(msg, withType: type, datas: data) @@ -636,12 +638,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { } } } - + // Delagate methods - + public func websocketDidConnect(socket:WebSocket) { self.websocketConnected = true - + if !self.forceWebsockets { self.probing = true self.probeWebSocket() @@ -651,21 +653,21 @@ public class SocketEngine: NSObject, WebSocketDelegate { self._polling = false } } - + public func websocketDidDisconnect(socket:WebSocket, error:NSError?) { self.websocketConnected = false self.probing = false - + if self.closed { self.client?.didForceClose("Disconnect") return } - + if self.websocket { self.pingTimer?.invalidate() self._connected = false self._websocket = false - + let reason = error?.localizedDescription self.client?.webSocketDidCloseWithCode(1, reason: reason == nil ? "Socket Disconnected" : reason!) @@ -673,11 +675,11 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.flushProbeWait() } } - + public func websocketDidReceiveMessage(socket:WebSocket, text:String) { self.parseEngineMessage(text, fromPolling: false) } - + public func websocketDidReceiveData(socket:WebSocket, data:NSData) { self.parseEngineData(data) } diff --git a/SwiftIO/SocketFixUTF8.swift b/SwiftIO/SocketFixUTF8.swift index 032509a..0c36b41 100644 --- a/SwiftIO/SocketFixUTF8.swift +++ b/SwiftIO/SocketFixUTF8.swift @@ -34,4 +34,4 @@ func doubleEncodeUTF8(inout str:String) { let latin1 = str.dataUsingEncoding(NSUTF8StringEncoding)! let utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding)! str = utf8 as String -} \ No newline at end of file +} diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index 455ff29..df1b85b 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -195,7 +195,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { return } - self?.ackHandlers.addAck(ack, callback) + self?.ackHandlers.addAck(ack, callback: callback) dispatch_async(self!.emitQueue) { self?._emit(event, items, ack: ack) @@ -344,7 +344,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { var ackData:[AnyObject]? if data is NSArray { - ackData = data as? NSArray + ackData = (data as? [AnyObject]?)! } else if data != nil { ackData = [data!] } diff --git a/SwiftIO/SocketPacket.swift b/SwiftIO/SocketPacket.swift index 5fc9a51..97581c1 100644 --- a/SwiftIO/SocketPacket.swift +++ b/SwiftIO/SocketPacket.swift @@ -32,7 +32,7 @@ enum SocketPacketType:Int { case ERROR = 4 case BINARY_EVENT = 5 case BINARY_ACK = 6 - + init(str:String) { if let int = str.toInt() { self = SocketPacketType(rawValue: int)! @@ -51,7 +51,7 @@ class SocketPacket { var nsp = "" var placeholders:Int? var type:SocketPacketType? - + init(type:SocketPacketType?, data:[AnyObject]? = nil, nsp:String = "", placeholders:Int? = nil, id:Int? = nil) { self.type = type @@ -60,11 +60,11 @@ class SocketPacket { self.placeholders = placeholders self.id = id } - + func getEvent() -> String { - return data?.removeAtIndex(0) as String + return data?.removeAtIndex(0) as! String } - + func addData(data:NSData) -> Bool { func checkDoEvent() -> Bool { if self.placeholders == self.currentPlace { @@ -73,14 +73,14 @@ class SocketPacket { return false } } - + if checkDoEvent() { return true } - + self.binary.append(data) self.currentPlace++ - + if checkDoEvent() { self.currentPlace = 0 return true @@ -88,14 +88,14 @@ class SocketPacket { return false } } - + func createMessageForEvent(event:String) -> String { var message:String var jsonSendError:NSError? - + if self.binary.count == 0 { self.type = SocketPacketType.EVENT - + if self.nsp == "/" { if self.id == nil { message = "2[\"\(event)\"" @@ -111,7 +111,7 @@ class SocketPacket { } } else { self.type = SocketPacketType.BINARY_EVENT - + if self.nsp == "/" { if self.id == nil { message = "5\(self.binary.count)-[\"\(event)\"" @@ -126,16 +126,16 @@ class SocketPacket { } } } - + return self.completeMessage(message) } - + func createAck() -> String { var msg:String - + if self.binary.count == 0 { self.type = SocketPacketType.ACK - + if nsp == "/" { msg = "3\(self.id!)[" } else { @@ -143,58 +143,57 @@ class SocketPacket { } } else { self.type = SocketPacketType.BINARY_ACK - + if nsp == "/" { msg = "6\(self.binary.count)-\(self.id!)[" } else { msg = "6\(self.binary.count)-/\(self.nsp),\(self.id!)[" } } - + return self.completeMessage(msg, ack: true) } - + func completeMessage(var message:String, ack:Bool = false) -> String { var err:NSError? - + if self.data == nil || self.data!.count == 0 { return message + "]" } else if !ack { message += "," } - + for arg in self.data! { - if arg is NSDictionary || arg is [AnyObject] { let jsonSend = NSJSONSerialization.dataWithJSONObject(arg, options: NSJSONWritingOptions(0), error: &err) let jsonString = NSString(data: jsonSend!, encoding: NSUTF8StringEncoding) - + message += jsonString! as String message += "," continue } - + if arg is String { message += "\"\(arg)\"" message += "," continue } - + message += "\(arg)" message += "," } - + if message != "" { message.removeAtIndex(message.endIndex.predecessor()) } - + return message + "]" } - + func fillInPlaceholders() { var newArr = NSMutableArray(array: self.data!) - + for i in 0.. AnyObject { if let str = data as? String { if let num = str["~~(\\d)"].groups() { @@ -217,19 +216,19 @@ class SocketPacket { } } else if let dict = data as? NSDictionary { var newDict = NSMutableDictionary(dictionary: dict) - + for (key, value) in dict { - newDict[key as NSCopying] = _fillInPlaceholders(value) + newDict[key as! NSCopying] = _fillInPlaceholders(value) } - + return newDict } else if let arr = data as? NSArray { var newArr = NSMutableArray(array: arr) - + for i in 0..() - + func shred(data:AnyObject) -> AnyObject { if let bin = data as? NSData { let placeholder = ["_placeholder" :true, "num": buf.count] - + buf.append(bin) - + return placeholder } else if let arr = data as? NSArray { var newArr = NSMutableArray(array: arr) - + for i in 0.. SocketPacket? { let arr = Array(str) let type = String(arr[0]) - + if arr.count == 1 { return SocketPacket(type: SocketPacketType(str: type)) } - + var id = nil as Int? var nsp = "" var i = 0 var placeholders = -1 - + if type == "5" || type == "6" { var buf = "" - + while arr[++i] != "-" { buf += String(arr[i]) if i == arr.count { break } } - + if buf.toInt() == nil || arr[i] != "-" { NSLog("Error parsing \(str)") return nil @@ -110,26 +110,26 @@ class SocketParser { placeholders = buf.toInt()! } } - + if arr[i + 1] == "/" { while ++i < arr.count { let c = arr[i] - + if c == "," { break } - + nsp += String(c) } } - + if i + 1 >= arr.count { return SocketPacket(type: SocketPacketType(str: type), nsp: nsp, placeholders: placeholders, id: id) } - + let next = String(arr[i + 1]) - + if next.toInt() != nil { var c = "" while ++i < arr.count { @@ -140,48 +140,48 @@ class SocketParser { break } } - + id = c.toInt() } - + if i + 1 < arr.count { let d = String(arr[++i...arr.count-1]) let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" - - let data = SocketParser.parseData(noPlaceholders) as [AnyObject] - + + let data = SocketParser.parseData(noPlaceholders) as! [AnyObject] + return SocketPacket(type: SocketPacketType(str: type), data: data, nsp: nsp, placeholders: placeholders, id: id) } - + return nil } - + // Parses data for events class func parseData(data:String) -> AnyObject? { var err:NSError? let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!, options: NSJSONReadingOptions.AllowFragments, error: &err) - + if err != nil { // println(err) return nil } - + return parsed } - + class func parseForEmit(packet:SocketPacket) { shredder.deconstructPacket(packet) } - + // Parses messages recieved class func parseSocketMessage(stringMessage:String, socket:SocketIOClient) { if stringMessage == "" { return } - + func checkNSP(nsp:String) -> Bool { if nsp == "" && socket.nsp != "/" { return true @@ -189,33 +189,33 @@ class SocketParser { return false } } - + let p = parseString(stringMessage) as SocketPacket! - + if p.type == SocketPacketType.EVENT { if checkNSP(p.nsp) { return } - + socket.handleEvent(p.getEvent(), data: p.data, isInternalMessage: false, wantsAck: p.id) } else if p.type == SocketPacketType.ACK { if checkNSP(p.nsp) { return } - + socket.handleAck(p.id!, data: p.data) } else if p.type == SocketPacketType.BINARY_EVENT { if checkNSP(p.nsp) { return } - + socket.waitingData.append(p) } else if p.type == SocketPacketType.BINARY_ACK { if checkNSP(p.nsp) { return } - + p.justAck = true socket.waitingData.append(p) } else if p.type == SocketPacketType.CONNECT { @@ -230,25 +230,25 @@ class SocketParser { socket.didForceClose("Got Disconnect") } } - + // Handles binary data class func parseBinaryData(data:NSData, socket:SocketIOClient) { // NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros)) - + if socket.waitingData.count == 0 { NSLog("Got data when not remaking packet") return } - + let shouldExecute = socket.waitingData[0].addData(data) - + if !shouldExecute { return } - + let packet = socket.waitingData.removeAtIndex(0) packet.fillInPlaceholders() - + if !packet.justAck { socket.handleEvent(packet.getEvent(), data: packet.data, wantsAck: packet.id) diff --git a/SwiftIO/SwiftRegex.swift b/SwiftIO/SwiftRegex.swift index 49f9524..47095f4 100644 --- a/SwiftIO/SwiftRegex.swift +++ b/SwiftIO/SwiftRegex.swift @@ -18,7 +18,7 @@ var swiftRegexCache = [String: NSRegularExpression]() public class SwiftRegex: NSObject, BooleanType { var target:String var regex: NSRegularExpression - + init(target:String, pattern:String, options:NSRegularExpressionOptions = nil) { self.target = target if let regex = swiftRegexCache[pattern] { @@ -36,16 +36,16 @@ public class SwiftRegex: NSObject, BooleanType { } super.init() } - + class func failure(message: String) { println("SwiftRegex: "+message) //assert(false,"SwiftRegex: failed") } - + final var targetRange: NSRange { - return NSRange(location: 0,length: countElements(target.utf16)) + return NSRange(location: 0,length: count(target.utf16)) } - + final func substring(range: NSRange) -> String? { if ( range.location != NSNotFound ) { return (target as NSString).substringWithRange(range) @@ -53,23 +53,23 @@ public class SwiftRegex: NSObject, BooleanType { return nil } } - + public func doesMatch(options: NSMatchingOptions = nil) -> Bool { return range(options: options).location != NSNotFound } - + public func range(options: NSMatchingOptions = nil) -> NSRange { return regex.rangeOfFirstMatchInString(target as String, options: nil, range: targetRange) } - + public func match(options: NSMatchingOptions = nil) -> String? { return substring(range(options: options)) } - + public func groups(options: NSMatchingOptions = nil) -> [String]? { return groupsForMatch(regex.firstMatchInString(target as String, options: options, range: targetRange)) } - + func groupsForMatch(match: NSTextCheckingResult!) -> [String]? { if match != nil { var groups = [String]() @@ -85,51 +85,51 @@ public class SwiftRegex: NSObject, BooleanType { return nil } } - + public subscript(groupno: Int) -> String? { get { return groups()?[groupno] } - + set(newValue) { if newValue == nil { return } - + for match in matchResults()!.reverse() { let replacement = regex.replacementStringForResult(match, inString: target as String, offset: 0, template: newValue!) let mut = NSMutableString(string: target) mut.replaceCharactersInRange(match.rangeAtIndex(groupno), withString: replacement) - + target = mut as String } } } - + func matchResults(options: NSMatchingOptions = nil) -> [NSTextCheckingResult]? { let matches = regex.matchesInString(target as String, options: options, range: targetRange) as? [NSTextCheckingResult] - + if matches != nil { return matches! } else { return nil } } - + public func ranges(options: NSMatchingOptions = nil) -> [NSRange] { return matchResults(options: options)!.map { $0.range } } - + public func matches(options: NSMatchingOptions = nil) -> [String] { return matchResults(options: options)!.map( { self.substring($0.range)!}) } - + public func allGroups(options: NSMatchingOptions = nil) -> [[String]?] { return matchResults(options: options)!.map {self.groupsForMatch($0)} } - + public func dictionary(options: NSMatchingOptions = nil) -> Dictionary { var out = Dictionary() for match in matchResults(options: options)! { @@ -137,26 +137,26 @@ public class SwiftRegex: NSObject, BooleanType { } return out } - + func substituteMatches(substitution: (NSTextCheckingResult, UnsafeMutablePointer) -> String, options:NSMatchingOptions = nil) -> String { let out = NSMutableString() var pos = 0 - + regex.enumerateMatchesInString(target as String, options: options, range: targetRange ) { (match: NSTextCheckingResult!, flags: NSMatchingFlags, stop: UnsafeMutablePointer) in - + let matchRange = match.range out.appendString( self.substring(NSRange(location:pos, length:matchRange.location-pos))!) out.appendString( substitution(match, stop) ) pos = matchRange.location + matchRange.length } - + out.appendString(substring( NSRange(location:pos, length:targetRange.length-pos))!) - + return out as String } - + public var boolValue: Bool { return doesMatch() } @@ -184,11 +184,11 @@ public func ~= (left: SwiftRegex, right: String) -> String { public func ~= (left: SwiftRegex, right: [String]) -> String { var matchNumber = 0 return left.substituteMatches({match, stop -> String in - + if ++matchNumber == right.count { stop.memory = true } - + return left.regex.replacementStringForResult( match, inString: left.target as String, offset: 0, template: right[matchNumber-1] ) }, options: nil) diff --git a/SwiftIO/WebSocket.swift b/SwiftIO/WebSocket.swift index c74e2b3..4643ce3 100644 --- a/SwiftIO/WebSocket.swift +++ b/SwiftIO/WebSocket.swift @@ -7,7 +7,6 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// import Foundation -import CoreFoundation public protocol WebSocketDelegate: class { func websocketDidConnect(socket: WebSocket) @@ -236,8 +235,8 @@ public class WebSocket : NSObject, NSStreamDelegate { } if self.selfSignedSSL { let settings: Dictionary = [kCFStreamSSLValidatesCertificateChain: NSNumber(bool:false), kCFStreamSSLPeerName: kCFNull] - inputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings) - outputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings) + inputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String) + outputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String) } isRunLoop = true inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) @@ -247,18 +246,18 @@ public class WebSocket : NSObject, NSStreamDelegate { let bytes = UnsafePointer(data.bytes) outputStream!.write(bytes, maxLength: data.length) while(isRunLoop) { - NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as NSDate) + NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as! NSDate) } } //delegate for the stream methods. Processes incoming bytes - func stream(aStream: NSStream!, handleEvent eventCode: NSStreamEvent) { + public func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { if eventCode == .HasBytesAvailable { if(aStream == inputStream) { processInputStream() } } else if eventCode == .ErrorOccurred { - disconnectStream(aStream!.streamError) + disconnectStream(aStream.streamError) } else if eventCode == .EndEncountered { disconnectStream(nil) } @@ -333,7 +332,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } ///Finds the HTTP Packet in the TCP stream, by looking for the CRLF. private func processHTTP(buffer: UnsafePointer, bufferLen: Int) -> Bool { - let CRLFBytes = [UInt8("\r"), UInt8("\n"), UInt8("\r"), UInt8("\n")] + let CRLFBytes = [UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\r"), UInt8(ascii: "\n")] var k = 0 var totalSize = 0 for var i = 0; i < bufferLen; i++ { @@ -376,7 +375,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } let cfHeaders = CFHTTPMessageCopyAllHeaderFields(response.takeUnretainedValue()) let headers: NSDictionary = cfHeaders.takeUnretainedValue() - let acceptKey = headers[headerWSAcceptName] as NSString + let acceptKey = headers[headerWSAcceptName] as! NSString if acceptKey.length > 0 { return true } @@ -500,7 +499,7 @@ public class WebSocket : NSObject, NSStreamDelegate { data = NSData(bytes: UnsafePointer((buffer+offset)), length: Int(len)) } if receivedOpcode == OpCode.Pong.rawValue { - let step = Int(offset+len) + let step = offset + Int(len) let extra = bufferLen-step if extra > 0 { processRawMessage((buffer+step), bufferLen: extra) @@ -565,7 +564,7 @@ public class WebSocket : NSObject, NSStreamDelegate { processResponse(response!) } - let step = Int(offset+len) + let step = offset + Int(len) let extra = bufferLen-step if(extra > 0) { processExtra((buffer+step), bufferLen: extra) @@ -597,9 +596,9 @@ public class WebSocket : NSObject, NSStreamDelegate { } dispatch_async(queue,{ if let textBlock = self.receivedTextBlock{ - textBlock(str!) + textBlock(str! as String) } - self.delegate?.websocketDidReceiveMessage(self, text: str!) + self.delegate?.websocketDidReceiveMessage(self, text: str! as String) }) } else if response.code == .BinaryFrame { let data = response.buffer! //local copy so it is perverse for writing @@ -673,7 +672,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } buffer[1] |= self.MaskMask var maskKey = UnsafeMutablePointer(buffer + offset) - SecRandomCopyBytes(kSecRandomDefault, UInt(sizeof(UInt32)), maskKey) + SecRandomCopyBytes(kSecRandomDefault, Int(sizeof(UInt32)), maskKey) offset += sizeof(UInt32) for (var i = 0; i < dataLength; i++) { @@ -711,4 +710,4 @@ public class WebSocket : NSObject, NSStreamDelegate { } } -} +} \ No newline at end of file