aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Utility/FoundationExtensions.swift
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2023-12-06 22:52:09 -0800
committerDustin Mierau <dustin@mierau.me>2023-12-06 22:52:09 -0800
commite3392bb948ad53889ad334140952f2acf614668e (patch)
tree74937a9202b3bb71f28ef9d8e0b3560bdd195b49 /Hotline/Utility/FoundationExtensions.swift
parent195af38221d1a4358455ba8501b87e4098da101b (diff)
Some work on news. More UI tweaks across the board.
Diffstat (limited to 'Hotline/Utility/FoundationExtensions.swift')
-rw-r--r--Hotline/Utility/FoundationExtensions.swift96
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)
+ }
+}