diff options
| author | Dustin Mierau <dustin@mierau.me> | 2023-12-06 22:52:09 -0800 |
|---|---|---|
| committer | Dustin Mierau <dustin@mierau.me> | 2023-12-06 22:52:09 -0800 |
| commit | e3392bb948ad53889ad334140952f2acf614668e (patch) | |
| tree | 74937a9202b3bb71f28ef9d8e0b3560bdd195b49 /Hotline/Utility/FoundationExtensions.swift | |
| parent | 195af38221d1a4358455ba8501b87e4098da101b (diff) | |
Some work on news. More UI tweaks across the board.
Diffstat (limited to 'Hotline/Utility/FoundationExtensions.swift')
| -rw-r--r-- | Hotline/Utility/FoundationExtensions.swift | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/Hotline/Utility/FoundationExtensions.swift b/Hotline/Utility/FoundationExtensions.swift new file mode 100644 index 0000000..c6ca251 --- /dev/null +++ b/Hotline/Utility/FoundationExtensions.swift @@ -0,0 +1,96 @@ +import Foundation + +enum Endianness { + case big + case little +} + +extension Data { + init(_ val: UInt8) { + self.init() + self.appendUInt8(val) + } + + init(_ val: UInt16) { + self.init() + self.appendUInt16(val) + } + + init(_ val: UInt32) { + self.init() + self.appendUInt32(val) + } + + func readUInt8(at offset: Int) -> UInt8? { + guard offset >= 0, offset + 1 <= self.count else { + return nil + } + return self[offset] + } + + func readUInt16(at offset: Int) -> UInt16? { + guard offset >= 0, offset + 2 <= self.count else { + return nil + } + + return (UInt16(self[offset]) << 8) + UInt16(self[offset + 1]) + } + + func readUInt32(at offset: Int) -> UInt32? { + guard offset >= 0, offset + 4 <= self.count else { + return nil + } + + return (UInt32(self[offset]) << 24) + (UInt32(self[offset + 1]) << 16) + (UInt32(self[offset + 2]) << 8) + UInt32(self[offset + 3]) + } + + func readData(at offset: Int, length: Int) -> Data? { + guard offset >= 0, offset + length <= self.count else { + return nil + } + return self.subdata(in: offset..<(offset + length)) + } + + func readString(at offset: Int, length: Int) -> String? { + var str: String? + + str = String(data: self[offset..<(offset + length)], encoding: .utf8) + if str == nil { + str = String(data: self[offset..<(offset + length)], encoding: .ascii) + } + + return str + } + + func readPString(at offset: Int) -> (String?, Int) { + let len = Int(self.readUInt8(at: offset)!) + return (self.readString(at: offset+1, length: len), 1 + len) + } + + func readLongPString(at offset: Int) -> (String?, Int) { + let len = Int(self.readUInt16(at: offset)!) + return (self.readString(at: offset+2, length: len), 2 + len) + } + + + mutating func appendUInt8(_ value: UInt8, endianness: Endianness = .big) { + var val = endianness == .big ? value.bigEndian : value.littleEndian + append(&val, count: MemoryLayout<UInt8>.size) + } + + mutating func appendUInt16(_ value: UInt16, endianness: Endianness = .big) { + var val = endianness == .big ? value.bigEndian : value.littleEndian + Swift.withUnsafeBytes(of: &val) { buffer in + append(buffer.bindMemory(to: UInt8.self)) + } +// append(&val, count: MemoryLayout<UInt16>.size) + } + + mutating func appendUInt32(_ value: UInt32, endianness: Endianness = .big) { + var val = endianness == .big ? value.bigEndian : value.littleEndian + Swift.withUnsafeBytes(of: &val) { buffer in + append(buffer.bindMemory(to: UInt8.self)) + } +// append(&val, count: MemoryLayout<UInt32>.size) + } +} |