even more xcode 8 stuff. style changes

This commit is contained in:
Erik 2016-06-15 10:13:44 -04:00
parent 2adcf2d35d
commit 7c3de9f30a
14 changed files with 97 additions and 79 deletions

View File

@ -526,7 +526,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0730; LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0720; LastUpgradeCheck = 0800;
TargetAttributes = { TargetAttributes = {
572EF2181B51F16C00EEBB58 = { 572EF2181B51F16C00EEBB58 = {
CreatedOnToolsVersion = 6.4; CreatedOnToolsVersion = 6.4;
@ -799,10 +799,25 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
BITCODE_GENERATION_MODE = bitcode; BITCODE_GENERATION_MODE = bitcode;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_IDENTITY = "Developer ID Application";
ENABLE_BITCODE = YES; ENABLE_BITCODE = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10; MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
@ -817,8 +832,23 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
BITCODE_GENERATION_MODE = bitcode; BITCODE_GENERATION_MODE = bitcode;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_IDENTITY = "Developer ID Application";
ENABLE_BITCODE = YES; ENABLE_BITCODE = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10; MACOSX_DEPLOYMENT_TARGET = 10.10;
PRODUCT_NAME = SocketIOClientSwift; PRODUCT_NAME = SocketIOClientSwift;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0720" LastUpgradeVersion = "0800"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0720" LastUpgradeVersion = "0800"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0720" LastUpgradeVersion = "0800"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -41,7 +41,7 @@
} }
- (void)testOffSyntax { - (void)testOffSyntax {
[self.socket offWithEvent:@"test"]; [self.socket off:@"test"];
} }
- (void)testSocketManager { - (void)testSocketManager {

View File

@ -111,9 +111,9 @@ class SocketParserTest: XCTestCase {
func testGenericParser() { func testGenericParser() {
var parser = SocketStringReader(message: "61-/swift,") var parser = SocketStringReader(message: "61-/swift,")
XCTAssertEqual(parser.read(1), "6") XCTAssertEqual(parser.read(count: 1), "6")
XCTAssertEqual(parser.currentCharacter, "1") XCTAssertEqual(parser.currentCharacter, "1")
XCTAssertEqual(parser.readUntilStringOccurence("-"), "1") XCTAssertEqual(parser.readUntilOccurence(of: "-"), "1")
XCTAssertEqual(parser.currentCharacter, "/") XCTAssertEqual(parser.currentCharacter, "/")
} }

View File

@ -144,10 +144,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
2: Bad handshake request 2: Bad handshake request
3: Bad request 3: Bad request
*/ */
didError(error) didError(reason: error)
} }
} catch { } catch {
didError("Got unknown error from server \(msg)") didError(reason: "Got unknown error from server \(msg)")
} }
} }
@ -180,7 +180,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
public func connect() { public func connect() {
if connected { if connected {
DefaultSocketLogger.Logger.error("Engine tried opening while connected. Assuming this was a reconnect", type: logType) DefaultSocketLogger.Logger.error("Engine tried opening while connected. Assuming this was a reconnect", type: logType)
disconnect("reconnect") disconnect(reason: "reconnect")
} }
DefaultSocketLogger.Logger.log("Starting engine. Server: %@", type: logType, args: url) DefaultSocketLogger.Logger.log("Starting engine. Server: %@", type: logType, args: url)
@ -208,9 +208,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
} }
} }
(emitQueue).async { emitQueue.async { self.doLongPoll(for: reqPolling as URLRequest) }
self.doLongPoll(for: reqPolling as URLRequest)
}
} }
private func createURLs() -> (URL, URL) { private func createURLs() -> (URL, URL) {
@ -273,20 +271,20 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
ws?.connect() ws?.connect()
} }
public func didError(_ error: String) { public func didError(reason: String) {
DefaultSocketLogger.Logger.error("%@", type: logType, args: error) DefaultSocketLogger.Logger.error("%@", type: logType, args: reason)
client?.engineDidError(error) client?.engineDidError(reason: reason)
disconnect(error) disconnect(reason: reason)
} }
public func disconnect(_ reason: String) { public func disconnect(reason: String) {
guard connected else { return closeOutEngine() } guard connected else { return closeOutEngine() }
DefaultSocketLogger.Logger.log("Engine is being closed.", type: logType) DefaultSocketLogger.Logger.log("Engine is being closed.", type: logType)
if closed { if closed {
closeOutEngine() closeOutEngine()
client?.engineDidClose(reason) client?.engineDidClose(reason: reason)
return return
} }
@ -352,7 +350,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
} }
private func handleClose(_ reason: String) { private func handleClose(_ reason: String) {
client?.engineDidClose(reason) client?.engineDidClose(reason: reason)
} }
private func handleMessage(_ message: String) { private func handleMessage(_ message: String) {
@ -395,10 +393,10 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
doPoll() doPoll()
} }
client?.engineDidOpen("Connect") client?.engineDidOpen(reason: "Connect")
} }
} catch { } catch {
didError("Error parsing open packet") didError(reason: "Error parsing open packet")
} }
} }
@ -478,7 +476,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
//Server is not responding //Server is not responding
if pongsMissed > pongsMissedMax { if pongsMissed > pongsMissedMax {
client?.engineDidClose("Ping timeout") client?.engineDidClose(reason: "Ping timeout")
return return
} }
@ -487,9 +485,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
write("", withType: .ping, withData: []) write("", withType: .ping, withData: [])
let time = DispatchTime.now() + Double(Int64(pingInterval * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) let time = DispatchTime.now() + Double(Int64(pingInterval * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.after(when: time) {[weak self] in DispatchQueue.main.after(when: time) {[weak self] in self?.sendPing() }
self?.sendPing()
}
} }
} }
@ -539,7 +535,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
probing = false probing = false
if closed { if closed {
client?.engineDidClose("Disconnect") client?.engineDidClose(reason: "Disconnect")
return return
} }
@ -548,9 +544,9 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
websocket = false websocket = false
if let reason = error?.localizedDescription { if let reason = error?.localizedDescription {
didError(reason) didError(reason: reason)
} else { } else {
client?.engineDidClose("Socket Disconnected") client?.engineDidClose(reason: "Socket Disconnected")
} }
} else { } else {
flushProbeWait() flushProbeWait()

View File

@ -26,9 +26,9 @@
import Foundation import Foundation
@objc public protocol SocketEngineClient { @objc public protocol SocketEngineClient {
func engineDidError(_ reason: String) func engineDidError(reason: String)
func engineDidClose(_ reason: String) func engineDidClose(reason: String)
func engineDidOpen(_ reason: String) func engineDidOpen(reason: String)
func parseEngineMessage(_ msg: String) func parseEngineMessage(_ msg: String)
func parseEngineBinaryData(_ data: Data) func parseEngineBinaryData(_ data: Data)
} }

View File

@ -118,7 +118,7 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling") DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling")
if this.polling { if this.polling {
this.didError(err?.localizedDescription ?? "Error") this.didError(reason: err?.localizedDescription ?? "Error")
} }
return return
@ -163,7 +163,7 @@ extension SocketEnginePollable {
DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling") DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling")
if this.polling { if this.polling {
this.didError(err?.localizedDescription ?? "Error") this.didError(reason: err?.localizedDescription ?? "Error")
} }
return return
@ -186,16 +186,12 @@ extension SocketEnginePollable {
var reader = SocketStringReader(message: str) var reader = SocketStringReader(message: str)
while reader.hasNext { while reader.hasNext {
if let n = Int(reader.readUntilStringOccurence(":")) { if let n = Int(reader.readUntilOccurence(of: ":")) {
let str = reader.read(n) let str = reader.read(count: n)
(handleQueue).async { handleQueue.async { self.parseEngineMessage(str, fromPolling: true) }
self.parseEngineMessage(str, fromPolling: true)
}
} else { } else {
handleQueue.async { handleQueue.async { self.parseEngineMessage(str, fromPolling: true) }
self.parseEngineMessage(str, fromPolling: true)
}
break break
} }
} }

View File

@ -51,8 +51,8 @@ import Foundation
init(client: SocketEngineClient, url: URL, options: NSDictionary?) init(client: SocketEngineClient, url: URL, options: NSDictionary?)
func connect() func connect()
func didError(_ error: String) func didError(reason: String)
func disconnect(_ reason: String) func disconnect(reason: String)
func doFastUpgrade() func doFastUpgrade()
func flushWaitingForPostToWebSocket() func flushWaitingForPostToWebSocket()
func parseEngineData(_ data: Data) func parseEngineData(_ data: Data)

View File

@ -110,7 +110,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
deinit { deinit {
DefaultSocketLogger.Logger.log("Client is being released", type: logType) DefaultSocketLogger.Logger.log("Client is being released", type: logType)
engine?.disconnect("Client Deinit") engine?.disconnect(reason: "Client Deinit")
} }
private func addEngine() -> SocketEngineSpec { private func addEngine() -> SocketEngineSpec {
@ -150,7 +150,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
handleQueue.after(when: time) {[weak self] in handleQueue.after(when: time) {[weak self] in
if let this = self where this.status != .connected && this.status != .disconnected { if let this = self where this.status != .connected && this.status != .disconnected {
this.status = .disconnected this.status = .disconnected
this.engine?.disconnect("Connect timeout") this.engine?.disconnect(reason: "Connect timeout")
handler?() handler?()
} }
@ -185,7 +185,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
handleEvent("connect", data: [], isInternalMessage: false) handleEvent("connect", data: [], isInternalMessage: false)
} }
func didDisconnect(_ reason: String) { func didDisconnect(reason: String) {
guard status != .disconnected else { return } guard status != .disconnected else { return }
DefaultSocketLogger.Logger.log("Disconnected: %@", type: logType, args: reason) DefaultSocketLogger.Logger.log("Disconnected: %@", type: logType, args: reason)
@ -193,7 +193,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
status = .disconnected status = .disconnected
// Make sure the engine is actually dead. // Make sure the engine is actually dead.
engine?.disconnect(reason) engine?.disconnect(reason: reason)
handleEvent("disconnect", data: [reason as AnyObject], isInternalMessage: true) handleEvent("disconnect", data: [reason as AnyObject], isInternalMessage: true)
} }
@ -203,7 +203,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
DefaultSocketLogger.Logger.log("Closing socket", type: logType) DefaultSocketLogger.Logger.log("Closing socket", type: logType)
didDisconnect("Disconnect") didDisconnect(reason: "Disconnect")
} }
/// Send a message to the server /// Send a message to the server
@ -262,7 +262,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
} }
} }
public func engineDidClose(_ reason: String) { public func engineDidClose(reason: String) {
waitingPackets.removeAll() waitingPackets.removeAll()
if status != .disconnected { if status != .disconnected {
@ -270,7 +270,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
} }
if status == .disconnected || !reconnects { if status == .disconnected || !reconnects {
didDisconnect(reason) didDisconnect(reason: reason)
} else if !reconnecting { } else if !reconnecting {
reconnecting = true reconnecting = true
tryReconnect(reason) tryReconnect(reason)
@ -278,13 +278,13 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
} }
/// error /// error
public func engineDidError(_ reason: String) { public func engineDidError(reason: String) {
DefaultSocketLogger.Logger.error("%@", type: logType, args: reason) DefaultSocketLogger.Logger.error("%@", type: logType, args: reason)
handleEvent("error", data: [reason as AnyObject], isInternalMessage: true) handleEvent("error", data: [reason as AnyObject], isInternalMessage: true)
} }
public func engineDidOpen(_ reason: String) { public func engineDidOpen(reason: String) {
DefaultSocketLogger.Logger.log(reason, type: "SocketEngineClient") DefaultSocketLogger.Logger.log(reason, type: "SocketEngineClient")
} }
@ -383,22 +383,18 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
public func parseEngineMessage(_ msg: String) { public func parseEngineMessage(_ msg: String) {
DefaultSocketLogger.Logger.log("Should parse message: %@", type: "SocketIOClient", args: msg) DefaultSocketLogger.Logger.log("Should parse message: %@", type: "SocketIOClient", args: msg)
parseQueue.async { parseQueue.async { self.parseSocketMessage(msg) }
self.parseSocketMessage(msg)
}
} }
public func parseEngineBinaryData(_ data: Data) { public func parseEngineBinaryData(_ data: Data) {
parseQueue.async { parseQueue.async { self.parseBinaryData(data) }
self.parseBinaryData(data)
}
} }
/// Tries to reconnect to the server. /// Tries to reconnect to the server.
public func reconnect() { public func reconnect() {
guard !reconnecting else { return } guard !reconnecting else { return }
engine?.disconnect("manual reconnect") engine?.disconnect(reason: "manual reconnect")
} }
/// Removes all handlers. /// Removes all handlers.
@ -426,7 +422,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
} }
if reconnectAttempts != -1 && currentReconnectAttempt + 1 > reconnectAttempts || !reconnects { if reconnectAttempts != -1 && currentReconnectAttempt + 1 > reconnectAttempts || !reconnects {
return didDisconnect("Reconnect Failed") return didDisconnect(reason: "Reconnect Failed")
} }
DefaultSocketLogger.Logger.log("Trying to reconnect", type: logType) DefaultSocketLogger.Logger.log("Trying to reconnect", type: logType)

