return n, err
}
-// WriteTo writes the entire contents of this.Reader to dest. Returns
-// BadChecksum if the checksum doesn't match.
+// WriteTo writes the entire contents of this.Reader to dest. Returns
+// BadChecksum if writing is successful but the checksum doesn't
+// match.
func (this HashCheckingReader) WriteTo(dest io.Writer) (written int64, err error) {
if writeto, ok := this.Reader.(io.WriterTo); ok {
written, err = writeto.WriteTo(io.MultiWriter(dest, this.Hash))
written, err = io.Copy(io.MultiWriter(dest, this.Hash), this.Reader)
}
- sum := this.Hash.Sum(make([]byte, 0, this.Hash.Size()))
+ if err != nil {
+ return written, err
+ }
+ sum := this.Hash.Sum(make([]byte, 0, this.Hash.Size()))
if fmt.Sprintf("%x", sum) != this.Check {
- err = BadChecksum
+ return written, BadChecksum
}
- return written, err
+ return written, nil
}
// Close reads all remaining data from the underlying Reader and
"bytes"
"crypto/md5"
"fmt"
- . "gopkg.in/check.v1"
"io"
"io/ioutil"
+
+ . "gopkg.in/check.v1"
)
type HashcheckSuiteSuite struct{}
c.Check(err, Equals, BadChecksum)
<-done
}
+
+ // If WriteTo stops early due to a write error, return the
+ // write error (not "bad checksum").
+ {
+ input := bytes.NewBuffer(make([]byte, 1<<26))
+ hcr := HashCheckingReader{input, md5.New(), hash}
+ r, w := io.Pipe()
+ r.Close()
+ n, err := hcr.WriteTo(w)
+ c.Check(n, Equals, int64(0))
+ c.Check(err, NotNil)
+ c.Check(err, Not(Equals), BadChecksum)
+ }
}