I suspect this is really easy but it is evading me.
I have a file representing a disk image read into memory as type Data. I want to be able to address this image as an array of Sectors and, in turn, address Sectors as UInt16 (Word) and UInt8 (Byte) arrays .. a structure like:
| .. bytes from a disk image ..
+-----------------------+-----------------------+-----------------------+- - - -
| disk sector .. | disk sector .. | ⬅︎ sector array
+-----------------------+-----------------------+
| | | | | | | ⬅︎ word array
+---+---+---+---+---+---+
| | | | | | | | | | | | | ⬅︎ byte array
+-+-+-+-+-+-+-+-+-+-+-+-+
.. so I can refer to parts of the disk image via:
let header = sector[1]
let word = header[24]
let byte = header[48] // indexing the same memory location (as 8 bits)
.. with the presumption that slicing etc will avoid any more copying after the whole disk image is in memory. My first pass over this will read-only but I'm sure I'll go mutable before I'm done.
This is addressed, in part, by several StackOverflow entries but a frightening number of them are Swift 3 and earlier usages and unsafe memory cleverness has progressed a long way since then.
This fundamental API does not show up in the index of of Data's methods. And the URL above doesn't contain any documentation, so here it is from the source:
/// Calls the given closure with the contents of underlying storage.
///
/// - note: Calling `withUnsafeBytes` multiple times does not guarantee that
/// the same buffer pointer will be passed in every time.
/// - warning: The buffer argument to the body should not be stored or used
/// outside of the lifetime of the call to the closure.
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
It has a disclaimer about memory moving from underneath you because Data is a copy-on-write data structure. Presumably you're careful not to trigger a copy though. This API itself won't copy any bytes.