no.
Here's a version that doesn't use UnsafePointer / UnsafeRawBufferPointer at all:
extension Data {
func readInt32(at offset: Int, bigEndian: Bool) -> Int32 {
let a = Int32(self[offset + (bigEndian ? 3 : 0)])
let b = Int32(self[offset + (bigEndian ? 2 : 1)])
let c = Int32(self[offset + (bigEndian ? 1 : 2)])
let d = Int32(self[offset + (bigEndian ? 0 : 3)])
return a + (b << 8) + (c << 16) + (d << 24)
}
func readString(at offset: Int, count: Int) -> String {
let fragment = self[offset ..< offset + count]
return String(data: fragment, encoding: .ascii)!
}
init(url: URL, mappedIfSafe: Bool) throws {
if mappedIfSafe {
let data = try NSData(contentsOf: url, options: .mappedIfSafe)
self = data as Data
} else {
try self.init(contentsOf: url)
}
}
}
struct S {
private let data: Data
private var bigEndian: Bool = false
init(data: Data) {
self.data = data
let x = data.readInt32(at: 0, bigEndian: bigEndian)
bigEndian = x == 1234 // TODO: logic to determine big vs little endian
}
var locifn: String {
data.readString(at: 16, count: 60)
}
var fward: Int32 {
data.readInt32(at: 76, bigEndian: bigEndian)
}
}
func test(url: URL) {
let data = try! Data(url: url, mappedIfSafe: true)
let pageIndex = 1 // adjust accordingly
let pageSize = 1024
let page = data[pageIndex*pageSize ..< (pageIndex + 1)* pageSize]
// despite returning type "Data", data range subscript does not return Data
// you may expect. Let's convert to proper Data for simplicity:
let pageData = Data(page)
let s = S(data: pageData)
print(s.locifn)
print(s.fward)
}
Perhaps you also want the code not trapping on invalid input (throwing on out of bounds, or strings being non ascii, etc).