diff --git a/Sources/SwiftRedis/RedisResp.swift b/Sources/SwiftRedis/RedisResp.swift index 9cdd9cf..5d3a76f 100644 --- a/Sources/SwiftRedis/RedisResp.swift +++ b/Sources/SwiftRedis/RedisResp.swift @@ -114,32 +114,30 @@ class RedisResp { private func parseByPrefix(_ buffer: inout Data, from: Int) throws -> (RedisResponse, Int) { var response: RedisResponse - var (matched, offset) = try compare(&buffer, at: from, with: RedisResp.plus) - if matched { - (response, offset) = try parseSimpleString(&buffer, offset: offset) - } else { - (matched, offset) = try compare(&buffer, at: from, with: RedisResp.colon) - if matched { - (response, offset) = try parseInteger(&buffer, offset: offset) - } else { - (matched, offset) = try compare(&buffer, at: from, with: RedisResp.dollar) - if matched { - (response, offset) = try parseBulkString(&buffer, offset: offset) - } else { - (matched, offset) = try compare(&buffer, at: from, with: RedisResp.asterisk) - if matched { - (response, offset) = try parseArray(&buffer, offset: offset) - } else { - (matched, offset) = try compare(&buffer, at: from, with: RedisResp.minus) - if matched { - (response, offset) = try parseError(&buffer, offset: offset) - } else { - response = RedisResponse.Error("Unknown response type") - } - } - } + var offset = from + + while offset+1 >= buffer.count { + let length = try socket?.read(into: &buffer) + + if length == 0 { + throw RedisRespError(code: .EOF) } } + + switch (buffer[offset.. (RedisResponse, Int) { - let eos = try find(&buffer, from: offset, data: RedisResp.crLf) - let data = buffer.subdata(in: offset.. (RedisResponse, Int) { - let eos = try find(&buffer, from: offset, data: RedisResp.crLf) - let data = buffer.subdata(in: offset.. (Bool, Int) { - while offset+with.count >= buffer.count { + while offset+with.count >= buffer.count { let length = try socket?.read(into: &buffer) if length == 0 { throw RedisRespError(code: .EOF) } } - let range = buffer.range(of: with, options: [], in: offset.. Int { var offset = from - var notFound = true - - while notFound { + + while true { let range = buffer.range(of: data, options: [], in: offset.. Int { + /* 5X faster than using find() above. range() is expensive */ + var i = from + while true { + while i < buffer.count - 1 { + if buffer[i+1] == 10{ + if buffer[i] == 13{ + return i + } else { + i+=2 + } + } else { + i+=1 + } + } + + let length = try socket?.read(into: &buffer) + if length == 0 { + throw RedisRespError(code: .EOF) + } + } + return from + } + + private func parseIntegerValue(_ buffer: inout Data, offset: Int) throws -> (Int64, Int) { - let eos = try find(&buffer, from: offset, data: RedisResp.crLf) - let data = buffer.subdata(in: offset..