go
go copied to clipboard
proposal: io: add ZeroReader io.Reader
Needing to read a stream of zero-bytes is an ocassional use-case of an io.Reader
. io.ZeroReader
would be the /dev/zero
counterpoint to /dev/null
and io.Discard
.
One particular use-case is with cipher.StreamReader
to create a CSPRNG (this is the crypto/ecdsa use below).
I've proposed it be called io.ZeroReader
, but it could also be called io.Zero
or similar.
Proposed API:
package io
// ZeroReader is a Reader that reads an endless stream of zero-bytes.
var ZeroReader Reader = zeroReader{}
type zeroReader struct{}
func (zeroReader) Read(p []byte) (int, error) {
for i := range p {
p[i] = 0
}
return len(p), nil
}
There are two uses of this I can find in the standard library:
https://github.com/golang/go/blob/3a7a528c2d7ee0c7b2988a7aee0b9347e973cbed/src/archive/tar/reader.go#L811-L818
https://github.com/golang/go/blob/34ab0bcc5eaf97cc0aff11cfe782e4c174d52ef0/src/crypto/ecdsa/ecdsa.go#L446-L456
...and five more in test code: here and here.
Admittedly the archive/tar use could be written differently (it seems to be just zeroing a slice), but the crypto/ecdsa use does require it.
There are also two examples in the standard library of io.ReaderAt
zeroing:
https://github.com/golang/go/blob/ea14d1b6e1167159dfc8408073ef411c3cf1d7e0/src/internal/xcoff/file.go#L449-L458
https://github.com/golang/go/blob/ea14d1b6e1167159dfc8408073ef411c3cf1d7e0/src/debug/pe/file.go#L185-L194
If you leave it as zeroing only this could make use of #56351, but you could also make it a bit more flexible by making it something like type RepeatReader struct { Value byte }
or something and then make it fill the slice with Value
instead of just 0
.
Duplicate of #48897
Duplicate of #48897
@seankhliao I don't think this is a duplicate of #48897. That issue was seeking an io.Reader
that always returns io.EOF
, this issue is instead proposing an io.Reader
that reads an infinite stream of zero-bytes.
Compare what this issue is requesting versus what #48897 was asking for:
var Empty Reader = emptyReader{}
type emptyReader struct {}
func (emptyReader) Read(p []byte) (n int, err error) {
return len(p), EOF
}
Please re-open this issue.
This proposal has been added to the active column of the proposals project and will now be reviewed at the weekly proposal review meetings. — rsc for the proposal review group
There is a question of what type to give this thing. It is both a Reader and a ReaderAt, and we don't have an interface for that type. We would probably need to do:
var Zero ZeroReader
func (ZeroReader) Read
func (ZeroReader) ReadAt
There is also potential confusion with it being a reader that has no (zero) bytes in length, not a reader that has an infinite number of zero bytes. "A reader that returns 0 bytes" can be read either way.
There is also the question of whether this arises enough to be worthwhile. The uses in the standard library are pretty fringe. I might also worry about uses in crypto and then having to preserve some properties of the implementation that we might or might not remember to preserve.
Are the use cases really here?
Note that the new clear
builtin will shorten the implementation of these, making it even easier to maintain them outside the standard library.
Based on the discussion above, this proposal seems like a likely decline. — rsc for the proposal review group
No change in consensus, so declined. — rsc for the proposal review group