I'm writing a pure-Swift GeoTIFF parser. Part of that involves creating a BinaryReader
struct that maintains an index into a Data
, and allows seeking and reading different types.
Something I commonly do is save the current index, seek to some other part of the file, read some data, then seek to the saved index (note that read()
accesses self.reader
in a loop):
let saveIdx = self.reader.idx
self.reader.seek(to: de.offset)
ifd.stripByteCounts = try read(count: de.count, ofType: de.type)
self.reader.seek(to: saveIdx)
I thought this boilerplate could be cleaned up with a method that takes a closure, like this:
try self.reader.at(de.offset)
{
ifd.stripByteCounts = try read(count: de.count, ofType: de.type)
}
where at(_,op:)
looks like:
mutating
func
at(_ inOffset: UInt64, op inOp: () throws -> ())
throws
{
let saveIdx = self.idx
seek(to: inOffset)
try inOp()
seek(to: saveIdx)
}
Unfortunately, when I call at(_,:op:)
, I get
Overlapping accesses to 'self.reader', but modification requires exclusive access; consider copying to a local variable.
If BinaryReader
is a class and not a struct, this error goes away. I’m not sure semantically which makes more sense. Perhaps class, because I find that all the methods are mutating (despite coding in Swift for many years now, I’m still not sure of these sorts of things). But even as a struct, the code seems valid, so is there a way to tell the compiler it’ll be okay?