aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Utility
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2023-11-27 12:39:11 -0800
committerDustin Mierau <dustin@mierau.me>2023-11-27 12:39:11 -0800
commitde5ee043826bce23906bfcb351a2702e1aa88270 (patch)
tree39c945bf3958d2e295a66596d1bac53ceb4c54d6 /Hotline/Utility
Getting started
Diffstat (limited to 'Hotline/Utility')
-rw-r--r--Hotline/Utility/DataExtensions.swift54
1 files changed, 54 insertions, 0 deletions
diff --git a/Hotline/Utility/DataExtensions.swift b/Hotline/Utility/DataExtensions.swift
new file mode 100644
index 0000000..9530416
--- /dev/null
+++ b/Hotline/Utility/DataExtensions.swift
@@ -0,0 +1,54 @@
+import Foundation
+
+enum Endianness {
+ case big
+ case little
+}
+
+extension Data {
+ func readUInt8(at offset: Int) -> UInt8? {
+ guard offset >= 0, offset + MemoryLayout<UInt8>.size <= self.count else {
+ return nil
+ }
+ return self[offset]
+ }
+
+ func readUInt16(at offset: Int, endianness: Endianness = .big) -> UInt16? {
+ guard offset >= 0, offset + MemoryLayout<UInt16>.size <= self.count else {
+ return nil
+ }
+ let value = self.subdata(in: offset..<(offset + MemoryLayout<UInt16>.size)).withUnsafeBytes { $0.load(as: UInt16.self) }
+ return (endianness == .big) ? value.bigEndian : value.littleEndian
+ }
+
+ func readUInt32(at offset: Int, endianness: Endianness = .big) -> UInt32? {
+ guard offset >= 0, offset + MemoryLayout<UInt32>.size <= self.count else {
+ return nil
+ }
+ let value = self.subdata(in: offset..<(offset + MemoryLayout<UInt32>.size)).withUnsafeBytes { $0.load(as: UInt32.self) }
+ return (endianness == .big) ? value.bigEndian : value.littleEndian
+ }
+
+ func read<T: FixedWidthInteger>(type: T.Type, at offset: Int) -> T? {
+ guard offset >= 0, offset + MemoryLayout<T>.size <= self.count else {
+ return nil // Ensure the offset is within the Data's range
+ }
+
+ return self.withUnsafeBytes { rawBufferPointer in
+ let pointer = rawBufferPointer.baseAddress!
+ .advanced(by: offset)
+ .assumingMemoryBound(to: T.self)
+
+// switch endianness {
+// case .big:
+ return pointer.pointee.bigEndian
+// case .little:
+// return pointer.pointee.littleEndian
+// }
+ }
+ }
+
+ func readString(at offset: Int, length: Int, encoding: String.Encoding) -> String? {
+ return String(data: self[offset..<(offset + length)], encoding: encoding)
+ }
+}