2022-04-07 23:53:25 +02:00
|
|
|
import Foundation
|
|
|
|
import NIOCore
|
|
|
|
|
|
|
|
struct Message: Equatable, Hashable {
|
|
|
|
|
|
|
|
struct Content: Equatable, Hashable {
|
|
|
|
|
|
|
|
let time: UInt32
|
|
|
|
|
|
|
|
let id: UInt32
|
|
|
|
|
|
|
|
init(time: UInt32, id: UInt32) {
|
|
|
|
self.time = time
|
|
|
|
self.id = id
|
|
|
|
}
|
|
|
|
|
2022-04-08 13:33:09 +02:00
|
|
|
init<T: Sequence>(decodeFrom data: T) where T.Element == UInt8 {
|
|
|
|
self.time = UInt32(data: data.prefix(4))
|
|
|
|
self.id = UInt32(data: data.dropFirst(4))
|
2022-04-07 23:53:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static var length: Int {
|
|
|
|
MemoryLayout<UInt32>.size * 2
|
|
|
|
}
|
|
|
|
|
|
|
|
var encoded: Data {
|
|
|
|
time.encoded + id.encoded
|
|
|
|
}
|
|
|
|
|
|
|
|
var bytes: [UInt8] {
|
|
|
|
time.bytes + id.bytes
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mac: Data
|
|
|
|
|
|
|
|
let content: Content
|
|
|
|
|
|
|
|
init(mac: Data, content: Content) {
|
|
|
|
self.mac = mac
|
|
|
|
self.content = content
|
|
|
|
}
|
|
|
|
|
|
|
|
init?(decodeFrom buffer: ByteBuffer) {
|
2022-04-08 13:33:09 +02:00
|
|
|
guard let data = buffer.getBytes(at: 0, length: Message.length) else {
|
2022-04-07 23:53:25 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
self.init(decodeFrom: data)
|
|
|
|
}
|
|
|
|
|
|
|
|
var encoded: Data {
|
|
|
|
mac + content.encoded
|
|
|
|
}
|
|
|
|
|
|
|
|
var bytes: [UInt8] {
|
|
|
|
Array(mac) + content.bytes
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension UInt32 {
|
|
|
|
|
2022-04-08 13:33:09 +02:00
|
|
|
init<T: Sequence>(data: T) where T.Element == UInt8 {
|
2022-04-07 23:53:25 +02:00
|
|
|
self = data
|
|
|
|
.reversed()
|
|
|
|
.enumerated()
|
|
|
|
.map { UInt32($0.element) << ($0.offset * 8) }
|
|
|
|
.reduce(0, +)
|
|
|
|
}
|
|
|
|
|
|
|
|
var encoded: Data {
|
|
|
|
.init(bytes)
|
|
|
|
}
|
|
|
|
|
|
|
|
var bytes: [UInt8] {
|
|
|
|
(0..<4).reversed().map {
|
|
|
|
UInt8((self >> ($0*8)) & 0xFF)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|