-
-
Notifications
You must be signed in to change notification settings - Fork 609
Description
2ff5d34 adds DecryptReaderAt, which enables seeking in encrypted age files. In particular, ReaderAt is what archive/zip needs, and it's (almost) a superset API. Indeed, you can get a ReadSeeker from io.SectionReader. Making a separate function was simpler, more type-safe, less confusing (because ReaderAt disregards the ReadSeeker index), and more discoverable.
Maybe this is enough for seeking use cases!
If it's not, and in particular if users need a ReadSeeker from a src which implements ReadSeeker but not ReaderAt, it would actually be possible to upgrade the return value of Decrypt to ReadSeeker. That would be a parallel implementation, that would use Seek(0, SeekEnd) to discover the file size (to authenticate the final chunk) and Seek(0, SeekCurrent) to discover the current seek index, and keep up the mapping. We could probably keep all the complexity in the Seek codepath.
It would also be possible to proxy ReaderAt through, but only if we also have Seeker to discover the total encrypted size first, which ReaderAt doesn't expose. (Note how io.SectionReader and DecryptReaderAt take a size.) However, we'd need to either do size discovery before returning (penalizing all uses of Decrypt) or carefully hold reads while doing opportunistic size discovery later. It's actually unclear if Read / ReadAt concurrency is allowed, another reason to keep them separate types. This part is mostly academic, because if a type has ReaderAt and Seeker, they can use DecryptReaderAt instead.