Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend reading with delay and retry. #201

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 45 additions & 20 deletions Sources/Socket/Socket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2682,16 +2682,21 @@ public class Socket: SocketReader, SocketWriter {
///
/// Read a string from the socket
///
/// In order to deal with slow connection, the function can retry a few times.
///
/// - Parameter retry: **UInt** the number of time to retry.
/// - Parameter wait: **UInt32** the time to wait in-between retry.
///
/// - Returns: String containing the data read from the socket.
///
public func readString() throws -> String? {
public func readString(retry: UInt = 0, wait: UInt32 = 0) throws -> String? {

guard let data = NSMutableData(capacity: 2000) else {

throw Error(code: Socket.SOCKET_ERR_INTERNAL, reason: "Unable to create temporary NSMutableData...")
}

let rc = try self.read(into: data)
let rc = try self.read(into: data, retry: retry, wait: wait)

guard let str = NSString(bytes: data.bytes, length: data.length, encoding: String.Encoding.utf8.rawValue),
rc > 0 else {
Expand All @@ -2707,10 +2712,12 @@ public class Socket: SocketReader, SocketWriter {
/// Read data from the socket.
///
/// - Parameter data: The buffer to return the data in.
/// - Parameter retry: **UInt** the number of time to retry.
/// - Parameter wait: **UInt32** the time to wait in-between retry.
///
/// - Returns: The number of bytes returned in the buffer.
///
public func read(into data: NSMutableData) throws -> Int {
public func read(into data: NSMutableData, retry: UInt = 0, wait: UInt32 = 0) throws -> Int {

// The socket must've been created and must be connected...
if self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {
Expand All @@ -2723,19 +2730,27 @@ public class Socket: SocketReader, SocketWriter {
throw Error(code: Socket.SOCKET_ERR_NOT_CONNECTED, reason: "Socket is not connected")
}

// Read all available bytes...
let count = try self.readDataIntoStorage()

// Did we get data?
var returnCount: Int = 0
if count > 0 {
var i: UInt = 0
while i <= retry {
// Read all available bytes...
let count = try self.readDataIntoStorage()

data.append(self.readStorage.bytes, length: self.readStorage.length)

returnCount = self.readStorage.length
// Did we get data?
if count > 0 {

// - Reset the storage buffer...
self.readStorage.length = 0
data.append(self.readStorage.bytes, length: self.readStorage.length)

returnCount += self.readStorage.length

// - Reset the storage buffer...
self.readStorage.length = 0

break
} else {
i += 1
usleep(wait)
}
}

return returnCount
Expand All @@ -2745,10 +2760,12 @@ public class Socket: SocketReader, SocketWriter {
/// Read data from the socket.
///
/// - Parameter data: The buffer to return the data in.
/// - Parameter retry: **UInt** the number of time to retry.
/// - Parameter wait: **UInt32** the time to wait in-between retry.
///
/// - Returns: The number of bytes returned in the buffer.
///
public func read(into data: inout Data) throws -> Int {
public func read(into data: inout Data, retry: UInt = 0, wait: UInt32 = 0) throws -> Int {

// The socket must've been created and must be connected...
if self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {
Expand All @@ -2766,15 +2783,23 @@ public class Socket: SocketReader, SocketWriter {

// Did we get data?
var returnCount: Int = 0
if count > 0 {
var i: UInt = 0
while i <= retry {
if count > 0 {

// - Yes, move to caller's buffer...
data.append(self.readStorage.bytes.assumingMemoryBound(to: UInt8.self), count: self.readStorage.length)
// - Yes, move to caller's buffer...
data.append(self.readStorage.bytes.assumingMemoryBound(to: UInt8.self), count: self.readStorage.length)

returnCount = self.readStorage.length
returnCount = self.readStorage.length

// - Reset the storage buffer...
self.readStorage.length = 0
// - Reset the storage buffer...
self.readStorage.length = 0

break
} else {
i += 1
usleep(wait)
}
}

return returnCount
Expand Down
15 changes: 12 additions & 3 deletions Sources/Socket/SocketProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,36 @@ public protocol SocketReader {
///
/// Reads a string.
///
/// In order to deal with slow connection, the function can retry a few times.
///
/// - Parameter retry: **UInt** the number of time to retry.
/// - Parameter wait: **UInt32** the time to wait in-between retry.
///
/// - Returns: Optional **String**
///
func readString() throws -> String?
func readString(retry: UInt, wait: UInt32) throws -> String?

///
/// Reads all available data into an Data object.
///
/// - Parameter data: **Data** object to contain read data.
/// - Parameter retry: **UInt** the number of time to retry.
/// - Parameter wait: **UInt32** the time to wait in-between retry.
///
/// - Returns: Integer representing the number of bytes read.
///
func read(into data: inout Data) throws -> Int
func read(into data: inout Data, retry: UInt, wait: UInt32) throws -> Int

///
/// Reads all available data into an **NSMutableData** object.
///
/// - Parameter data: **NSMutableData** object to contain read data.
/// - Parameter retry: **UInt** the number of time to retry.
/// - Parameter wait: **UInt32** the time to wait in-between retry.
///
/// - Returns: Integer representing the number of bytes read.
///
func read(into data: NSMutableData) throws -> Int
func read(into data: NSMutableData, retry: UInt, wait: UInt32) throws -> Int
}

// MARK: Writer
Expand Down