aboutsummaryrefslogtreecommitdiff
path: root/Hotline
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2025-11-07 11:35:59 -0800
committerDustin Mierau <dustin@mierau.me>2025-11-07 11:35:59 -0800
commit786a387d58fc66ae20716a9dee46b74dff8e6894 (patch)
tree83d0cd183b71ef432bf5e06d7bf77e9245322cdf /Hotline
parent39f51fd902bb34272c78ffdfb872c22095382f70 (diff)
Rename NetSocketNew as NetSocket (old CFStream based NetSocket is gone!)
Diffstat (limited to 'Hotline')
-rw-r--r--Hotline/Hotline/HotlineClientNew.swift6
-rw-r--r--Hotline/Hotline/HotlineExtensions.swift4
-rw-r--r--Hotline/Hotline/HotlineProtocol.swift6
-rw-r--r--Hotline/Hotline/HotlineTrackerClient.swift2
-rw-r--r--Hotline/Hotline/Transfers/HotlineFileDownloadClientNew.swift8
-rw-r--r--Hotline/Hotline/Transfers/HotlineFilePreviewClientNew.swift2
-rw-r--r--Hotline/Hotline/Transfers/HotlineFileUploadClientNew.swift6
-rw-r--r--Hotline/Hotline/Transfers/HotlineFolderDownloadClientNew.swift12
-rw-r--r--Hotline/Hotline/Transfers/HotlineFolderUploadClientNew.swift10
-rw-r--r--Hotline/Library/NetSocket/FileProgress.swift2
-rw-r--r--Hotline/Library/NetSocket/NetSocketNew.swift38
-rw-r--r--Hotline/Library/NetSocket/TransferRateEstimator.swift8
-rw-r--r--Hotline/macOS/ServerView.swift1
13 files changed, 52 insertions, 53 deletions
diff --git a/Hotline/Hotline/HotlineClientNew.swift b/Hotline/Hotline/HotlineClientNew.swift
index 9e60b5e..8642d42 100644
--- a/Hotline/Hotline/HotlineClientNew.swift
+++ b/Hotline/Hotline/HotlineClientNew.swift
@@ -126,7 +126,7 @@ public struct HotlineServerInfo: Sendable {
public actor HotlineClientNew {
// MARK: - Properties
- private let socket: NetSocketNew
+ private let socket: NetSocket
private var serverInfo: HotlineServerInfo?
private var isConnected: Bool = true
@@ -188,7 +188,7 @@ public actor HotlineClientNew {
// Connect socket
print("HotlineClientNew.connect(): Connecting socket...")
- let socket = try await NetSocketNew.connect(host: host, port: port, tls: tls)
+ let socket = try await NetSocket.connect(host: host, port: port, tls: tls)
print("HotlineClientNew.connect(): Socket connected")
// Perform handshake
@@ -240,7 +240,7 @@ public actor HotlineClientNew {
return client
}
- private init(socket: NetSocketNew) {
+ private init(socket: NetSocket) {
self.socket = socket
// Set up event stream
diff --git a/Hotline/Hotline/HotlineExtensions.swift b/Hotline/Hotline/HotlineExtensions.swift
index 16e9583..049ebf9 100644
--- a/Hotline/Hotline/HotlineExtensions.swift
+++ b/Hotline/Hotline/HotlineExtensions.swift
@@ -1107,7 +1107,7 @@ extension FourCharCode {
}
-extension NetSocketNew {
+extension NetSocket {
/// Read a pascal string (1-byte length prefix followed by string data)
///
/// This method reads a single byte for the length, then reads that many bytes and attempts
@@ -1145,7 +1145,7 @@ extension NetSocketNew {
// Fallback to MacRoman for classic Mac compatibility
guard let str = String(data: data, encoding: .macOSRoman) else {
throw NetSocketError.decodeFailed(NSError(
- domain: "NetSocketNew",
+ domain: "NetSocket",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "Failed to decode pascal string with any known encoding"]
))
diff --git a/Hotline/Hotline/HotlineProtocol.swift b/Hotline/Hotline/HotlineProtocol.swift
index 43f018e..927cf69 100644
--- a/Hotline/Hotline/HotlineProtocol.swift
+++ b/Hotline/Hotline/HotlineProtocol.swift
@@ -188,7 +188,7 @@ struct HotlineServer: Identifiable, Hashable, NetSocketDecodable {
hasher.combine(self.id)
}
- init(from socket: NetSocketNew, endian: Endian) async throws {
+ init(from socket: NetSocket, endian: Endian) async throws {
// Read IP address (4 individual bytes)
let ip1 = try await socket.read(UInt8.self)
let ip2 = try await socket.read(UInt8.self)
@@ -986,7 +986,7 @@ extension HotlineTransaction: NetSocketDecodable {
/// Decode a Hotline transaction directly from the socket stream
///
/// Reads the 20-byte header, then reads and decodes the variable-length body with fields.
- init(from socket: NetSocketNew, endian: Endian) async throws {
+ init(from socket: NetSocket, endian: Endian) async throws {
// Read 20-byte header
let flags = try await socket.read(UInt8.self)
let isReply = try await socket.read(UInt8.self)
@@ -1173,7 +1173,7 @@ enum HotlineTransactionType: UInt16 {
// /// - Unused: 2 bytes
// /// - Server name: Pascal string (1-byte length + data)
// /// - Server description: Pascal string (1-byte length + data)
-// init(from socket: NetSocketNew, endian: Endian) async throws {
+// init(from socket: NetSocket, endian: Endian) async throws {
// // Read IP address (4 individual bytes)
// let ip1 = try await socket.read(UInt8.self)
// let ip2 = try await socket.read(UInt8.self)
diff --git a/Hotline/Hotline/HotlineTrackerClient.swift b/Hotline/Hotline/HotlineTrackerClient.swift
index 52d34c1..f72735d 100644
--- a/Hotline/Hotline/HotlineTrackerClient.swift
+++ b/Hotline/Hotline/HotlineTrackerClient.swift
@@ -72,7 +72,7 @@ class HotlineTrackerClient {
private func doFetch(address: String, port: Int, continuation: AsyncThrowingStream<HotlineServer, Error>.Continuation) async throws {
// Connect to tracker (plaintext, no TLS)
- let socket = try await NetSocketNew.connect(
+ let socket = try await NetSocket.connect(
host: address,
port: UInt16(port),
tls: .disabled
diff --git a/Hotline/Hotline/Transfers/HotlineFileDownloadClientNew.swift b/Hotline/Hotline/Transfers/HotlineFileDownloadClientNew.swift
index ced79a1..77d2e38 100644
--- a/Hotline/Hotline/Transfers/HotlineFileDownloadClientNew.swift
+++ b/Hotline/Hotline/Transfers/HotlineFileDownloadClientNew.swift
@@ -39,7 +39,7 @@ public class HotlineFileDownloadClientNew {
private let transferTotal: Int
private var transferProgress: Progress
- private var socket: NetSocketNew?
+ private var socket: NetSocket?
private var downloadTask: Task<URL, Error>?
// MARK: - Initialization
@@ -251,14 +251,14 @@ public class HotlineFileDownloadClientNew {
// MARK: - Helper Methods
- private func connectToTransferServer() async throws -> NetSocketNew {
+ private func connectToTransferServer() async throws -> NetSocket {
guard let transferPort = NWEndpoint.Port(rawValue: serverPort + 1) else {
throw NetSocketError.invalidPort
}
print("HotlineFileDownloadClientNew[\(referenceNumber)]: Connecting to \(serverAddress):\(serverPort + 1)")
- let socket = try await NetSocketNew.connect(
+ let socket = try await NetSocket.connect(
host: .name(serverAddress, nil),
port: transferPort,
tls: .disabled
@@ -268,7 +268,7 @@ public class HotlineFileDownloadClientNew {
return socket
}
- private func sendMagicHeader(socket: NetSocketNew) async throws {
+ private func sendMagicHeader(socket: NetSocket) async throws {
let header = Data(endian: .big) {
"HTXF".fourCharCode()
referenceNumber
diff --git a/Hotline/Hotline/Transfers/HotlineFilePreviewClientNew.swift b/Hotline/Hotline/Transfers/HotlineFilePreviewClientNew.swift
index 9839997..63fe099 100644
--- a/Hotline/Hotline/Transfers/HotlineFilePreviewClientNew.swift
+++ b/Hotline/Hotline/Transfers/HotlineFilePreviewClientNew.swift
@@ -101,7 +101,7 @@ public class HotlineFilePreviewClientNew {
print("HotlineFilePreviewClientNew[\(referenceNumber)]: Connecting to \(serverAddress):\(serverPort + 1)")
- let socket = try await NetSocketNew.connect(
+ let socket = try await NetSocket.connect(
host: .name(serverAddress, nil),
port: transferPort,
tls: .disabled
diff --git a/Hotline/Hotline/Transfers/HotlineFileUploadClientNew.swift b/Hotline/Hotline/Transfers/HotlineFileUploadClientNew.swift
index 10934e7..5acff2a 100644
--- a/Hotline/Hotline/Transfers/HotlineFileUploadClientNew.swift
+++ b/Hotline/Hotline/Transfers/HotlineFileUploadClientNew.swift
@@ -24,7 +24,7 @@ public class HotlineFileUploadClientNew {
private let transferTotal: Int
private var transferProgress: Progress
- private var socket: NetSocketNew?
+ private var socket: NetSocket?
private var uploadTask: Task<Void, Error>?
// MARK: - Initialization
@@ -236,14 +236,14 @@ public class HotlineFileUploadClientNew {
// MARK: - Helper Methods
- private func connectToTransferServer() async throws -> NetSocketNew {
+ private func connectToTransferServer() async throws -> NetSocket {
guard let transferPort = NWEndpoint.Port(rawValue: serverPort + 1) else {
throw NetSocketError.invalidPort
}
print("HotlineFileUploadClientNew[\(referenceNumber)]: Connecting to \(serverAddress):\(serverPort + 1)")
- let socket = try await NetSocketNew.connect(
+ let socket = try await NetSocket.connect(
host: .name(serverAddress, nil),
port: transferPort,
tls: .disabled
diff --git a/Hotline/Hotline/Transfers/HotlineFolderDownloadClientNew.swift b/Hotline/Hotline/Transfers/HotlineFolderDownloadClientNew.swift
index 4ad35e7..254a1c6 100644
--- a/Hotline/Hotline/Transfers/HotlineFolderDownloadClientNew.swift
+++ b/Hotline/Hotline/Transfers/HotlineFolderDownloadClientNew.swift
@@ -20,7 +20,7 @@ public class HotlineFolderDownloadClientNew {
private let folderItemCount: Int
private var transferSize: Int = 0
- private var socket: NetSocketNew?
+ private var socket: NetSocket?
private var downloadTask: Task<URL, Error>?
private var folderProgress: Progress?
@@ -245,14 +245,14 @@ public class HotlineFolderDownloadClientNew {
// MARK: - Helper Methods
- private func connectToTransferServer() async throws -> NetSocketNew {
+ private func connectToTransferServer() async throws -> NetSocket {
guard let transferPort = NWEndpoint.Port(rawValue: serverPort + 1) else {
throw NetSocketError.invalidPort
}
print("HotlineFolderDownloadClientNew[\(referenceNumber)]: Connecting to \(serverAddress):\(serverPort + 1)")
- let socket = try await NetSocketNew.connect(
+ let socket = try await NetSocket.connect(
host: .name(serverAddress, nil),
port: transferPort,
tls: .disabled
@@ -262,7 +262,7 @@ public class HotlineFolderDownloadClientNew {
return socket
}
- private func sendAction(socket: NetSocketNew, action: HotlineFolderAction) async throws {
+ private func sendAction(socket: NetSocket, action: HotlineFolderAction) async throws {
let actionData = Data(endian: .big) {
action.rawValue
}
@@ -297,7 +297,7 @@ public class HotlineFolderDownloadClientNew {
}
private func downloadFile(
- socket: NetSocketNew,
+ socket: NetSocket,
fileName: String,
parentPath: [String],
destinationFolder: URL,
@@ -383,7 +383,7 @@ public class HotlineFolderDownloadClientNew {
fileDataForkSize = Int(forkHeader.dataSize)
- // Stream data fork using NetSocketNew's optimized file streaming
+ // Stream data fork using NetSocket's optimized file streaming
let updates = await socket.receiveFile(to: fh, length: fileDataForkSize)
for try await p in updates {
// Calculate overall folder progress
diff --git a/Hotline/Hotline/Transfers/HotlineFolderUploadClientNew.swift b/Hotline/Hotline/Transfers/HotlineFolderUploadClientNew.swift
index 2efced2..38532f1 100644
--- a/Hotline/Hotline/Transfers/HotlineFolderUploadClientNew.swift
+++ b/Hotline/Hotline/Transfers/HotlineFolderUploadClientNew.swift
@@ -38,7 +38,7 @@ public class HotlineFolderUploadClientNew {
private var folderItems: [FolderItem] = []
private var totalItems: Int = 0
- private var socket: NetSocketNew?
+ private var socket: NetSocket?
private var uploadTask: Task<Void, Error>?
// MARK: - Initialization
@@ -281,12 +281,12 @@ public class HotlineFolderUploadClientNew {
progressHandler?(.completed(url: nil))
}
- private func connect(address: String, port: UInt16) async throws -> NetSocketNew {
+ private func connect(address: String, port: UInt16) async throws -> NetSocket {
guard let transferPort = NWEndpoint.Port(rawValue: port + 1) else {
throw NetSocketError.invalidPort
}
- return try await NetSocketNew.connect(
+ return try await NetSocket.connect(
host: .name(address, nil),
port: transferPort,
tls: .disabled
@@ -361,7 +361,7 @@ public class HotlineFolderUploadClientNew {
}
}
- private func readAction(socket: NetSocketNew) async throws -> HotlineFolderAction {
+ private func readAction(socket: NetSocket) async throws -> HotlineFolderAction {
let actionData = try await socket.read(2)
guard let rawAction = actionData.readUInt16(at: 0),
let action = HotlineFolderAction(rawValue: rawAction) else {
@@ -371,7 +371,7 @@ public class HotlineFolderUploadClientNew {
}
private func uploadFile(
- socket: NetSocketNew,
+ socket: NetSocket,
fileURL: URL,
itemNumber: Int,
totalItems: Int,
diff --git a/Hotline/Library/NetSocket/FileProgress.swift b/Hotline/Library/NetSocket/FileProgress.swift
index c086af7..1cc0228 100644
--- a/Hotline/Library/NetSocket/FileProgress.swift
+++ b/Hotline/Library/NetSocket/FileProgress.swift
@@ -4,7 +4,7 @@
import Foundation
-public extension NetSocketNew {
+public extension NetSocket {
/// Progress information for file uploads/downloads
struct FileProgress: Sendable {
diff --git a/Hotline/Library/NetSocket/NetSocketNew.swift b/Hotline/Library/NetSocket/NetSocketNew.swift
index 7b24b37..12f4271 100644
--- a/Hotline/Library/NetSocket/NetSocketNew.swift
+++ b/Hotline/Library/NetSocket/NetSocketNew.swift
@@ -1,4 +1,4 @@
-// NetSocketNew.swift
+// NetSocket.swift
// Dustin Mierau • @mierau
import Foundation
@@ -86,11 +86,9 @@ public enum NetSocketError: Error, CustomStringConvertible, Sendable {
}
}
-// MARK: - NetSocketNew
-
/// An async/await TCP socket with automatic buffering and framing support
///
-/// NetSocketNew provides:
+/// NetSocket provides:
/// - Async connection management
/// - Automatic receive buffering with memory compaction
/// - Type-safe reading/writing of integers, strings, and custom types
@@ -98,11 +96,11 @@ public enum NetSocketError: Error, CustomStringConvertible, Sendable {
///
/// Example usage:
/// ```swift
-/// let socket = try await NetSocketNew.connect(host: "example.com", port: 80)
+/// let socket = try await NetSocket.connect(host: "example.com", port: 80)
/// try await socket.write("Hello\n".data(using: .utf8)!)
/// let response = try await socket.readUntil(delimiter: .lineFeed)
/// ```
-public actor NetSocketNew {
+public actor NetSocket {
/// Configuration options for the socket
public struct Config: Sendable {
/// Size of chunks to receive from network at once (default: 64 KB)
@@ -153,9 +151,9 @@ public actor NetSocketNew {
/// - port: Network framework port
/// - tls: TLS policy (default: enabled with default settings)
/// - config: Socket configuration (default: standard settings)
- /// - Returns: A connected and ready `NetSocketNew`
+ /// - Returns: A connected and ready `NetSocket`
/// - Throws: Network errors or connection failures
- public static func connect(host: NWEndpoint.Host, port: NWEndpoint.Port, tls: TLSPolicy = .enabled(), config: Config = .init()) async throws -> NetSocketNew {
+ public static func connect(host: NWEndpoint.Host, port: NWEndpoint.Port, tls: TLSPolicy = .enabled(), config: Config = .init()) async throws -> NetSocket {
let parameters = NWParameters.tcp
if tls.enabled {
let tlsOptions = NWProtocolTLS.Options()
@@ -164,13 +162,13 @@ public actor NetSocketNew {
}
let conn = NWConnection(host: host, port: port, using: parameters)
- let socket = NetSocketNew(connection: conn, config: config)
+ let socket = NetSocket(connection: conn, config: config)
try await socket.start()
return socket
}
/// Convenience wrapper to connect using string hostname and integer port
- public static func connect(host: String, port: UInt16, tls: TLSPolicy = .enabled(), config: Config = .init()) async throws -> NetSocketNew {
+ public static func connect(host: String, port: UInt16, tls: TLSPolicy = .enabled(), config: Config = .init()) async throws -> NetSocket {
guard let nwPort = NWEndpoint.Port(rawValue: port) else {
throw NetSocketError.invalidPort
}
@@ -506,7 +504,7 @@ public actor NetSocketNew {
// 1. Open file and get length (blocking I/O, done off-actor)
do {
- total = Int(try NetSocketNew.fileLength(at: url))
+ total = Int(try NetSocket.fileLength(at: url))
fh = try FileHandle(forReadingFrom: url)
} catch {
continuation.finish(throwing: NetSocketError.failed(underlying: error))
@@ -792,11 +790,11 @@ public actor NetSocketNew {
}
private func startReceiveLoop() {
- @Sendable func loop(_ connection: NWConnection, chunk: Int, owner: NetSocketNew, connID: String) {
- print("NetSocketNew[\(connID)]: Calling connection.receive(\(chunk)) to request more data...")
+ @Sendable func loop(_ connection: NWConnection, chunk: Int, owner: NetSocket, connID: String) {
+ print("NetSocket[\(connID)]: Calling connection.receive(\(chunk)) to request more data...")
connection.receive(minimumIncompleteLength: 1, maximumLength: chunk) { [weak owner] data, _, isComplete, error in
- print("NetSocketNew[\(connID)]: Receive callback - data: \(data?.count ?? 0) bytes, isComplete: \(isComplete), error: \(String(describing: error))")
+ print("NetSocket[\(connID)]: Receive callback - data: \(data?.count ?? 0) bytes, isComplete: \(isComplete), error: \(String(describing: error))")
Task {
guard let o = owner else {
return
@@ -810,7 +808,7 @@ public actor NetSocketNew {
await o.append(data, connID: connID)
}
if isComplete {
- print("NetSocketNew[\(connID)]: EOF from peer.")
+ print("NetSocket[\(connID)]: EOF from peer.")
await o.handleEOF()
return
}
@@ -952,7 +950,7 @@ public actor NetSocketNew {
}
private func append(_ data: Data, connID: String) {
- print("NetSocketNew[\(connID)]: Received \(data.count) bytes from network, buffer now has \(buffer.count - head + data.count) available")
+ print("NetSocket[\(connID)]: Received \(data.count) bytes from network, buffer now has \(buffer.count - head + data.count) available")
buffer.append(data)
if buffer.count - head > config.maxBufferBytes {
// Hard stop: drop connection rather than OOM'ing.
@@ -1038,7 +1036,7 @@ public protocol NetSocketEncodable: Sendable {
/// let id: UInt32
/// let name: String
///
-/// init(from socket: NetSocketNew, endian: Endian) async throws {
+/// init(from socket: NetSocket, endian: Endian) async throws {
/// self.id = try await socket.read(UInt32.self, endian: endian)
/// let nameLen = try await socket.read(UInt16.self, endian: endian)
/// let nameData = try await socket.readExactly(Int(nameLen))
@@ -1064,10 +1062,10 @@ public protocol NetSocketDecodable: Sendable {
/// - socket: Socket to read from
/// - endian: Byte order for multi-byte values
/// - Throws: Network errors, insufficient data, or custom decoding errors
- init(from socket: NetSocketNew, endian: Endian) async throws
+ init(from socket: NetSocket, endian: Endian) async throws
}
-public extension NetSocketNew {
+public extension NetSocket {
/// Send an encodable value to the socket
///
/// The type encodes itself to binary data, which is then sent in a single write operation.
@@ -1109,7 +1107,7 @@ public extension NetSocketNew {
/// let id: UInt32
/// let name: String
///
- /// init(from socket: NetSocketNew, endian: Endian) async throws {
+ /// init(from socket: NetSocket, endian: Endian) async throws {
/// self.id = try await socket.read(UInt32.self, endian: endian)
/// // Read variable-length string...
/// }
diff --git a/Hotline/Library/NetSocket/TransferRateEstimator.swift b/Hotline/Library/NetSocket/TransferRateEstimator.swift
index 7d16904..60647a7 100644
--- a/Hotline/Library/NetSocket/TransferRateEstimator.swift
+++ b/Hotline/Library/NetSocket/TransferRateEstimator.swift
@@ -70,7 +70,7 @@ public struct TransferRateEstimator {
self.minSamples = minSamples
}
- public mutating func update(total: Int) -> NetSocketNew.FileProgress {
+ public mutating func update(total: Int) -> NetSocket.FileProgress {
return self.update(bytes: max(0, total - self.transferred))
}
@@ -80,7 +80,7 @@ public struct TransferRateEstimator {
///
/// - Parameter bytes: Number of bytes transferred in this sample
/// - Returns: Current progress with speed and ETA estimates
- public mutating func update(bytes: Int) -> NetSocketNew.FileProgress {
+ public mutating func update(bytes: Int) -> NetSocket.FileProgress {
let clock = ContinuousClock()
let now = clock.now
@@ -102,7 +102,7 @@ public struct TransferRateEstimator {
let instantRate = Double(bytes) / seconds
self.sampleCount += 1
- // Update EMA
+ // Update EMANetSocket
if self.emaBytesPerSecond == 0 {
self.emaBytesPerSecond = instantRate
} else {
@@ -124,7 +124,7 @@ public struct TransferRateEstimator {
eta = nil
}
- return NetSocketNew.FileProgress(
+ return NetSocket.FileProgress(
sent: self.transferred,
total: self.total,
bytesPerSecond: haveEstimate ? self.emaBytesPerSecond : nil,
diff --git a/Hotline/macOS/ServerView.swift b/Hotline/macOS/ServerView.swift
index df3e54b..a66a071 100644
--- a/Hotline/macOS/ServerView.swift
+++ b/Hotline/macOS/ServerView.swift
@@ -135,6 +135,7 @@ struct ServerView: View {
Text(error)
.font(.caption)
.foregroundStyle(.secondary)
+ .multilineTextAlignment(.center)
}
.frame(maxWidth: 300)
.padding()