AFAIK it's good Swift practice to use Int
whenever possible.
Sometimes that doesn't make sense though.
For example Data
uses Int
as count and FileHandle uses UInt64
to seek an offset.
A negative count or position doesn't make sense but neither does Int.max
in practice. Both are valid (or historic?) choices.
In my case I am storing page numbers, offsets, sizes, checksums. UInt32
, UInt16
and UInt8
will do and anything bigger is just writing a bunch of UInt8.zero
bytes to disk. No point in wasting so much of available storage space on .zero. In the aggregate though content can be bigger than the UInt16.max
of an individual page.
In other words I'm mixing all these types either to compute something. The user is presented with a uniform facade of Int
. I have a hunch I am not the only one in this situation.
My question is how do you deal with this in a nice way without giving up too much of Swift type safety system or without cussing it out?
I have thus far tried variations like A:
func space() throws -> Int
{
try Int(sheet.move(to: format_free).read(type: Page.Offset.self))
}
func set(space: Int) throws
{
assert(space < Page.Offset.max)
try sheet.move(to: format_free).write(value: Page.Offset(space))
}
B:
func space() throws -> Int
{
try sheet.move(to: format_free).read(type: Page.Offset.self, as: Int.self)
}
func set(space: Int) throws
{
try sheet.move(to: format_free).write(value: space, as: Page.Offset.self)
}
C:
func space() throws -> Page.Offset
{
try sheet.move(to: format_free).read(type: Page.Offset.self)
}
func set(space: Page.Offset) throws
{
try sheet.move(to: format_free).write(value: space)
}
which lets the call site deal with it. That last one litters every call site with:
let space = try Int(current.space())
or leads to ugly looking code like
let space = try current.space()
let foo = Int( UInt64(fileSize) / UInt64(pageSize))
assert(foo < UInt32.max)
let bar = foo * Int(number) + Int(...)
example.seek( UInt64(bar) ).write( UInt16(referenceBar))
and it's way too easy to mess up types.
It's driving me bonkers and I can't seem to settle down something that looks nice, is easy to read and type safe. Any suggestions or places I can look to for inspiration?
Please keep in mind that, in my case, the user can (maliciously) change the file contents including stored page offsets etc. The assumption that "writing valid offsets == reading valid offsets" is wrong even though the user never directly deals in offsets.