nb int64 // Number of remaining bytes to read
}
-func (fr *regFileReader) Read(b []byte) (int, error) {
+func (fr *regFileReader) Read(b []byte) (n int, err error) {
if int64(len(b)) > fr.nb {
b = b[:fr.nb]
}
- n, err := fr.r.Read(b)
- fr.nb -= int64(n)
+ if len(b) > 0 {
+ n, err = fr.r.Read(b)
+ fr.nb -= int64(n)
+ }
switch {
case err == io.EOF && fr.nb > 0:
return n, io.ErrUnexpectedEOF
import (
"bytes"
"crypto/md5"
+ "errors"
"fmt"
"io"
"io/ioutil"
}
}
+// testNonEmptyReader wraps an io.Reader and ensures that
+// Read is never called with an empty buffer.
+type testNonEmptyReader struct{ io.Reader }
+
+func (r testNonEmptyReader) Read(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, errors.New("unexpected empty Read call")
+ }
+ return r.Reader.Read(b)
+}
+
func TestFileReader(t *testing.T) {
type (
testRead struct { // Read(cnt) == (wantStr, wantErr)
maker: makeReg{"", 1},
tests: []testFnc{
testRemaining{1, 1},
- testRead{0, "", io.ErrUnexpectedEOF},
testRead{5, "", io.ErrUnexpectedEOF},
testWriteTo{nil, 0, io.ErrUnexpectedEOF},
testRemaining{1, 1},
var fr fileReader
switch maker := v.maker.(type) {
case makeReg:
- r := strings.NewReader(maker.str)
+ r := testNonEmptyReader{strings.NewReader(maker.str)}
fr = ®FileReader{r, maker.size}
case makeSparse:
if !validateSparseEntries(maker.spd, maker.size) {
t.Fatalf("invalid sparse map: %v", maker.spd)
}
sph := invertSparseEntries(maker.spd, maker.size)
- r := strings.NewReader(maker.makeReg.str)
+ r := testNonEmptyReader{strings.NewReader(maker.makeReg.str)}
fr = ®FileReader{r, maker.makeReg.size}
fr = &sparseFileReader{fr, sph, 0}
default:
nb int64 // Number of remaining bytes to write
}
-func (fw *regFileWriter) Write(b []byte) (int, error) {
+func (fw *regFileWriter) Write(b []byte) (n int, err error) {
overwrite := int64(len(b)) > fw.nb
if overwrite {
b = b[:fw.nb]
}
- n, err := fw.w.Write(b)
- fw.nb -= int64(n)
+ if len(b) > 0 {
+ n, err = fw.w.Write(b)
+ fw.nb -= int64(n)
+ }
switch {
case err != nil:
return n, err
import (
"bytes"
"encoding/hex"
+ "errors"
"io"
"io/ioutil"
"os"
}
}
+// testNonEmptyWriter wraps an io.Writer and ensures that
+// Write is never called with an empty buffer.
+type testNonEmptyWriter struct{ io.Writer }
+
+func (w testNonEmptyWriter) Write(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, errors.New("unexpected empty Write call")
+ }
+ return w.Writer.Write(b)
+}
+
func TestFileWriter(t *testing.T) {
type (
testWrite struct { // Write(str) == (wantCnt, wantErr)
for i, v := range vectors {
var wantStr string
bb := new(bytes.Buffer)
+ w := testNonEmptyWriter{bb}
var fw fileWriter
switch maker := v.maker.(type) {
case makeReg:
- fw = ®FileWriter{bb, maker.size}
+ fw = ®FileWriter{w, maker.size}
wantStr = maker.wantStr
case makeSparse:
if !validateSparseEntries(maker.sph, maker.size) {
t.Fatalf("invalid sparse map: %v", maker.sph)
}
spd := invertSparseEntries(maker.sph, maker.size)
- fw = ®FileWriter{bb, maker.makeReg.size}
+ fw = ®FileWriter{w, maker.makeReg.size}
fw = &sparseFileWriter{fw, spd, 0}
wantStr = maker.makeReg.wantStr
default: