Refactor engine polling. Change SocketGenericParser to SocketStringReader

This commit is contained in:
Erik 2015-09-12 17:04:34 -04:00
parent f82aafd5c8
commit 0e0d47b6ed
7 changed files with 102 additions and 131 deletions

View File

@ -12,7 +12,7 @@
572EF23D1B51F18A00EEBB58 /* SocketIO-Mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 572EF23C1B51F18A00EEBB58 /* SocketIO-Mac.h */; settings = {ATTRIBUTES = (Public, ); }; };
572EF2431B51F18A00EEBB58 /* SocketIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 572EF2381B51F18A00EEBB58 /* SocketIO.framework */; };
572EF24A1B51F18A00EEBB58 /* SocketIO_MacTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 572EF2491B51F18A00EEBB58 /* SocketIO_MacTests.swift */; };
57425F9C1BA3A46000BDAAC1 /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketGenericParser.swift */; };
57425F9C1BA3A46000BDAAC1 /* SocketStringReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketStringReader.swift */; };
57425F9D1BA3A46000BDAAC1 /* SocketEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7E1B51F254004FF46E /* SocketEngine.swift */; };
57425F9E1BA3A46000BDAAC1 /* SocketParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF851B51F254004FF46E /* SocketParser.swift */; };
57425F9F1BA3A46000BDAAC1 /* SocketTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF861B51F254004FF46E /* SocketTypes.swift */; };
@ -28,7 +28,7 @@
57425FA91BA3A46000BDAAC1 /* SocketAckManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7C1B51F254004FF46E /* SocketAckManager.swift */; };
57425FAA1BA3A46000BDAAC1 /* SwiftRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF871B51F254004FF46E /* SwiftRegex.swift */; };
57425FAD1BA3A46000BDAAC1 /* SocketIO-iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 572EF21E1B51F16C00EEBB58 /* SocketIO-iOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
57425FDC1BA3A4F100BDAAC1 /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketGenericParser.swift */; };
57425FDC1BA3A4F100BDAAC1 /* SocketStringReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketStringReader.swift */; };
57425FDD1BA3A4F100BDAAC1 /* SocketParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF851B51F254004FF46E /* SocketParser.swift */; };
57425FDE1BA3A4F100BDAAC1 /* SocketPacket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF841B51F254004FF46E /* SocketPacket.swift */; };
57425FDF1BA3A4F100BDAAC1 /* SocketFixUTF8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF811B51F254004FF46E /* SocketFixUTF8.swift */; };
@ -83,9 +83,9 @@
74781D5B1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; };
74781D5C1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; };
74781D5D1B7E83930042CACA /* SocketIOClientStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74781D591B7E83930042CACA /* SocketIOClientStatus.swift */; };
74D765621B9F0D870028551C /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketGenericParser.swift */; };
74D765631B9F0D9F0028551C /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketGenericParser.swift */; };
74D765641B9F0DA40028551C /* SocketGenericParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketGenericParser.swift */; };
74D765621B9F0D870028551C /* SocketStringReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketStringReader.swift */; };
74D765631B9F0D9F0028551C /* SocketStringReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketStringReader.swift */; };
74D765641B9F0DA40028551C /* SocketStringReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D765611B9F0D870028551C /* SocketStringReader.swift */; };
941A4ABA1B67A56C00C42318 /* TestKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 941A4AB91B67A56C00C42318 /* TestKind.swift */; };
94242BB81B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */; };
945B65351B5FCEEA0081E995 /* SocketAckManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5764DF7C1B51F254004FF46E /* SocketAckManager.swift */; };
@ -162,7 +162,7 @@
5764DF871B51F254004FF46E /* SwiftRegex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftRegex.swift; path = SocketIOClientSwift/SwiftRegex.swift; sourceTree = "<group>"; };
5764DF881B51F254004FF46E /* WebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebSocket.swift; path = SocketIOClientSwift/WebSocket.swift; sourceTree = "<group>"; };
74781D591B7E83930042CACA /* SocketIOClientStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClientStatus.swift; path = SocketIOClientSwift/SocketIOClientStatus.swift; sourceTree = "<group>"; };
74D765611B9F0D870028551C /* SocketGenericParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SocketGenericParser.swift; path = SocketIOClientSwift/SocketGenericParser.swift; sourceTree = "<group>"; };
74D765611B9F0D870028551C /* SocketStringReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SocketStringReader.swift; path = SocketIOClientSwift/SocketStringReader.swift; sourceTree = "<group>"; };
941A4AB91B67A56C00C42318 /* TestKind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestKind.swift; sourceTree = "<group>"; };
94242BB71B67B0E500AAAC9D /* SocketNamespaceAcknowledgementTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespaceAcknowledgementTest.swift; sourceTree = "<group>"; };
945B65421B63D9DB0081E995 /* SocketEmitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketEmitTest.swift; sourceTree = "<group>"; };
@ -333,12 +333,12 @@
5764DF7F1B51F254004FF46E /* SocketEngineClient.swift */,
5764DF801B51F254004FF46E /* SocketEventHandler.swift */,
5764DF811B51F254004FF46E /* SocketFixUTF8.swift */,
74D765611B9F0D870028551C /* SocketGenericParser.swift */,
5764DF821B51F254004FF46E /* SocketIOClient.swift */,
74781D591B7E83930042CACA /* SocketIOClientStatus.swift */,
5764DF831B51F254004FF46E /* SocketLogger.swift */,
5764DF841B51F254004FF46E /* SocketPacket.swift */,
5764DF851B51F254004FF46E /* SocketParser.swift */,
74D765611B9F0D870028551C /* SocketStringReader.swift */,
5764DF861B51F254004FF46E /* SocketTypes.swift */,
5764DF871B51F254004FF46E /* SwiftRegex.swift */,
5764DF881B51F254004FF46E /* WebSocket.swift */,
@ -579,7 +579,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74D765631B9F0D9F0028551C /* SocketGenericParser.swift in Sources */,
74D765631B9F0D9F0028551C /* SocketStringReader.swift in Sources */,
5764DF8D1B51F254004FF46E /* SocketEngine.swift in Sources */,
5764DF9B1B51F254004FF46E /* SocketParser.swift in Sources */,
5764DF9D1B51F254004FF46E /* SocketTypes.swift in Sources */,
@ -601,7 +601,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74D765621B9F0D870028551C /* SocketGenericParser.swift in Sources */,
74D765621B9F0D870028551C /* SocketStringReader.swift in Sources */,
945B653E1B5FCEEA0081E995 /* SocketParser.swift in Sources */,
945B653D1B5FCEEA0081E995 /* SocketPacket.swift in Sources */,
945B653A1B5FCEEA0081E995 /* SocketFixUTF8.swift in Sources */,
@ -632,7 +632,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74D765641B9F0DA40028551C /* SocketGenericParser.swift in Sources */,
74D765641B9F0DA40028551C /* SocketStringReader.swift in Sources */,
5764DF8E1B51F254004FF46E /* SocketEngine.swift in Sources */,
5764DF9C1B51F254004FF46E /* SocketParser.swift in Sources */,
5764DF9E1B51F254004FF46E /* SocketTypes.swift in Sources */,
@ -663,7 +663,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
57425F9C1BA3A46000BDAAC1 /* SocketGenericParser.swift in Sources */,
57425F9C1BA3A46000BDAAC1 /* SocketStringReader.swift in Sources */,
57425F9D1BA3A46000BDAAC1 /* SocketEngine.swift in Sources */,
57425F9E1BA3A46000BDAAC1 /* SocketParser.swift in Sources */,
57425F9F1BA3A46000BDAAC1 /* SocketTypes.swift in Sources */,
@ -685,7 +685,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
57425FDC1BA3A4F100BDAAC1 /* SocketGenericParser.swift in Sources */,
57425FDC1BA3A4F100BDAAC1 /* SocketStringReader.swift in Sources */,
57425FDD1BA3A4F100BDAAC1 /* SocketParser.swift in Sources */,
57425FDE1BA3A4F100BDAAC1 /* SocketPacket.swift in Sources */,
57425FDF1BA3A4F100BDAAC1 /* SocketFixUTF8.swift in Sources */,

