52 lines
1.9 KiB
Swift
52 lines
1.9 KiB
Swift
import Foundation
|
|
|
|
public enum FrameCodec {
|
|
public static let maximumFrameSize = 1_200_000
|
|
|
|
public static func encode<T: Encodable>(_ value: T) throws -> Data {
|
|
let encoder = PropertyListEncoder(); encoder.outputFormat = .binary
|
|
let body = try encoder.encode(value)
|
|
guard body.count <= maximumFrameSize else { throw UMNError.invalidFrame }
|
|
var size = UInt32(body.count).bigEndian
|
|
return withUnsafeBytes(of: &size) { Data($0) } + body
|
|
}
|
|
|
|
public static func decode<T: Decodable>(_ type: T.Type, body: Data) throws -> T {
|
|
guard body.count <= maximumFrameSize else { throw UMNError.invalidFrame }
|
|
return try PropertyListDecoder().decode(type, from: body)
|
|
}
|
|
|
|
public static func bodyLength(from prefix: Data) throws -> Int {
|
|
guard prefix.count == 4 else { throw UMNError.invalidFrame }
|
|
let value = prefix.reduce(UInt32(0)) { ($0 << 8) | UInt32($1) }
|
|
guard value > 0, value <= maximumFrameSize else { throw UMNError.invalidFrame }
|
|
return Int(value)
|
|
}
|
|
}
|
|
|
|
public enum IPCOperation: String, Codable, Sendable {
|
|
case status, address, peers, routes, ping
|
|
case aliasSet, aliasRemove, aliasList
|
|
case firewallAllow, firewallRevoke, firewallList
|
|
case textSend, bindText, bindStream, openStream, streamData, streamClose
|
|
}
|
|
|
|
public struct IPCMessage: Codable, Sendable {
|
|
public var version: UInt16
|
|
public var operation: IPCOperation
|
|
public var requestID: UUID
|
|
public var target: String?
|
|
public var source: String?
|
|
public var name: String?
|
|
public var port: UInt16?
|
|
public var streamID: UInt64?
|
|
public var data: Data?
|
|
public var ok: Bool?
|
|
public var message: String?
|
|
public var values: [String]?
|
|
|
|
public init(operation: IPCOperation, requestID: UUID = UUID()) {
|
|
self.version = 1; self.operation = operation; self.requestID = requestID
|
|
}
|
|
}
|