restic/internal/hashing/reader.go

52 lines
985 B
Go

package hashing
import (
"hash"
"io"
)
// ReadSumer hashes all data read from the underlying reader.
type ReadSumer interface {
io.Reader
// Sum returns the hash of the data read so far.
Sum(d []byte) []byte
}
type reader struct {
io.Reader
h hash.Hash
}
type readWriterTo struct {
reader
writerTo io.WriterTo
}
// NewReader returns a new ReadSummer that uses the hash h. If the underlying
// reader supports WriteTo then the returned reader will do so too.
func NewReader(r io.Reader, h hash.Hash) ReadSumer {
rs := reader{
Reader: io.TeeReader(r, h),
h: h,
}
if _, ok := r.(io.WriterTo); ok {
return &readWriterTo{
reader: rs,
writerTo: r.(io.WriterTo),
}
}
return &rs
}
// Sum returns the hash of the data read so far.
func (h *reader) Sum(d []byte) []byte {
return h.h.Sum(d)
}
// WriteTo reads all data into the passed writer
func (h *readWriterTo) WriteTo(w io.Writer) (int64, error) {
return h.writerTo.WriteTo(NewWriter(w, h.h))
}