View File

@ -72,24 +72,25 @@ class SocketParserTest: XCTestCase {
}
func testGenericParser() {
var parser = SocketGenericParser(message: "61-/swift,", currentIndex: 0)
var parser = SocketStringReader(message: "61-/swift,", currentIndex: "61-/swift,".startIndex)
XCTAssertEqual(parser.read(1), "6")
XCTAssertEqual(parser.currentCharacter, "1")
XCTAssertEqual(parser.readUntilStringOccurence("-"), "1")
XCTAssertEqual(parser.currentCharacter, "-")
XCTAssertEqual(parser.currentCharacter, "/")
}
func validateParseResult(message:String) {
func validateParseResult(message: String) {
let validValues = SocketParserTest.packetTypes[message]!
let packet = SocketParser.parseString(message)
let type = message.substringWithRange(Range<String.Index>(start: message.startIndex, end: message.startIndex.advancedBy(1)))
if let packet = packet {
print(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 {
} else {
XCTFail()
}
}

View File

@ -154,7 +154,6 @@ public final class SocketEngine: NSObject, WebSocketDelegate {
}
if params != nil {
for (key, value) in params! {
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
allowedCharacterSet)!
@ -350,10 +349,10 @@ public final class SocketEngine: NSObject, WebSocketDelegate {
// We had packets waiting for send when we upgraded
// Send them raw
private func flushWaitingForPostToWebSocket() {
if let ws = ws {
for msg in postWait {
ws.writeString(msg)
}
guard let ws = self.ws else {return}
for msg in postWait {
ws.writeString(msg)
}
postWait.removeAll(keepCapacity: true)
@ -486,54 +485,19 @@ public final class SocketEngine: NSObject, WebSocketDelegate {
}
// Translatation of engine.io-parser#decodePayload
private func parsePollingMessage(str:String) {
private func parsePollingMessage(str: String) {
guard str.characters.count != 1 else {
return
}
// println(str)
let strArray = Array(str.characters)
var length = ""
var n = 0
var msg = ""
func testLength(length: String, inout n: Int) -> Bool {
if let num = Int(length) {
n = num
return false
} else {
return true
}
}
for var i = 0, l = str.characters.count; i < l; i++ {
let chr = String(strArray[i])
if chr != ":" {
length += chr
} else {
if length == "" || testLength(length, n: &n) {
Logger.error("Parsing error: %@", type: logType, args: str)
handlePollingFailed("Error parsing XHR message")
return
}
msg = String(strArray[i+1...i+n])
if let lengthInt = Int(length) where lengthInt != msg.characters.count {
Logger.error("Parsing error: %@", type: logType, args: str)
return
}
if msg.characters.count != 0 {
// Be sure to capture the value of the msg
dispatch_async(handleQueue) {
self.parseEngineMessage(msg, fromPolling: true)
}
}
i += n
length = ""
var reader = SocketStringReader(message: str, currentIndex: str.startIndex)
while reader.hasNext {
let n = reader.readUntilStringOccurence(":")
let str = reader.read(Int(n)!)
dispatch_async(handleQueue) {
self.parseEngineMessage(str, fromPolling: true)
}
}
}

View File

@ -1,52 +0,0 @@
//
// GenericSocketParser.swift
// Socket.IO-Client-Swift
//
// Created by Lukas Schmidt on 07.09.15.
//
//
import Foundation
struct SocketGenericParser {
let message: String
var currentIndex: Int
var messageCharacters: [Character] {
return Array(message.characters)
}
var currentCharacter: String? {
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<String.Index>(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<String.Index>(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)
}
mutating func readUntilEnd() -> String {
return read(messageCharacters.count - currentIndex)!
}
}

View File

@ -64,7 +64,8 @@ struct SocketPacket {
var binary: [NSData]
var data: [AnyObject]
var description: String {
return "SocketPacket {type: \(String(type.rawValue)); data: \(String(data)); id: \(id); placeholders: \(placeholders);}"
return "SocketPacket {type: \(String(type.rawValue)); data: " +
"\(String(data)); id: \(id); placeholders: \(placeholders); nsp: \(nsp)}"
}
var event: String {

View File

@ -59,12 +59,12 @@ class SocketParser {
// Translation of socket.io-client#decodeString
static func parseString(message: String) -> SocketPacket? {
var parser = SocketGenericParser(message: message, currentIndex: 0)
var parser = SocketStringReader(message: message, currentIndex: message.startIndex)
guard let typeString = parser.read(1), type = SocketPacket.PacketType(str: typeString)
guard let type = SocketPacket.PacketType(str: parser.read(1))
else {return nil}
if parser.messageCharacters.count == 1 {
if !parser.hasNext {
return SocketPacket(type: type, nsp: "/")
}
@ -72,34 +72,34 @@ class SocketParser {
var placeholders = -1
if type == .BinaryEvent || type == .BinaryAck {
if let buffer = parser.readUntilStringOccurence("-"), let holders = Int(buffer)
where parser.read(1)! == "-" {
Logger.log("Got some binary", type: "SocketParser")
if let holders = Int(parser.readUntilStringOccurence("-")) {
placeholders = holders
} else {
return nil
}
}
if parser.currentCharacter == "/" {
namespace = parser.readUntilStringOccurence(",") ?? parser.readUntilEnd()
parser.currentIndex++
}
if parser.currentIndex >= parser.messageCharacters.count {
if !parser.hasNext {
return SocketPacket(type: type, id: -1,
nsp: namespace ?? "/", placeholders: placeholders)
}
var idString = ""
while parser.currentIndex < parser.messageCharacters.count {
if let next = parser.read(1), let int = Int(next) {
while parser.hasNext {
if let int = Int(parser.read(1)) {
idString += String(int)
} else {
parser.currentIndex -= 2
parser.advanceIndexBy(-2)
break
}
}
let d = message[message.startIndex.advancedBy(parser.currentIndex + 1)...message.startIndex.advancedBy(message.characters.count - 1)]
let d = message[parser.currentIndex.advancedBy(1)...message.endIndex.predecessor()]
let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\""
let data = parseData(noPlaceholders) as? [AnyObject] ?? [noPlaceholders]
@ -126,7 +126,7 @@ class SocketParser {
Logger.log("Parsing %@", type: "SocketParser", args: message)
guard let pack = parseString(message) else {
Logger.error("Parsing message", type: "SocketParser", args: message)
Logger.error("Parsing message: %@", type: "SocketParser", args: message)
return
}

View File

@ -0,0 +1,57 @@
//
// SocketStringReader.swift
// Socket.IO-Client-Swift
//
// Created by Lukas Schmidt on 07.09.15.
//
//
import Foundation
struct SocketStringReader {
let message: String
var currentIndex: String.Index
var hasNext: Bool {
return currentIndex != message.endIndex
}
var messageCharacters: [Character] {
return Array(message.characters)
}
var currentCharacter: String {
return String(message[currentIndex])
}
mutating func advanceIndexBy(n: Int) {
currentIndex = currentIndex.advancedBy(n)
}
mutating func read(readLength: Int) -> String {
let range = Range<String.Index>(start: currentIndex, end: currentIndex.advancedBy(readLength))
advanceIndexBy(readLength)
return message.substringWithRange(range)
}
mutating func readUntilStringOccurence(string: String) -> String {
let range = Range<String.Index>(start: currentIndex, end: message.endIndex)
let subString = message.substringWithRange(range) as NSString
let foundRange = subString.rangeOfString(string)
if foundRange.length == 0 {
let restOfString = message[currentIndex...message.endIndex.predecessor()]
currentIndex = message.endIndex
return restOfString
}
advanceIndexBy(foundRange.location + 1)
return subString.substringToIndex(foundRange.location)
}
mutating func readUntilEnd() -> String {
return read(currentIndex.distanceTo(message.endIndex))
}
}