From e79199d2e65487e59311a8b296f8ddb026766739 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Sat, 5 Sep 2015 18:48:56 +0200 Subject: [PATCH 01/13] SocketAckManagerTest --- .../project.pbxproj | 4 +++ SocketIO-iOSTests/SocketAckManagerTest.swift | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 SocketIO-iOSTests/SocketAckManagerTest.swift diff --git a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj index 3315a7a..f4c7536 100644 --- a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj +++ b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ 945B65401B5FCEEA0081E995 /* SwiftRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF871B51F254004FF46E /* SwiftRegex.swift */; }; 945B65411B5FCEEA0081E995 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF881B51F254004FF46E /* WebSocket.swift */; }; 945B65431B63D9DB0081E995 /* SocketEmitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945B65421B63D9DB0081E995 /* SocketEmitTest.swift */; }; + 94A20D611B99E22F00BF9E44 /* SocketAckManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94A20D601B99E22F00BF9E44 /* SocketAckManagerTest.swift */; settings = {ASSET_TAGS = (); }; }; 94ADAC491B652D3300FD79AE /* SocketNamespaceEmitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94ADAC481B652D3300FD79AE /* SocketNamespaceEmitTest.swift */; }; 94ADAC4B1B6632DD00FD79AE /* SocketAcknowledgementTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94ADAC4A1B6632DD00FD79AE /* SocketAcknowledgementTest.swift */; }; 94CB8F0B1B6E48B90019ED53 /* SocketTestCases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94CB8F0A1B6E48B90019ED53 /* SocketTestCases.swift */; }; @@ -110,6 +111,7 @@ 941A4AB91B67A56C00C42318 /* TestKind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestKind.swift; sourceTree = ""; }; 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceAcknowledgementTest.swift; sourceTree = ""; }; 945B65421B63D9DB0081E995 /* SocketEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketEmitTest.swift; sourceTree = ""; }; + 94A20D601B99E22F00BF9E44 /* SocketAckManagerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketAckManagerTest.swift; sourceTree = ""; }; 94ADAC481B652D3300FD79AE /* SocketNamespaceEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceEmitTest.swift; sourceTree = ""; }; 94ADAC4A1B6632DD00FD79AE /* SocketAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketAcknowledgementTest.swift; sourceTree = ""; }; 94CB8F0A1B6E48B90019ED53 /* SocketTestCases.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketTestCases.swift; sourceTree = ""; }; @@ -201,6 +203,7 @@ 94CB8F0A1B6E48B90019ED53 /* SocketTestCases.swift */, 94CB8F0C1B6E66E60019ED53 /* AbstractSocketTest.swift */, 572EF2291B51F16C00EEBB58 /* Supporting Files */, + 94A20D601B99E22F00BF9E44 /* SocketAckManagerTest.swift */, ); path = "SocketIO-iOSTests"; sourceTree = ""; @@ -474,6 +477,7 @@ 945B65431B63D9DB0081E995 /* SocketEmitTest.swift in Sources */, 945B65401B5FCEEA0081E995 /* SwiftRegex.swift in Sources */, 945B653C1B5FCEEA0081E995 /* SocketLogger.swift in Sources */, + 94A20D611B99E22F00BF9E44 /* SocketAckManagerTest.swift in Sources */, 945B65381B5FCEEA0081E995 /* SocketEngineClient.swift in Sources */, 945B65361B5FCEEA0081E995 /* SocketAnyEvent.swift in Sources */, 94ADAC4B1B6632DD00FD79AE /* SocketAcknowledgementTest.swift in Sources */, diff --git a/SocketIO-iOSTests/SocketAckManagerTest.swift b/SocketIO-iOSTests/SocketAckManagerTest.swift new file mode 100644 index 0000000..04df7a5 --- /dev/null +++ b/SocketIO-iOSTests/SocketAckManagerTest.swift @@ -0,0 +1,26 @@ +// +// SocketAckManagerTest.swift +// Socket.IO-Client-Swift +// +// Created by Lukas Schmidt on 04.09.15. +// +// + +import XCTest + +class SocketAckManagerTest: XCTestCase { + var ackManager = SocketAckManager() + + func testAddAcks() { + let callbackExpection = self.expectationWithDescription("callbackExpection") + let itemsArray = ["Hi", "ho"] + func callback(items:NSArray?) { + callbackExpection.fulfill() + items?.isEqualToArray(itemsArray) + } + ackManager.addAck(1, callback: callback) + ackManager.executeAck(1, items: itemsArray) + waitForExpectationsWithTimeout(3.0, handler: nil) + + } +} From de0d0b8676e2a8983f98c259e2795834053854c8 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Sun, 6 Sep 2015 20:04:10 +0200 Subject: [PATCH 02/13] socket parser Test --- .../project.pbxproj | 6 +- SocketIO-iOSTests/SocketParserTest.swift | 81 +++++++++++++++++++ SocketIOClientSwift/SocketPacket.swift | 10 +-- SocketIOClientSwift/SocketParser.swift | 27 +++---- 4 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 SocketIO-iOSTests/SocketParserTest.swift diff --git a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj index f4c7536..7eb4cd2 100644 --- a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj +++ b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ 945B65401B5FCEEA0081E995 /* SwiftRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF871B51F254004FF46E /* SwiftRegex.swift */; }; 945B65411B5FCEEA0081E995 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF881B51F254004FF46E /* WebSocket.swift */; }; 945B65431B63D9DB0081E995 /* SocketEmitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945B65421B63D9DB0081E995 /* SocketEmitTest.swift */; }; + 949FAE8D1B9B94E600073BE9 /* SocketParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 949FAE8C1B9B94E600073BE9 /* SocketParserTest.swift */; settings = {ASSET_TAGS = (); }; }; 94A20D611B99E22F00BF9E44 /* SocketAckManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94A20D601B99E22F00BF9E44 /* SocketAckManagerTest.swift */; settings = {ASSET_TAGS = (); }; }; 94ADAC491B652D3300FD79AE /* SocketNamespaceEmitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94ADAC481B652D3300FD79AE /* SocketNamespaceEmitTest.swift */; }; 94ADAC4B1B6632DD00FD79AE /* SocketAcknowledgementTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94ADAC4A1B6632DD00FD79AE /* SocketAcknowledgementTest.swift */; }; @@ -111,6 +112,7 @@ 941A4AB91B67A56C00C42318 /* TestKind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestKind.swift; sourceTree = ""; }; 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceAcknowledgementTest.swift; sourceTree = ""; }; 945B65421B63D9DB0081E995 /* SocketEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketEmitTest.swift; sourceTree = ""; }; + 949FAE8C1B9B94E600073BE9 /* SocketParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketParserTest.swift; sourceTree = ""; }; 94A20D601B99E22F00BF9E44 /* SocketAckManagerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketAckManagerTest.swift; sourceTree = ""; }; 94ADAC481B652D3300FD79AE /* SocketNamespaceEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceEmitTest.swift; sourceTree = ""; }; 94ADAC4A1B6632DD00FD79AE /* SocketAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketAcknowledgementTest.swift; sourceTree = ""; }; @@ -202,8 +204,9 @@ 941A4AB91B67A56C00C42318 /* TestKind.swift */, 94CB8F0A1B6E48B90019ED53 /* SocketTestCases.swift */, 94CB8F0C1B6E66E60019ED53 /* AbstractSocketTest.swift */, - 572EF2291B51F16C00EEBB58 /* Supporting Files */, 94A20D601B99E22F00BF9E44 /* SocketAckManagerTest.swift */, + 572EF2291B51F16C00EEBB58 /* Supporting Files */, + 949FAE8C1B9B94E600073BE9 /* SocketParserTest.swift */, ); path = "SocketIO-iOSTests"; sourceTree = ""; @@ -484,6 +487,7 @@ 945B653F1B5FCEEA0081E995 /* SocketTypes.swift in Sources */, 74781D5B1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */, 945B653B1B5FCEEA0081E995 /* SocketIOClient.swift in Sources */, + 949FAE8D1B9B94E600073BE9 /* SocketParserTest.swift in Sources */, 94ADAC491B652D3300FD79AE /* SocketNamespaceEmitTest.swift in Sources */, 945B65411B5FCEEA0081E995 /* WebSocket.swift in Sources */, 94242BB81B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift in Sources */, diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift new file mode 100644 index 0000000..948efb8 --- /dev/null +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -0,0 +1,81 @@ +// +// SocketParserTest.swift +// Socket.IO-Client-Swift +// +// Created by Lukas Schmidt on 05.09.15. +// +// + +import XCTest + +class SocketParserTest: XCTestCase { + + //Format key: message; namespace-data-binary-id + static let packetTypes: Dictionary = [ + "0": ("/", [], [], -1), "1": ("/", [], [], -1), + "2/swift,[\"testArrayEmitReturn\",[\"test3\",\"test4\"]]": ("/swift", ["testArrayEmitReturn", ["test3", "test4"]], [], -1), + "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", ["testMultipleItemsWithBufferEmitReturn", [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], -1), + "3/swift,0[[\"test3\",\"test4\"]]": ("/swift", [["test3", "test4"]], [], 0), + "61-/swift,9[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 9), + "4/swift": ("/swift", [], [], -1), + "10": ("/swift", [], [], -1)] + + func testDisconnect() { + let message = "1" + validateParseResult(message) + } + + func testConnect() { + let message = "0" + validateParseResult(message) + } + + func testNameSpaceArrayParse() { + let message = "2/swift,[\"testArrayEmitReturn\",[\"test3\",\"test4\"]]" + validateParseResult(message) + } + + func testNameSpaceArrayAckParse() { + let message = "3/swift,0[[\"test3\",\"test4\"]]" + validateParseResult(message) + } + + func testNameSpaceBinaryEventParse() { + let message = "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]" + validateParseResult(message) + } + + func testNameSpaceBinaryAckParse() { + let message = "61-/swift,9[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]" + validateParseResult(message) + } + + func testNamespaceErrorParse() { + let message = "4/swift" + validateParseResult(message) + } + + func testInvalidInput() { + let message = "10" + validateParseResult(message) + } + + func validateParseResult(message:String) { + let validValues = SocketParserTest.packetTypes[message]! + let packet = SocketParser.parseString(message) + let type = message.substringWithRange(Range(start: message.startIndex, end: message.startIndex.advancedBy(1))) + if let packet = packet { + XCTAssertEqual(packet.type, SocketPacket.PacketType(str:type)!) + XCTAssertEqual(packet.nsp, validValues.0) + XCTAssertTrue((packet.data as NSArray).isEqualToArray(validValues.1)) + XCTAssertTrue((packet.binary as NSArray).isEqualToArray(validValues.2)) + XCTAssertEqual(packet.id, validValues.3) + }else { + XCTFail() + } + } + +// func testParsePerformance() { +// +// } +} diff --git a/SocketIOClientSwift/SocketPacket.swift b/SocketIOClientSwift/SocketPacket.swift index e25bd9d..e2f6f85 100644 --- a/SocketIOClientSwift/SocketPacket.swift +++ b/SocketIOClientSwift/SocketPacket.swift @@ -62,15 +62,7 @@ struct SocketPacket { var binary: [NSData] var data: [AnyObject] var description: String { - var better = "SocketPacket {type: ~~0; data: ~~1; " + - "id: ~~2; placeholders: ~~3;}" - - better = better["~~0"] ~= String(type.rawValue) - better = better["~~1"] ~= String(data) - better = better["~~2"] ~= String(id) - better = better["~~3"] ~= String(placeholders) - - return better + return "SocketPacket {type: \(String(type.rawValue)); data: \(String(data)); id: \(id); placeholders: \(placeholders);}" } var event: String { diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index e06681d..d37f8f2 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -173,38 +173,33 @@ class SocketParser { // Parses messages recieved static func parseSocketMessage(stringMessage: String, socket: SocketIOClient) { - if stringMessage == "" { - return - } + guard !stringMessage.isEmpty else { return } + print(stringMessage) Logger.log("Parsing %@", client: socket, altType: "SocketParser", args: stringMessage) - let p: SocketPacket - - if let pack = parseString(stringMessage) { - p = pack - } else { + guard let pack = parseString(stringMessage) else { socket.didError("Error parsing packet") return } - Logger.log("Decoded packet as: %@", client: socket, altType: "SocketParser", args: p.description) + Logger.log("Decoded packet as: %@", client: socket, altType: "SocketParser", args: pack.description) - switch p.type { + switch pack.type { case SocketPacket.PacketType.Event: - handleEvent(p, socket: socket) + handleEvent(pack, socket: socket) case SocketPacket.PacketType.Ack: - handleAck(p, socket: socket) + handleAck(pack, socket: socket) case SocketPacket.PacketType.BinaryEvent: - handleBinaryEvent(p, socket: socket) + handleBinaryEvent(pack, socket: socket) case SocketPacket.PacketType.BinaryAck: - handleBinaryAck(p, socket: socket) + handleBinaryAck(pack, socket: socket) case SocketPacket.PacketType.Connect: - handleConnect(p, socket: socket) + handleConnect(pack, socket: socket) case SocketPacket.PacketType.Disconnect: socket.didDisconnect("Got Disconnect") case SocketPacket.PacketType.Error: - socket.didError("Error: \(p.data)") + socket.didError("Error: \(pack.data)") } } From 16ed2bd1308ee9c67ccd0b3708905ff747dac380 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Sun, 6 Sep 2015 22:45:18 +0200 Subject: [PATCH 03/13] refactor clean up code --- SocketIO-iOSTests/SocketParserTest.swift | 15 +++++++++---- SocketIOClientSwift/SocketParser.swift | 27 ++++++++++++------------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 948efb8..602e6ab 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -57,7 +57,8 @@ class SocketParserTest: XCTestCase { func testInvalidInput() { let message = "10" - validateParseResult(message) + let packet = SocketParser.parseString(message) + XCTAssertNil(packet) } func validateParseResult(message:String) { @@ -75,7 +76,13 @@ class SocketParserTest: XCTestCase { } } -// func testParsePerformance() { -// -// } + func testParsePerformance() { + let keys = Array(SocketParserTest.packetTypes.keys) + measureBlock({ + for item in keys.enumerate() { + SocketParser.parseString(item.element) + } + }) + + } } diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index d37f8f2..74c57b2 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -73,10 +73,12 @@ class SocketParser { // Translation of socket.io-client#decodeString static func parseString(str: String) -> SocketPacket? { let arr = Array(str.characters) - let type = String(arr[0]) + guard let type = SocketPacket.PacketType(str: String(arr[0])) else { + NSLog("Error parsing \(str)") + return nil} if arr.count == 1 { - return SocketPacket(type: SocketPacket.PacketType(str: type)!, nsp: "/") + return SocketPacket(type: type, nsp: "/") } var id: Int? @@ -84,7 +86,7 @@ class SocketParser { var i = 0 var placeholders = -1 - if type == "5" || type == "6" { + if type == .BinaryEvent || type == .BinaryAck { var buf = "" while arr[++i] != "-" { @@ -117,7 +119,7 @@ class SocketParser { } if i + 1 >= arr.count { - return SocketPacket(type: SocketPacket.PacketType(str: type)!, id: id ?? -1, + return SocketPacket(type: type, id: id ?? -1, nsp: nsp ?? "/", placeholders: placeholders) } @@ -142,7 +144,7 @@ class SocketParser { let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" let data = SocketParser.parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] - return SocketPacket(type: SocketPacket.PacketType(str: type)!, data: data, id: id ?? -1, + return SocketPacket(type: type, data: data, id: id ?? -1, nsp: nsp ?? "/", placeholders: placeholders) } @@ -174,7 +176,6 @@ class SocketParser { // Parses messages recieved static func parseSocketMessage(stringMessage: String, socket: SocketIOClient) { guard !stringMessage.isEmpty else { return } - print(stringMessage) Logger.log("Parsing %@", client: socket, altType: "SocketParser", args: stringMessage) @@ -186,19 +187,19 @@ class SocketParser { Logger.log("Decoded packet as: %@", client: socket, altType: "SocketParser", args: pack.description) switch pack.type { - case SocketPacket.PacketType.Event: + case .Event: handleEvent(pack, socket: socket) - case SocketPacket.PacketType.Ack: + case .Ack: handleAck(pack, socket: socket) - case SocketPacket.PacketType.BinaryEvent: + case .BinaryEvent: handleBinaryEvent(pack, socket: socket) - case SocketPacket.PacketType.BinaryAck: + case .BinaryAck: handleBinaryAck(pack, socket: socket) - case SocketPacket.PacketType.Connect: + case .Connect: handleConnect(pack, socket: socket) - case SocketPacket.PacketType.Disconnect: + case .Disconnect: socket.didDisconnect("Got Disconnect") - case SocketPacket.PacketType.Error: + case .Error: socket.didError("Error: \(pack.data)") } } From 13087ff1b7d2050fba7fed5cc7b77982e22630a2 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Sun, 6 Sep 2015 23:45:52 +0200 Subject: [PATCH 04/13] clean up code --- SocketIOClientSwift/SocketParser.swift | 45 +++++++++++--------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 74c57b2..a3d97c7 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -23,6 +23,7 @@ import Foundation class SocketParser { + private static func isCorrectNamespace(nsp: String, _ socket: SocketIOClient) -> Bool { return nsp == socket.nsp } @@ -72,12 +73,12 @@ class SocketParser { // Translation of socket.io-client#decodeString static func parseString(str: String) -> SocketPacket? { - let arr = Array(str.characters) - guard let type = SocketPacket.PacketType(str: String(arr[0])) else { + let messageCharacters = Array(str.characters) + guard let type = SocketPacket.PacketType(str: String(messageCharacters[0])) else { NSLog("Error parsing \(str)") return nil} - if arr.count == 1 { + if messageCharacters.count == 1 { return SocketPacket(type: type, nsp: "/") } @@ -89,14 +90,14 @@ class SocketParser { if type == .BinaryEvent || type == .BinaryAck { var buf = "" - while arr[++i] != "-" { - buf += String(arr[i]) - if i == arr.count { + while messageCharacters[++i] != "-" { + buf += String(messageCharacters[i]) + if i == messageCharacters.count { break } } - if let holders = Int(buf) where arr[i] == "-" { + if let holders = Int(buf) where messageCharacters[i] == "-" { placeholders = holders } else { NSLog("Error parsing \(str)") @@ -104,11 +105,11 @@ class SocketParser { } } - if arr[i + 1] == "/" { + if messageCharacters[i + 1] == "/" { nsp = "" - while ++i < arr.count { - let c = arr[i] + while ++i < messageCharacters.count { + let c = messageCharacters[i] if c == "," { break @@ -118,17 +119,17 @@ class SocketParser { } } - if i + 1 >= arr.count { + if i + 1 >= messageCharacters.count { return SocketPacket(type: type, id: id ?? -1, nsp: nsp ?? "/", placeholders: placeholders) } - let next = String(arr[i + 1]) + let next = String(messageCharacters[i + 1]) if Int(next) != nil { var c = "" - while ++i < arr.count { - if let int = Int(String(arr[i])) { + while ++i < messageCharacters.count { + if let int = Int(String(messageCharacters[i])) { c += String(int) } else { --i @@ -139,7 +140,7 @@ class SocketParser { id = Int(c) } - if ++i < arr.count { + if ++i < messageCharacters.count { let d = str[str.startIndex.advancedBy(i)...str.startIndex.advancedBy(str.characters.count-1)] let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" let data = SocketParser.parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] @@ -153,24 +154,14 @@ class SocketParser { // Parses data for events static func parseData(data: String) -> AnyObject? { - var err: NSError? let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) - let parsed: AnyObject? - do { - parsed = try NSJSONSerialization.JSONObjectWithData(stringData!, + return try NSJSONSerialization.JSONObjectWithData(stringData!, options: NSJSONReadingOptions.MutableContainers) } catch let error as NSError { - err = error - parsed = nil - } - - if err != nil { - // println(err) + //TODO Log error return nil } - - return parsed } // Parses messages recieved From 0b8be08a5471edee2dcf742c872872fc95e7d8d9 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 12:53:28 +0200 Subject: [PATCH 05/13] use new parser for binary --- SocketIO-iOSTests/SocketParserTest.swift | 9 ++++ SocketIOClientSwift/SocketParser.swift | 55 +++++++++++++++++++----- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 602e6ab..71fb896 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -61,6 +61,15 @@ class SocketParserTest: XCTestCase { XCTAssertNil(packet) } + func testGenericParser() { + var parser = GenericParser(message: "61-/swift,", currentIndex: 0) + XCTAssertEqual(parser.read(1), "6") + XCTAssertEqual(parser.currentCharacter, "1") + XCTAssertEqual(parser.readUntilStringOccurence("-"), "1") + XCTAssertEqual(parser.currentCharacter, "-") + + } + func validateParseResult(message:String) { let validValues = SocketParserTest.packetTypes[message]! let packet = SocketParser.parseString(message) diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index d7086e8..1c20efd 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -22,6 +22,45 @@ import Foundation +struct GenericParser { + let message: String + var currentIndex:Int + var messageCharacters: Array { + get { + return Array(message.characters) + } + } + var currentCharacter: String? { + get{ + if currentIndex >= messageCharacters.count { + return nil + } + return String(messageCharacters[currentIndex]) + } + } + + mutating func read(characterLength:Int) -> String? { + let startIndex = message.startIndex.advancedBy(currentIndex) + let range = Range(start: startIndex, end: startIndex.advancedBy(characterLength)) + currentIndex = currentIndex + characterLength + + return message.substringWithRange(range) + } + + mutating func readUntilStringOccurence(string:String) -> String? { + let startIndex = message.startIndex.advancedBy(currentIndex) + let range = Range(start: startIndex, end: message.endIndex) + let subString = message.substringWithRange(range) as NSString + let foundRange = subString.rangeOfString(string) + if foundRange.location == Int.max { + return nil + } + currentIndex = foundRange.location + 1 + + return subString.substringToIndex(foundRange.location) + } +} + class SocketParser { private static func isCorrectNamespace(nsp: String, _ socket: SocketIOClient) -> Bool { @@ -73,8 +112,9 @@ class SocketParser { // Translation of socket.io-client#decodeString static func parseString(str: String) -> SocketPacket? { + var parser = GenericParser(message: str, currentIndex: 0) let messageCharacters = Array(str.characters) - guard let type = SocketPacket.PacketType(str: String(messageCharacters[0])) else { + guard let typeString = parser.read(1), let type = SocketPacket.PacketType(str: typeString) else { NSLog("Error parsing \(str)") return nil} @@ -88,21 +128,14 @@ class SocketParser { var placeholders = -1 if type == .BinaryEvent || type == .BinaryAck { - var buf = "" - - while messageCharacters[++i] != "-" { - buf += String(messageCharacters[i]) - if i == messageCharacters.count { - break - } - } - - if let holders = Int(buf) where messageCharacters[i] == "-" { + if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer) where parser.read(1) == "-" { placeholders = holders } else { NSLog("Error parsing \(str)") return nil } + + i = parser.currentIndex - 1 } if messageCharacters[i + 1] == "/" { From 8bae7d06d2dbb1b912e3c08575b9507380693976 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 13:53:43 +0200 Subject: [PATCH 06/13] using parser for namespace --- SocketIO-iOSTests/SocketParserTest.swift | 6 +++--- SocketIOClientSwift/SocketParser.swift | 22 ++++++---------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 71fb896..883a6d8 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -17,7 +17,7 @@ class SocketParserTest: XCTestCase { "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", ["testMultipleItemsWithBufferEmitReturn", [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], -1), "3/swift,0[[\"test3\",\"test4\"]]": ("/swift", [["test3", "test4"]], [], 0), "61-/swift,9[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 9), - "4/swift": ("/swift", [], [], -1), + "4/swift,": ("/swift", [], [], -1), "10": ("/swift", [], [], -1)] func testDisconnect() { @@ -51,12 +51,12 @@ class SocketParserTest: XCTestCase { } func testNamespaceErrorParse() { - let message = "4/swift" + let message = "4/swift," validateParseResult(message) } func testInvalidInput() { - let message = "10" + let message = "8" let packet = SocketParser.parseString(message) XCTAssertNil(packet) } diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 1c20efd..1318462 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -55,7 +55,7 @@ struct GenericParser { if foundRange.location == Int.max { return nil } - currentIndex = foundRange.location + 1 + currentIndex = currentIndex + foundRange.location return subString.substringToIndex(foundRange.location) } @@ -128,7 +128,7 @@ class SocketParser { var placeholders = -1 if type == .BinaryEvent || type == .BinaryAck { - if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer) where parser.read(1) == "-" { + if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer) where parser.read(1)! == "-" { placeholders = holders } else { NSLog("Error parsing \(str)") @@ -137,22 +137,12 @@ class SocketParser { i = parser.currentIndex - 1 } - - if messageCharacters[i + 1] == "/" { - nsp = "" - - while ++i < messageCharacters.count { - let c = messageCharacters[i] - - if c == "," { - break - } - - nsp! += String(c) - } + if parser.currentCharacter == "/" { + nsp = parser.readUntilStringOccurence(",") + i = parser.currentIndex } - if i + 1 >= messageCharacters.count { + if parser.currentIndex + 1 >= parser.messageCharacters.count { return SocketPacket(type: type, id: id ?? -1, nsp: nsp ?? "/", placeholders: placeholders) } From fb9b19820bb7fe2c784a92192f8c465d0d7103b4 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 14:44:43 +0200 Subject: [PATCH 07/13] complete use of parser --- SocketIO-iOSTests/SocketParserTest.swift | 4 +-- SocketIOClientSwift/SocketParser.swift | 35 +++++++++--------------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 883a6d8..362c71f 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -16,7 +16,7 @@ class SocketParserTest: XCTestCase { "2/swift,[\"testArrayEmitReturn\",[\"test3\",\"test4\"]]": ("/swift", ["testArrayEmitReturn", ["test3", "test4"]], [], -1), "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", ["testMultipleItemsWithBufferEmitReturn", [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], -1), "3/swift,0[[\"test3\",\"test4\"]]": ("/swift", [["test3", "test4"]], [], 0), - "61-/swift,9[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 9), + "61-/swift,19[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 19), "4/swift,": ("/swift", [], [], -1), "10": ("/swift", [], [], -1)] @@ -46,7 +46,7 @@ class SocketParserTest: XCTestCase { } func testNameSpaceBinaryAckParse() { - let message = "61-/swift,9[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]" + let message = "61-/swift,19[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]" validateParseResult(message) } diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 1318462..31db9db 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -122,9 +122,7 @@ class SocketParser { return SocketPacket(type: type, nsp: "/") } - var id: Int? var nsp:String? - var i = 0 var placeholders = -1 if type == .BinaryEvent || type == .BinaryAck { @@ -134,41 +132,34 @@ class SocketParser { NSLog("Error parsing \(str)") return nil } - - i = parser.currentIndex - 1 } if parser.currentCharacter == "/" { nsp = parser.readUntilStringOccurence(",") - i = parser.currentIndex + parser.currentIndex++ } - if parser.currentIndex + 1 >= parser.messageCharacters.count { - return SocketPacket(type: type, id: id ?? -1, + if parser.currentIndex >= parser.messageCharacters.count { + return SocketPacket(type: type, id: -1, nsp: nsp ?? "/", placeholders: placeholders) } - let next = String(messageCharacters[i + 1]) - if Int(next) != nil { - var c = "" - while ++i < messageCharacters.count { - if let int = Int(String(messageCharacters[i])) { - c += String(int) - } else { - --i - break - } + var idString = "" + while parser.currentIndex < messageCharacters.count { + if let next = parser.read(1), let int = Int(next) { + idString += String(int) + } else { + parser.currentIndex -= 2 + break } - - id = Int(c) } - if ++i < messageCharacters.count { - let d = str[str.startIndex.advancedBy(i)...str.startIndex.advancedBy(str.characters.count-1)] + if parser.currentIndex < messageCharacters.count { + let d = str[str.startIndex.advancedBy(parser.currentIndex + 1)...str.startIndex.advancedBy(str.characters.count-1)] let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" let data = SocketParser.parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] - return SocketPacket(type: type, data: data, id: id ?? -1, + return SocketPacket(type: type, data: data, id: Int(idString) ?? -1, nsp: nsp ?? "/", placeholders: placeholders) } From 2bd612e47a0b875f5b61bfa2720f46c965b597e0 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 15:08:10 +0200 Subject: [PATCH 08/13] refactor, make use of try catch --- GenericSocketParser.swift | 48 ++++++++ .../project.pbxproj | 6 + SocketIO-iOSTests/SocketParserTest.swift | 32 +++-- SocketIOClientSwift/SocketParser.swift | 112 +++++++----------- 4 files changed, 109 insertions(+), 89 deletions(-) create mode 100644 GenericSocketParser.swift diff --git a/GenericSocketParser.swift b/GenericSocketParser.swift new file mode 100644 index 0000000..4ab7d9c --- /dev/null +++ b/GenericSocketParser.swift @@ -0,0 +1,48 @@ +// +// GenericSocketParser.swift +// Socket.IO-Client-Swift +// +// Created by Lukas Schmidt on 07.09.15. +// +// + +import Foundation + +struct GenericParser { + let message: String + var currentIndex:Int + var messageCharacters: Array { + get { + return Array(message.characters) + } + } + var currentCharacter: String? { + get{ + if currentIndex >= messageCharacters.count { + return nil + } + return String(messageCharacters[currentIndex]) + } + } + + mutating func read(characterLength:Int) -> String? { + let startIndex = message.startIndex.advancedBy(currentIndex) + let range = Range(start: startIndex, end: startIndex.advancedBy(characterLength)) + currentIndex = currentIndex + characterLength + + return message.substringWithRange(range) + } + + mutating func readUntilStringOccurence(string:String) -> String? { + let startIndex = message.startIndex.advancedBy(currentIndex) + let range = Range(start: startIndex, end: message.endIndex) + let subString = message.substringWithRange(range) as NSString + let foundRange = subString.rangeOfString(string) + if foundRange.location == Int.max { + return nil + } + currentIndex = currentIndex + foundRange.location + + return subString.substringToIndex(foundRange.location) + } +} \ No newline at end of file diff --git a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj index 7eb4cd2..d49cac7 100644 --- a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj +++ b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj @@ -43,6 +43,8 @@ 74781D5C1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; }; 74781D5D1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; }; 941A4ABA1B67A56C00C42318 /* TestKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 941A4AB91B67A56C00C42318 /* TestKind.swift */; }; + 9421F5D01B9DBF5900D625BB /* GenericSocketParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */; settings = {ASSET_TAGS = (); }; }; + 9421F5D11B9DBF5900D625BB /* GenericSocketParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */; settings = {ASSET_TAGS = (); }; }; 94242BB81B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */; }; 945B65351B5FCEEA0081E995 /* SocketAckManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7C1B51F254004FF46E /* SocketAckManager.swift */; }; 945B65361B5FCEEA0081E995 /* SocketAnyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7D1B51F254004FF46E /* SocketAnyEvent.swift */; }; @@ -110,6 +112,7 @@ 5764DF881B51F254004FF46E /* WebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebSocket.swift; path = SocketIOClientSwift/WebSocket.swift; sourceTree = ""; }; 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClientStatus.swift; path = SocketIOClientSwift/SocketIOClientStatus.swift; sourceTree = ""; }; 941A4AB91B67A56C00C42318 /* TestKind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestKind.swift; sourceTree = ""; }; + 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenericSocketParser.swift; sourceTree = ""; }; 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceAcknowledgementTest.swift; sourceTree = ""; }; 945B65421B63D9DB0081E995 /* SocketEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketEmitTest.swift; sourceTree = ""; }; 949FAE8C1B9B94E600073BE9 /* SocketParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketParserTest.swift; sourceTree = ""; }; @@ -267,6 +270,7 @@ 5764DF831B51F254004FF46E /* SocketLogger.swift */, 5764DF841B51F254004FF46E /* SocketPacket.swift */, 5764DF851B51F254004FF46E /* SocketParser.swift */, + 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */, 5764DF861B51F254004FF46E /* SocketTypes.swift */, 5764DF871B51F254004FF46E /* SwiftRegex.swift */, 5764DF881B51F254004FF46E /* WebSocket.swift */, @@ -454,6 +458,7 @@ 5764DF911B51F254004FF46E /* SocketEventHandler.swift in Sources */, 5764DF931B51F254004FF46E /* SocketFixUTF8.swift in Sources */, 5764DF951B51F254004FF46E /* SocketIOClient.swift in Sources */, + 9421F5D01B9DBF5900D625BB /* GenericSocketParser.swift in Sources */, 5764DF8B1B51F254004FF46E /* SocketAnyEvent.swift in Sources */, 5764DF971B51F254004FF46E /* SocketLogger.swift in Sources */, 74781D5A1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */, @@ -475,6 +480,7 @@ 94CB8F0B1B6E48B90019ED53 /* SocketTestCases.swift in Sources */, 945B65371B5FCEEA0081E995 /* SocketEngine.swift in Sources */, 945B65351B5FCEEA0081E995 /* SocketAckManager.swift in Sources */, + 9421F5D11B9DBF5900D625BB /* GenericSocketParser.swift in Sources */, 941A4ABA1B67A56C00C42318 /* TestKind.swift in Sources */, 94CB8F0D1B6E66E60019ED53 /* AbstractSocketTest.swift in Sources */, 945B65431B63D9DB0081E995 /* SocketEmitTest.swift in Sources */, diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 362c71f..83ffc05 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -17,8 +17,7 @@ class SocketParserTest: XCTestCase { "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", ["testMultipleItemsWithBufferEmitReturn", [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], -1), "3/swift,0[[\"test3\",\"test4\"]]": ("/swift", [["test3", "test4"]], [], 0), "61-/swift,19[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 19), - "4/swift,": ("/swift", [], [], -1), - "10": ("/swift", [], [], -1)] + "4/swift,": ("/swift", [], [], -1)] func testDisconnect() { let message = "1" @@ -57,8 +56,12 @@ class SocketParserTest: XCTestCase { func testInvalidInput() { let message = "8" - let packet = SocketParser.parseString(message) - XCTAssertNil(packet) + do { + try SocketParser.parseString(message) + XCTFail("Should throw exeption") + } catch { + + } } func testGenericParser() { @@ -66,32 +69,27 @@ class SocketParserTest: XCTestCase { XCTAssertEqual(parser.read(1), "6") XCTAssertEqual(parser.currentCharacter, "1") XCTAssertEqual(parser.readUntilStringOccurence("-"), "1") - XCTAssertEqual(parser.currentCharacter, "-") + XCTAssertEqual(parser.currentCharacter, "-") } func validateParseResult(message:String) { let validValues = SocketParserTest.packetTypes[message]! - let packet = SocketParser.parseString(message) + let packet = try! SocketParser.parseString(message) let type = message.substringWithRange(Range(start: message.startIndex, end: message.startIndex.advancedBy(1))) - if let packet = packet { - XCTAssertEqual(packet.type, SocketPacket.PacketType(str:type)!) - XCTAssertEqual(packet.nsp, validValues.0) - XCTAssertTrue((packet.data as NSArray).isEqualToArray(validValues.1)) - XCTAssertTrue((packet.binary as NSArray).isEqualToArray(validValues.2)) - XCTAssertEqual(packet.id, validValues.3) - }else { - XCTFail() - } + XCTAssertEqual(packet.type, SocketPacket.PacketType(str:type)!) + XCTAssertEqual(packet.nsp, validValues.0) + XCTAssertTrue((packet.data as NSArray).isEqualToArray(validValues.1)) + XCTAssertTrue((packet.binary as NSArray).isEqualToArray(validValues.2)) + XCTAssertEqual(packet.id, validValues.3) } func testParsePerformance() { let keys = Array(SocketParserTest.packetTypes.keys) measureBlock({ for item in keys.enumerate() { - SocketParser.parseString(item.element) + try! SocketParser.parseString(item.element) } }) - } } diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 31db9db..05c0658 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -22,43 +22,8 @@ import Foundation -struct GenericParser { - let message: String - var currentIndex:Int - var messageCharacters: Array { - get { - return Array(message.characters) - } - } - var currentCharacter: String? { - get{ - if currentIndex >= messageCharacters.count { - return nil - } - return String(messageCharacters[currentIndex]) - } - } - - mutating func read(characterLength:Int) -> String? { - let startIndex = message.startIndex.advancedBy(currentIndex) - let range = Range(start: startIndex, end: startIndex.advancedBy(characterLength)) - currentIndex = currentIndex + characterLength - - return message.substringWithRange(range) - } - - mutating func readUntilStringOccurence(string:String) -> String? { - let startIndex = message.startIndex.advancedBy(currentIndex) - let range = Range(start: startIndex, end: message.endIndex) - let subString = message.substringWithRange(range) as NSString - let foundRange = subString.rangeOfString(string) - if foundRange.location == Int.max { - return nil - } - currentIndex = currentIndex + foundRange.location - - return subString.substringToIndex(foundRange.location) - } +enum SocketParserError: ErrorType { + case InvalidMessageType, InvalidBinaryPalceholder } class SocketParser { @@ -111,12 +76,12 @@ class SocketParser { } // Translation of socket.io-client#decodeString - static func parseString(str: String) -> SocketPacket? { + static func parseString(str: String) throws -> SocketPacket { var parser = GenericParser(message: str, currentIndex: 0) let messageCharacters = Array(str.characters) guard let typeString = parser.read(1), let type = SocketPacket.PacketType(str: typeString) else { - NSLog("Error parsing \(str)") - return nil} + throw SocketParserError.InvalidMessageType + } if messageCharacters.count == 1 { return SocketPacket(type: type, nsp: "/") @@ -129,8 +94,7 @@ class SocketParser { if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer) where parser.read(1)! == "-" { placeholders = holders } else { - NSLog("Error parsing \(str)") - return nil + throw SocketParserError.InvalidBinaryPalceholder } } if parser.currentCharacter == "/" { @@ -154,16 +118,12 @@ class SocketParser { } } - if parser.currentIndex < messageCharacters.count { - let d = str[str.startIndex.advancedBy(parser.currentIndex + 1)...str.startIndex.advancedBy(str.characters.count-1)] - let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" - let data = SocketParser.parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] - - return SocketPacket(type: type, data: data, id: Int(idString) ?? -1, - nsp: nsp ?? "/", placeholders: placeholders) - } + let d = str[str.startIndex.advancedBy(parser.currentIndex + 1)...str.startIndex.advancedBy(str.characters.count - 1)] + let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" + let data = SocketParser.parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] - return nil + return SocketPacket(type: type, data: data, id: Int(idString) ?? -1, + nsp: nsp ?? "/", placeholders: placeholders) } // Parses data for events @@ -184,29 +144,37 @@ class SocketParser { Logger.log("Parsing %@", type: "SocketParser", args: stringMessage) - guard let pack = parseString(stringMessage) else { - socket.didError("Error parsing packet") - return + do { + let pack = try parseString(stringMessage) + Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) + + switch pack.type { + case .Event: + handleEvent(pack, socket: socket) + case .Ack: + handleAck(pack, socket: socket) + case .BinaryEvent: + handleBinaryEvent(pack, socket: socket) + case .BinaryAck: + handleBinaryAck(pack, socket: socket) + case .Connect: + handleConnect(pack, socket: socket) + case .Disconnect: + socket.didDisconnect("Got Disconnect") + case .Error: + socket.didError("Error: \(pack.data)") + } + + }catch SocketParserError.InvalidBinaryPalceholder { + Logger.error("Parsed Invalid Binary Placeholder", type: "SocketParser") } - - Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) - - switch pack.type { - case .Event: - handleEvent(pack, socket: socket) - case .Ack: - handleAck(pack, socket: socket) - case .BinaryEvent: - handleBinaryEvent(pack, socket: socket) - case .BinaryAck: - handleBinaryAck(pack, socket: socket) - case .Connect: - handleConnect(pack, socket: socket) - case .Disconnect: - socket.didDisconnect("Got Disconnect") - case .Error: - socket.didError("Error: \(pack.data)") + catch SocketParserError.InvalidMessageType { + Logger.error("Parsed Invalid Binary Placeholder", type: "SocketParser") } + catch { + + } + } static func parseBinaryData(data: NSData, socket: SocketIOClient) { From 70cacb025ffaa5af37dec2c717688aca2e2c5965 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 19:19:22 +0200 Subject: [PATCH 09/13] fix join namespace parse --- GenericSocketParser.swift | 4 ++++ SocketIO-iOSTests/AbstractSocketTest.swift | 2 +- SocketIO-iOSTests/SocketAcknowledgementTest.swift | 3 ++- SocketIO-iOSTests/SocketEmitTest.swift | 3 ++- .../SocketNamespaceAcknowledgementTest.swift | 3 ++- SocketIO-iOSTests/SocketNamespaceEmitTest.swift | 5 ++--- SocketIO-iOSTests/SocketParserTest.swift | 14 +++++++++++++- SocketIOClientSwift/SocketParser.swift | 4 ++-- 8 files changed, 28 insertions(+), 10 deletions(-) diff --git a/GenericSocketParser.swift b/GenericSocketParser.swift index 4ab7d9c..a963988 100644 --- a/GenericSocketParser.swift +++ b/GenericSocketParser.swift @@ -45,4 +45,8 @@ struct GenericParser { return subString.substringToIndex(foundRange.location) } + + mutating func readUntilEnd() ->String { + return read(messageCharacters.count - currentIndex)! + } } \ No newline at end of file diff --git a/SocketIO-iOSTests/AbstractSocketTest.swift b/SocketIO-iOSTests/AbstractSocketTest.swift index 1fd61c2..fb3c5f4 100644 --- a/SocketIO-iOSTests/AbstractSocketTest.swift +++ b/SocketIO-iOSTests/AbstractSocketTest.swift @@ -9,7 +9,7 @@ import XCTest class AbstractSocketTest: XCTestCase { - static let testLocal = false + static let testLocal = true static let serverURL = AbstractSocketTest.testLocal ? "localhost:6979" : "milkbartube.com:6979" static let TEST_TIMEOUT = 8.0 static var socket:SocketIOClient! diff --git a/SocketIO-iOSTests/SocketAcknowledgementTest.swift b/SocketIO-iOSTests/SocketAcknowledgementTest.swift index 0f1f425..4a8c7ad 100644 --- a/SocketIO-iOSTests/SocketAcknowledgementTest.swift +++ b/SocketIO-iOSTests/SocketAcknowledgementTest.swift @@ -21,11 +21,12 @@ class SocketAcknowledgementTest: AbstractSocketTest { "forcePolling": false, "forceWebsockets": false,// default false "path": ""]) + openConnection() }else { AbstractSocketTest.socket.leaveNamespace() } - openConnection() + } func testConnectionStatus() { diff --git a/SocketIO-iOSTests/SocketEmitTest.swift b/SocketIO-iOSTests/SocketEmitTest.swift index 5e58491..baffb95 100644 --- a/SocketIO-iOSTests/SocketEmitTest.swift +++ b/SocketIO-iOSTests/SocketEmitTest.swift @@ -22,11 +22,12 @@ class SocketEmitTest: AbstractSocketTest { "forceWebsockets": false,// default false "path": ""] ) + openConnection() }else { AbstractSocketTest.socket.leaveNamespace() } - openConnection() + } override func tearDown() { diff --git a/SocketIO-iOSTests/SocketNamespaceAcknowledgementTest.swift b/SocketIO-iOSTests/SocketNamespaceAcknowledgementTest.swift index a0604f3..ce7e272 100644 --- a/SocketIO-iOSTests/SocketNamespaceAcknowledgementTest.swift +++ b/SocketIO-iOSTests/SocketNamespaceAcknowledgementTest.swift @@ -22,11 +22,12 @@ class SocketNamespaceAcknowledgementTest: AbstractSocketTest { "forceWebsockets": false,// default false "path": "", "nsp": "/swift"]) + openConnection() }else { AbstractSocketTest.socket.joinNamespace("/swift") } - openConnection() + } func testConnectionStatus() { diff --git a/SocketIO-iOSTests/SocketNamespaceEmitTest.swift b/SocketIO-iOSTests/SocketNamespaceEmitTest.swift index e02ede3..9573a64 100644 --- a/SocketIO-iOSTests/SocketNamespaceEmitTest.swift +++ b/SocketIO-iOSTests/SocketNamespaceEmitTest.swift @@ -22,13 +22,12 @@ class SocketNamespaceEmitTest: AbstractSocketTest { "forceWebsockets": false,// default false "path": "", "nsp": "/swift"]) + openConnection() }else { AbstractSocketTest.socket.joinNamespace("/swift") } - - openConnection() } - + func testConnectionStatus() { super.checkConnectionStatus() } diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 83ffc05..0e4e3ac 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -17,7 +17,9 @@ class SocketParserTest: XCTestCase { "51-/swift,[\"testMultipleItemsWithBufferEmitReturn\",[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", ["testMultipleItemsWithBufferEmitReturn", [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], -1), "3/swift,0[[\"test3\",\"test4\"]]": ("/swift", [["test3", "test4"]], [], 0), "61-/swift,19[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 19), - "4/swift,": ("/swift", [], [], -1)] + "4/swift,": ("/swift", [], [], -1), + "0/swift": ("/swift", [], [], -1), + "1/swift": ("/swift", [], [], -1)] func testDisconnect() { let message = "1" @@ -29,6 +31,16 @@ class SocketParserTest: XCTestCase { validateParseResult(message) } + func testDisconnectNameSpace() { + let message = "1/swift" + validateParseResult(message) + } + + func testConnecttNameSpace() { + let message = "0/swift" + validateParseResult(message) + } + func testNameSpaceArrayParse() { let message = "2/swift,[\"testArrayEmitReturn\",[\"test3\",\"test4\"]]" validateParseResult(message) diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 05c0658..72ea70a 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -98,7 +98,7 @@ class SocketParser { } } if parser.currentCharacter == "/" { - nsp = parser.readUntilStringOccurence(",") + nsp = parser.readUntilStringOccurence(",") ?? parser.readUntilEnd() parser.currentIndex++ } @@ -178,7 +178,7 @@ class SocketParser { } static func parseBinaryData(data: NSData, socket: SocketIOClient) { - if socket.waitingData.count == 0 { + guard !socket.waitingData.isEmpty else { Logger.error("Got data when not remaking packet", type: "SocketParser") return } From 568b2ae1bc2f43ae786b4d2813290a0474b55688 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 19:28:19 +0200 Subject: [PATCH 10/13] clean up using guard --- SocketIOClientSwift/SocketParser.swift | 54 ++++++++------------------ 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 72ea70a..225c3cd 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -32,26 +32,20 @@ class SocketParser { return nsp == socket.nsp } + private static func handleEvent(p: SocketPacket, socket: SocketIOClient) { + guard isCorrectNamespace(p.nsp, socket) else { return } + socket.handleEvent(p.event, data: p.args, + isInternalMessage: false, wantsAck: p.id) + } + private static func handleAck(p: SocketPacket, socket: SocketIOClient) { - if !isCorrectNamespace(p.nsp, socket) { - return - } + guard isCorrectNamespace(p.nsp, socket) else { return } socket.handleAck(p.id, data: p.data) } - private static func handleBinaryAck(p: SocketPacket, socket: SocketIOClient) { - if !isCorrectNamespace(p.nsp, socket) { - return - } - - socket.waitingData.append(p) - } - - private static func handleBinaryEvent(p: SocketPacket, socket: SocketIOClient) { - if !isCorrectNamespace(p.nsp, socket) { - return - } + private static func handleBinary(p: SocketPacket, socket: SocketIOClient) { + guard isCorrectNamespace(p.nsp, socket) else { return } socket.waitingData.append(p) } @@ -66,24 +60,14 @@ class SocketParser { } } - private static func handleEvent(p: SocketPacket, socket: SocketIOClient) { - if !isCorrectNamespace(p.nsp, socket) { - return - } - - socket.handleEvent(p.event, data: p.args, - isInternalMessage: false, wantsAck: p.id) - } - // Translation of socket.io-client#decodeString static func parseString(str: String) throws -> SocketPacket { var parser = GenericParser(message: str, currentIndex: 0) - let messageCharacters = Array(str.characters) guard let typeString = parser.read(1), let type = SocketPacket.PacketType(str: typeString) else { throw SocketParserError.InvalidMessageType } - if messageCharacters.count == 1 { + if parser.messageCharacters.count == 1 { return SocketPacket(type: type, nsp: "/") } @@ -107,9 +91,8 @@ class SocketParser { nsp: nsp ?? "/", placeholders: placeholders) } - var idString = "" - while parser.currentIndex < messageCharacters.count { + while parser.currentIndex < parser.messageCharacters.count { if let next = parser.read(1), let int = Int(next) { idString += String(int) } else { @@ -132,8 +115,8 @@ class SocketParser { do { return try NSJSONSerialization.JSONObjectWithData(stringData!, options: NSJSONReadingOptions.MutableContainers) - } catch let error as NSError { - //TODO Log error + } catch { + Logger.error("Parsing JSON: %@", type: "SocketParser", args: data) return nil } } @@ -154,9 +137,9 @@ class SocketParser { case .Ack: handleAck(pack, socket: socket) case .BinaryEvent: - handleBinaryEvent(pack, socket: socket) + handleBinary(pack, socket: socket) case .BinaryAck: - handleBinaryAck(pack, socket: socket) + handleBinary(pack, socket: socket) case .Connect: handleConnect(pack, socket: socket) case .Disconnect: @@ -184,15 +167,12 @@ class SocketParser { } let shouldExecute = socket.waitingData[0].addData(data) - - if !shouldExecute { - return - } + guard shouldExecute else { return } var packet = socket.waitingData.removeAtIndex(0) packet.fillInPlaceholders() - if packet.type != SocketPacket.PacketType.BinaryAck { + if packet.type != .BinaryAck { socket.handleEvent(packet.event, data: packet.args, isInternalMessage: false, wantsAck: packet.id) } else { From 12f607e3c3aff4f87a7010be5e76eaaaded9ea1a Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 19:34:45 +0200 Subject: [PATCH 11/13] disable locale test --- SocketIO-iOSTests/AbstractSocketTest.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SocketIO-iOSTests/AbstractSocketTest.swift b/SocketIO-iOSTests/AbstractSocketTest.swift index fb3c5f4..1fd61c2 100644 --- a/SocketIO-iOSTests/AbstractSocketTest.swift +++ b/SocketIO-iOSTests/AbstractSocketTest.swift @@ -9,7 +9,7 @@ import XCTest class AbstractSocketTest: XCTestCase { - static let testLocal = true + static let testLocal = false static let serverURL = AbstractSocketTest.testLocal ? "localhost:6979" : "milkbartube.com:6979" static let TEST_TIMEOUT = 8.0 static var socket:SocketIOClient! From 91cc683b5b1ec0195264385c99c9dc316b2b2908 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 20:25:13 +0200 Subject: [PATCH 12/13] clean up code style --- GenericSocketParser.swift | 6 ++-- SocketIO-iOSTests/SocketAckManagerTest.swift | 2 +- SocketIO-iOSTests/SocketParserTest.swift | 2 +- SocketIOClientSwift/SocketParser.swift | 30 +++++++++++--------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/GenericSocketParser.swift b/GenericSocketParser.swift index a963988..04b25ae 100644 --- a/GenericSocketParser.swift +++ b/GenericSocketParser.swift @@ -8,10 +8,10 @@ import Foundation -struct GenericParser { +struct GenericSocketParser { let message: String - var currentIndex:Int - var messageCharacters: Array { + var currentIndex: Int + var messageCharacters: [Character] { get { return Array(message.characters) } diff --git a/SocketIO-iOSTests/SocketAckManagerTest.swift b/SocketIO-iOSTests/SocketAckManagerTest.swift index 04df7a5..e2664d9 100644 --- a/SocketIO-iOSTests/SocketAckManagerTest.swift +++ b/SocketIO-iOSTests/SocketAckManagerTest.swift @@ -14,7 +14,7 @@ class SocketAckManagerTest: XCTestCase { func testAddAcks() { let callbackExpection = self.expectationWithDescription("callbackExpection") let itemsArray = ["Hi", "ho"] - func callback(items:NSArray?) { + func callback(items: NSArray?) { callbackExpection.fulfill() items?.isEqualToArray(itemsArray) } diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 0e4e3ac..e4f7a1a 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -77,7 +77,7 @@ class SocketParserTest: XCTestCase { } func testGenericParser() { - var parser = GenericParser(message: "61-/swift,", currentIndex: 0) + var parser = GenericSocketParser(message: "61-/swift,", currentIndex: 0) XCTAssertEqual(parser.read(1), "6") XCTAssertEqual(parser.currentCharacter, "1") XCTAssertEqual(parser.readUntilStringOccurence("-"), "1") diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 225c3cd..59025e4 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -61,9 +61,10 @@ class SocketParser { } // Translation of socket.io-client#decodeString - static func parseString(str: String) throws -> SocketPacket { - var parser = GenericParser(message: str, currentIndex: 0) - guard let typeString = parser.read(1), let type = SocketPacket.PacketType(str: typeString) else { + static func parseString(message: String) throws -> SocketPacket { + var parser = GenericSocketParser(message: message, currentIndex: 0) + guard let typeString = parser.read(1), + let type = SocketPacket.PacketType(str: typeString) else { throw SocketParserError.InvalidMessageType } @@ -71,24 +72,25 @@ class SocketParser { return SocketPacket(type: type, nsp: "/") } - var nsp:String? + var namespace: String? var placeholders = -1 if type == .BinaryEvent || type == .BinaryAck { - if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer) where parser.read(1)! == "-" { + if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer) + where parser.read(1)! == "-" { placeholders = holders } else { throw SocketParserError.InvalidBinaryPalceholder } } if parser.currentCharacter == "/" { - nsp = parser.readUntilStringOccurence(",") ?? parser.readUntilEnd() + namespace = parser.readUntilStringOccurence(",") ?? parser.readUntilEnd() parser.currentIndex++ } if parser.currentIndex >= parser.messageCharacters.count { return SocketPacket(type: type, id: -1, - nsp: nsp ?? "/", placeholders: placeholders) + nsp: namespace ?? "/", placeholders: placeholders) } var idString = "" @@ -101,12 +103,12 @@ class SocketParser { } } - let d = str[str.startIndex.advancedBy(parser.currentIndex + 1)...str.startIndex.advancedBy(str.characters.count - 1)] + let d = message[message.startIndex.advancedBy(parser.currentIndex + 1)...message.startIndex.advancedBy(message.characters.count - 1)] let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" - let data = SocketParser.parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] + let data = parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders] return SocketPacket(type: type, data: data, id: Int(idString) ?? -1, - nsp: nsp ?? "/", placeholders: placeholders) + nsp: namespace ?? "/", placeholders: placeholders) } // Parses data for events @@ -122,13 +124,13 @@ class SocketParser { } // Parses messages recieved - static func parseSocketMessage(stringMessage: String, socket: SocketIOClient) { - guard !stringMessage.isEmpty else { return } + static func parseSocketMessage(message: String, socket: SocketIOClient) { + guard !message.isEmpty else { return } - Logger.log("Parsing %@", type: "SocketParser", args: stringMessage) + Logger.log("Parsing %@", type: "SocketParser", args: message) do { - let pack = try parseString(stringMessage) + let pack = try parseString(message) Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) switch pack.type { From 222f622d3a3f892c53ff138464c797f783c821cf Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 7 Sep 2015 21:29:51 +0200 Subject: [PATCH 13/13] use optionals instead of try/catch --- .../project.pbxproj | 12 ++-- ...tParser.swift => SocketGenericParser.swift | 2 +- SocketIO-iOSTests/SocketParserTest.swift | 28 ++++----- SocketIOClientSwift/SocketParser.swift | 60 ++++++++----------- 4 files changed, 44 insertions(+), 58 deletions(-) rename GenericSocketParser.swift => SocketGenericParser.swift (98%) diff --git a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj index d49cac7..3800e67 100644 --- a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj +++ b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj @@ -43,8 +43,8 @@ 74781D5C1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; }; 74781D5D1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; }; 941A4ABA1B67A56C00C42318 /* TestKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 941A4AB91B67A56C00C42318 /* TestKind.swift */; }; - 9421F5D01B9DBF5900D625BB /* GenericSocketParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */; settings = {ASSET_TAGS = (); }; }; - 9421F5D11B9DBF5900D625BB /* GenericSocketParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */; settings = {ASSET_TAGS = (); }; }; + 9421F5D01B9DBF5900D625BB /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9421F5CF1B9DBF5900D625BB /* SocketGenericParser.swift */; settings = {ASSET_TAGS = (); }; }; + 9421F5D11B9DBF5900D625BB /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9421F5CF1B9DBF5900D625BB /* SocketGenericParser.swift */; settings = {ASSET_TAGS = (); }; }; 94242BB81B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */; }; 945B65351B5FCEEA0081E995 /* SocketAckManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7C1B51F254004FF46E /* SocketAckManager.swift */; }; 945B65361B5FCEEA0081E995 /* SocketAnyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7D1B51F254004FF46E /* SocketAnyEvent.swift */; }; @@ -112,7 +112,7 @@ 5764DF881B51F254004FF46E /* WebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebSocket.swift; path = SocketIOClientSwift/WebSocket.swift; sourceTree = ""; }; 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClientStatus.swift; path = SocketIOClientSwift/SocketIOClientStatus.swift; sourceTree = ""; }; 941A4AB91B67A56C00C42318 /* TestKind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestKind.swift; sourceTree = ""; }; - 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenericSocketParser.swift; sourceTree = ""; }; + 9421F5CF1B9DBF5900D625BB /* SocketGenericParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketGenericParser.swift; sourceTree = ""; }; 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceAcknowledgementTest.swift; sourceTree = ""; }; 945B65421B63D9DB0081E995 /* SocketEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketEmitTest.swift; sourceTree = ""; }; 949FAE8C1B9B94E600073BE9 /* SocketParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketParserTest.swift; sourceTree = ""; }; @@ -270,7 +270,7 @@ 5764DF831B51F254004FF46E /* SocketLogger.swift */, 5764DF841B51F254004FF46E /* SocketPacket.swift */, 5764DF851B51F254004FF46E /* SocketParser.swift */, - 9421F5CF1B9DBF5900D625BB /* GenericSocketParser.swift */, + 9421F5CF1B9DBF5900D625BB /* SocketGenericParser.swift */, 5764DF861B51F254004FF46E /* SocketTypes.swift */, 5764DF871B51F254004FF46E /* SwiftRegex.swift */, 5764DF881B51F254004FF46E /* WebSocket.swift */, @@ -458,7 +458,7 @@ 5764DF911B51F254004FF46E /* SocketEventHandler.swift in Sources */, 5764DF931B51F254004FF46E /* SocketFixUTF8.swift in Sources */, 5764DF951B51F254004FF46E /* SocketIOClient.swift in Sources */, - 9421F5D01B9DBF5900D625BB /* GenericSocketParser.swift in Sources */, + 9421F5D01B9DBF5900D625BB /* SocketGenericParser.swift in Sources */, 5764DF8B1B51F254004FF46E /* SocketAnyEvent.swift in Sources */, 5764DF971B51F254004FF46E /* SocketLogger.swift in Sources */, 74781D5A1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */, @@ -480,7 +480,7 @@ 94CB8F0B1B6E48B90019ED53 /* SocketTestCases.swift in Sources */, 945B65371B5FCEEA0081E995 /* SocketEngine.swift in Sources */, 945B65351B5FCEEA0081E995 /* SocketAckManager.swift in Sources */, - 9421F5D11B9DBF5900D625BB /* GenericSocketParser.swift in Sources */, + 9421F5D11B9DBF5900D625BB /* SocketGenericParser.swift in Sources */, 941A4ABA1B67A56C00C42318 /* TestKind.swift in Sources */, 94CB8F0D1B6E66E60019ED53 /* AbstractSocketTest.swift in Sources */, 945B65431B63D9DB0081E995 /* SocketEmitTest.swift in Sources */, diff --git a/GenericSocketParser.swift b/SocketGenericParser.swift similarity index 98% rename from GenericSocketParser.swift rename to SocketGenericParser.swift index 04b25ae..0320084 100644 --- a/GenericSocketParser.swift +++ b/SocketGenericParser.swift @@ -8,7 +8,7 @@ import Foundation -struct GenericSocketParser { +struct SocketGenericParser { let message: String var currentIndex: Int var messageCharacters: [Character] { diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index e4f7a1a..7198b4c 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -68,39 +68,37 @@ class SocketParserTest: XCTestCase { func testInvalidInput() { let message = "8" - do { - try SocketParser.parseString(message) - XCTFail("Should throw exeption") - } catch { - - } + XCTAssertNil(SocketParser.parseString(message)) } func testGenericParser() { - var parser = GenericSocketParser(message: "61-/swift,", currentIndex: 0) + var parser = SocketGenericParser(message: "61-/swift,", currentIndex: 0) XCTAssertEqual(parser.read(1), "6") XCTAssertEqual(parser.currentCharacter, "1") XCTAssertEqual(parser.readUntilStringOccurence("-"), "1") XCTAssertEqual(parser.currentCharacter, "-") - } func validateParseResult(message:String) { let validValues = SocketParserTest.packetTypes[message]! - let packet = try! SocketParser.parseString(message) + let packet = SocketParser.parseString(message) let type = message.substringWithRange(Range(start: message.startIndex, end: message.startIndex.advancedBy(1))) - XCTAssertEqual(packet.type, SocketPacket.PacketType(str:type)!) - XCTAssertEqual(packet.nsp, validValues.0) - XCTAssertTrue((packet.data as NSArray).isEqualToArray(validValues.1)) - XCTAssertTrue((packet.binary as NSArray).isEqualToArray(validValues.2)) - XCTAssertEqual(packet.id, validValues.3) + if let packet = packet { + XCTAssertEqual(packet.type, SocketPacket.PacketType(str:type)!) + XCTAssertEqual(packet.nsp, validValues.0) + XCTAssertTrue((packet.data as NSArray).isEqualToArray(validValues.1)) + XCTAssertTrue((packet.binary as NSArray).isEqualToArray(validValues.2)) + XCTAssertEqual(packet.id, validValues.3) + }else { + XCTFail() + } } func testParsePerformance() { let keys = Array(SocketParserTest.packetTypes.keys) measureBlock({ for item in keys.enumerate() { - try! SocketParser.parseString(item.element) + SocketParser.parseString(item.element) } }) } diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 59025e4..fc637a6 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -22,10 +22,6 @@ import Foundation -enum SocketParserError: ErrorType { - case InvalidMessageType, InvalidBinaryPalceholder -} - class SocketParser { private static func isCorrectNamespace(nsp: String, _ socket: SocketIOClient) -> Bool { @@ -61,11 +57,11 @@ class SocketParser { } // Translation of socket.io-client#decodeString - static func parseString(message: String) throws -> SocketPacket { - var parser = GenericSocketParser(message: message, currentIndex: 0) + static func parseString(message: String) -> SocketPacket? { + var parser = SocketGenericParser(message: message, currentIndex: 0) guard let typeString = parser.read(1), let type = SocketPacket.PacketType(str: typeString) else { - throw SocketParserError.InvalidMessageType + return nil } if parser.messageCharacters.count == 1 { @@ -80,7 +76,7 @@ class SocketParser { where parser.read(1)! == "-" { placeholders = holders } else { - throw SocketParserError.InvalidBinaryPalceholder + return nil } } if parser.currentCharacter == "/" { @@ -129,35 +125,27 @@ class SocketParser { Logger.log("Parsing %@", type: "SocketParser", args: message) - do { - let pack = try parseString(message) - Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) - - switch pack.type { - case .Event: - handleEvent(pack, socket: socket) - case .Ack: - handleAck(pack, socket: socket) - case .BinaryEvent: - handleBinary(pack, socket: socket) - case .BinaryAck: - handleBinary(pack, socket: socket) - case .Connect: - handleConnect(pack, socket: socket) - case .Disconnect: - socket.didDisconnect("Got Disconnect") - case .Error: - socket.didError("Error: \(pack.data)") - } - - }catch SocketParserError.InvalidBinaryPalceholder { - Logger.error("Parsed Invalid Binary Placeholder", type: "SocketParser") + guard let pack = parseString(message) else { + Logger.error("Parsing message", type: "SocketParser", args: message) + return } - catch SocketParserError.InvalidMessageType { - Logger.error("Parsed Invalid Binary Placeholder", type: "SocketParser") - } - catch { - + Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description) + + switch pack.type { + case .Event: + handleEvent(pack, socket: socket) + case .Ack: + handleAck(pack, socket: socket) + case .BinaryEvent: + handleBinary(pack, socket: socket) + case .BinaryAck: + handleBinary(pack, socket: socket) + case .Connect: + handleConnect(pack, socket: socket) + case .Disconnect: + socket.didDisconnect("Got Disconnect") + case .Error: + socket.didError("Error: \(pack.data)") } }