diff options
| author | Dustin Mierau <dustin@mierau.me> | 2025-11-07 11:35:59 -0800 |
|---|---|---|
| committer | Dustin Mierau <dustin@mierau.me> | 2025-11-07 11:35:59 -0800 |
| commit | 786a387d58fc66ae20716a9dee46b74dff8e6894 (patch) | |
| tree | 83d0cd183b71ef432bf5e06d7bf77e9245322cdf /Hotline | |
| parent | 39f51fd902bb34272c78ffdfb872c22095382f70 (diff) | |
Rename NetSocketNew as NetSocket (old CFStream based NetSocket is gone!)
Diffstat (limited to 'Hotline')
| -rw-r--r-- | Hotline/Hotline/HotlineClientNew.swift | 6 | ||||
| -rw-r--r-- | Hotline/Hotline/HotlineExtensions.swift | 4 | ||||
| -rw-r--r-- | Hotline/Hotline/HotlineProtocol.swift | 6 | ||||
| -rw-r--r-- | Hotline/Hotline/HotlineTrackerClient.swift | 2 | ||||
| -rw-r--r-- | Hotline/Hotline/Transfers/HotlineFileDownloadClientNew.swift | 8 | ||||
| -rw-r--r-- | Hotline/Hotline/Transfers/HotlineFilePreviewClientNew.swift | 2 | ||||
| -rw-r--r-- | Hotline/Hotline/Transfers/HotlineFileUploadClientNew.swift | 6 | ||||
| -rw-r--r-- | Hotline/Hotline/Transfers/HotlineFolderDownloadClientNew.swift | 12 | ||||
| -rw-r--r-- | Hotline/Hotline/Transfers/HotlineFolderUploadClientNew.swift | 10 | ||||
| -rw-r--r-- | Hotline/Library/NetSocket/FileProgress.swift | 2 | ||||
| -rw-r--r-- | Hotline/Library/NetSocket/NetSocketNew.swift | 38 | ||||
| -rw-r--r-- | Hotline/Library/NetSocket/TransferRateEstimator.swift | 8 | ||||
| -rw-r--r-- | Hotline/macOS/ServerView.swift | 1 |
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() |