Open straight-shoota opened 6 years ago
I don't think these methods should exist. What if read_bytes? reads a few bytes but not enough to decode the data? How can you recover those lost bytes?
read_bytes?
would be for use cases like https://forum.crystal-lang.org/t/read-nrrd-file-with-attached-header-and-gzipped-data/5355 where you know from the data format description that you can either read the full bytes or not.
Anything in between would be a failure state and should probably raise. Excess bytes that have been read in the method could be attached to the exception if that's useful.
What if read_bytes? reads a few bytes but not enough to decode the data? How can you recover those lost bytes?
In C you would ungetc
the bytes already read. However I guess it isn't very appropriate to implement a similar in-memory buffer for every IO
in Crystal
In the end I'm thinking that read_bytes
can also fail in the same way, and right now there's no way to recover the lost bytes. So it's probably fine to add read_bytes?
However, we must clearly document that if nil
is returned it might be because there wasn't enough data to read, but some of it might have been read (IOs that have peek
could sometimes avoid advancing the pointer)
As suggested in https://github.com/crystal-lang/crystal/pull/6873#issuecomment-424730829, the IO methods
read_string
andread_bytes
don't have a non-raising counterpart which would be useful in situations where it's optional if the IO can provide an additional value.See https://github.com/crystal-lang/crystal/pull/6501#discussion_r208516591 for another example where
read_bytes?
would be useful but a workaround needed to be employed.Implementing
#read_string?
should be pretty easy. For#read_bytes?
, we'd probably also needIO::ByteFormat#decode?
or letIO::ByteFormat#decode
returnnil
instead of raising. But then we'd need to ensure a proper exception is raised.