View File

@ -27,15 +27,15 @@ protocol SocketIOClientSpec : class {
var waitingPackets: [SocketPacket] { get set } var waitingPackets: [SocketPacket] { get set }
func didConnect() func didConnect()
func didDisconnect(_ reason: String) func didDisconnect(reason: String)
func didError(_ reason: String) func didError(reason: String)
func handleAck(_ ack: Int, data: [AnyObject]) func handleAck(_ ack: Int, data: [AnyObject])
func handleEvent(_ event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int) func handleEvent(_ event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int)
func joinNamespace(_ namespace: String) func joinNamespace(_ namespace: String)
} }
extension SocketIOClientSpec { extension SocketIOClientSpec {
func didError(_ reason: String) { func didError(reason: String) {
DefaultSocketLogger.Logger.error("%@", type: "SocketIOClient", args: reason) DefaultSocketLogger.Logger.error("%@", type: "SocketIOClient", args: reason)
handleEvent("error", data: [reason as AnyObject], isInternalMessage: true, withAck: -1) handleEvent("error", data: [reason as AnyObject], isInternalMessage: true, withAck: -1)

View File

@ -53,7 +53,7 @@ extension SocketParsable {
case .connect: case .connect:
handleConnect(pack) handleConnect(pack)
case .disconnect: case .disconnect:
didDisconnect("Got Disconnect") didDisconnect(reason: "Got Disconnect")
case .error: case .error:
handleEvent("error", data: pack.data, isInternalMessage: true, withAck: pack.id) handleEvent("error", data: pack.data, isInternalMessage: true, withAck: pack.id)
default: default:
@ -65,7 +65,7 @@ extension SocketParsable {
func parseString(_ message: String) -> Either<String, SocketPacket> { func parseString(_ message: String) -> Either<String, SocketPacket> {
var parser = SocketStringReader(message: message) var parser = SocketStringReader(message: message)
guard let type = SocketPacket.PacketType(rawValue: Int(parser.read(1)) ?? -1) else { guard let type = SocketPacket.PacketType(rawValue: Int(parser.read(count: 1)) ?? -1) else {
return .left("Invalid packet type") return .left("Invalid packet type")
} }
@ -77,7 +77,7 @@ extension SocketParsable {
var placeholders = -1 var placeholders = -1
if type == .binaryEvent || type == .binaryAck { if type == .binaryEvent || type == .binaryAck {
if let holders = Int(parser.readUntilStringOccurence("-")) { if let holders = Int(parser.readUntilOccurence(of: "-")) {
placeholders = holders placeholders = holders
} else { } else {
return .left("Invalid packet") return .left("Invalid packet")
@ -85,7 +85,7 @@ extension SocketParsable {
} }
if parser.currentCharacter == "/" { if parser.currentCharacter == "/" {
namespace = parser.readUntilStringOccurence(",") ?? parser.readUntilEnd() namespace = parser.readUntilOccurence(of: ",") ?? parser.readUntilEnd()
} }
if !parser.hasNext { if !parser.hasNext {
@ -95,19 +95,19 @@ extension SocketParsable {
var idString = "" var idString = ""
if type == .error { if type == .error {
parser.advance(-1) parser.advance(by: -1)
} else { } else {
while parser.hasNext { while parser.hasNext {
if let int = Int(parser.read(1)) { if let int = Int(parser.read(count: 1)) {
idString += String(int) idString += String(int)
} else { } else {
parser.advance(-2) parser.advance(by: -2)
break break
} }
} }
} }
let d = message[parser.advance(1)..<message.endIndex] let d = message[parser.advance(by: 1)..<message.endIndex]
switch parseData(d) { switch parseData(d) {
case let .left(err): case let .left(err):

View File

@ -39,20 +39,20 @@ struct SocketStringReader {
} }
@discardableResult @discardableResult
mutating func advance(_ by: Int) -> String.Index { mutating func advance(by: Int) -> String.Index {
currentIndex = message.characters.index(currentIndex, offsetBy: by) currentIndex = message.characters.index(currentIndex, offsetBy: by)
return currentIndex return currentIndex
} }
mutating func read(_ length: Int) -> String { mutating func read(count: Int) -> String {
let readString = message[currentIndex..<message.characters.index(currentIndex, offsetBy: length)] let readString = message[currentIndex..<message.characters.index(currentIndex, offsetBy: count)]
advance(length) advance(by: count)
return readString return readString
} }
mutating func readUntilStringOccurence(_ string: String) -> String { mutating func readUntilOccurence(of string: String) -> String {
let substring = message[currentIndex..<message.endIndex] let substring = message[currentIndex..<message.endIndex]
guard let foundRange = substring.range(of: string) else { guard let foundRange = substring.range(of: string) else {
currentIndex = message.endIndex currentIndex = message.endIndex
@ -60,12 +60,12 @@ struct SocketStringReader {
return substring return substring
} }
advance(message.characters.distance(from: message.characters.startIndex, to: foundRange.lowerBound) + 1) advance(by: message.characters.distance(from: message.characters.startIndex, to: foundRange.lowerBound) + 1)
return substring.substring(to: foundRange.lowerBound) return substring.substring(to: foundRange.lowerBound)
} }
mutating func readUntilEnd() -> String { mutating func readUntilEnd() -> String {
return read(message.characters.distance(from: currentIndex, to: message.endIndex)) return read(count: message.characters.distance(from: currentIndex, to: message.endIndex))
} }
} }