Writing in Swift, I have a specific need that might be a candidate for type punning. I'm reading files from a disk image where they exist in contiguous 512 byte sectors. A file comes off the disk as a Data
struct which is easily converted to a byte array and/or 512 byte DataSlices
without making copying necessary.
So far, so good! A file can be represented quickly as a collection of arrays containing 512 UInt8
units. However, some disk sectors, typically containing metadata, are better treated as 256 UInt16
items. Ideally, I'd like to be able to refer to the sectors in memory either way without any copying.
Right now, I'm taking a simple approach in which I copy a sector (needing two copies) into something like:
struct Sector {
let bytes: [UInt8]
let words: [UInt16]
. . .
init() {
self.bytes = Array(repeating: 0, count: 512)
self.words = Array(repeating: 0, count: 256)
. . .
and then refer to sector.words
or sector.bytes
depending which is appropriate. Luckily, the [UInt16]
sectors are much fewer than their byte equivalents, so this isn't too awful; and any given sector is one or the other, I don't have to worry that changing bytes
doesn't change words
(although that's an accident waiting to happen).
Everything I read decries punning the [UInt8]
and [UInt16]
arrays, and Swift's "unsafe" memory functions are somewhat intimidating. I'm trying to think of a way to make .words
in the above struct occupy the same memory as .bytes
and would appreciate some suggestions.
I'm still working on this .. if I find something worthwhile, I'll share.