diff options
| author | Dustin Mierau <dustin@mierau.me> | 2023-11-27 12:39:11 -0800 |
|---|---|---|
| committer | Dustin Mierau <dustin@mierau.me> | 2023-11-27 12:39:11 -0800 |
| commit | de5ee043826bce23906bfcb351a2702e1aa88270 (patch) | |
| tree | 39c945bf3958d2e295a66596d1bac53ceb4c54d6 /Hotline/Utility | |
Getting started
Diffstat (limited to 'Hotline/Utility')
| -rw-r--r-- | Hotline/Utility/DataExtensions.swift | 54 |
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) + } +} |