b := make([]byte, size)
// zeroes
- _, err := NewReader(sliceReaderAt(b), size)
+ _, err := NewReader(bytes.NewReader(b), size)
if err != ErrFormat {
t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
}
for i := 0; i < size-4; i += 4 {
copy(b[i:i+4], sig)
}
- _, err = NewReader(sliceReaderAt(b), size)
+ _, err = NewReader(bytes.NewReader(b), size)
if err != ErrFormat {
t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
}
}
-
-type sliceReaderAt []byte
-
-func (r sliceReaderAt) ReadAt(b []byte, off int64) (int, error) {
- copy(b, r[int(off):int(off)+len(b)])
- return len(b), nil
-}
}
// read it back
- r, err := NewReader(sliceReaderAt(buf.Bytes()), int64(buf.Len()))
+ r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {
t.Fatal(err)
}
import (
"bytes"
"fmt"
- "io"
"reflect"
+ "strings"
"testing"
"time"
)
-type stringReaderAt string
-
-func (s stringReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
- if off >= int64(len(s)) {
- return 0, io.EOF
- }
- n = copy(p, s[off:])
- return
-}
-
func TestOver65kFiles(t *testing.T) {
if testing.Short() {
t.Logf("slow test; skipping")
if err := w.Close(); err != nil {
t.Fatalf("Writer.Close: %v", err)
}
- rat := stringReaderAt(buf.String())
- zr, err := NewReader(rat, int64(len(rat)))
+ s := buf.String()
+ zr, err := NewReader(strings.NewReader(s), int64(len(s)))
if err != nil {
t.Fatalf("NewReader: %v", err)
}
"unicode/utf8"
)
-// A Reader implements the io.Reader, io.Seeker, io.ByteScanner, and
-// io.RuneScanner interfaces by reading from a byte slice.
+// A Reader implements the io.Reader, io.ReaderAt, io.Seeker,
+// io.ByteScanner, and io.RuneScanner interfaces by reading from
+// a byte slice.
// Unlike a Buffer, a Reader is read-only and supports seeking.
type Reader struct {
s []byte
return
}
+func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
+ if off < 0 {
+ return 0, errors.New("bytes: invalid offset")
+ }
+ if off >= int64(len(r.s)) {
+ return 0, io.EOF
+ }
+ n = copy(b, r.s[int(off):])
+ if n < len(b) {
+ err = io.EOF
+ }
+ return
+}
+
func (r *Reader) ReadByte() (b byte, err error) {
if r.i >= len(r.s) {
return 0, io.EOF
import (
. "bytes"
+ "fmt"
+ "io"
"os"
"testing"
)
}
}
}
+
+func TestReaderAt(t *testing.T) {
+ r := NewReader([]byte("0123456789"))
+ tests := []struct {
+ off int64
+ n int
+ want string
+ wanterr interface{}
+ }{
+ {0, 10, "0123456789", nil},
+ {1, 10, "123456789", io.EOF},
+ {1, 9, "123456789", nil},
+ {11, 10, "", io.EOF},
+ {0, 0, "", nil},
+ {-1, 0, "", "bytes: invalid offset"},
+ }
+ for i, tt := range tests {
+ b := make([]byte, tt.n)
+ rn, err := r.ReadAt(b, tt.off)
+ got := string(b[:rn])
+ if got != tt.want {
+ t.Errorf("%d. got %q; want %q", i, got, tt.want)
+ }
+ if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) {
+ t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr)
+ }
+ }
+}
// Open opens and returns the FileHeader's associated File.
func (fh *FileHeader) Open() (File, error) {
if b := fh.content; b != nil {
- r := io.NewSectionReader(sliceReaderAt(b), 0, int64(len(b)))
+ r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
return sectionReadCloser{r}, nil
}
return os.Open(fh.tmpfile)
func (rc sectionReadCloser) Close() error {
return nil
}
-
-type sliceReaderAt []byte
-
-func (r sliceReaderAt) ReadAt(b []byte, off int64) (int, error) {
- if int(off) >= len(r) || off < 0 {
- return 0, io.ErrUnexpectedEOF
- }
- n := copy(b, r[int(off):])
- return n, nil
-}
"unicode/utf8"
)
-// A Reader implements the io.Reader, io.Seeker, io.ByteScanner, and
-// io.RuneScanner interfaces by reading from a string.
+// A Reader implements the io.Reader, io.ReaderAt, io.Seeker,
+// io.ByteScanner, and io.RuneScanner interfaces by reading
+// from a string.
type Reader struct {
s string
i int // current reading index
return
}
+func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
+ if off < 0 {
+ return 0, errors.New("strings: invalid offset")
+ }
+ if off >= int64(len(r.s)) {
+ return 0, io.EOF
+ }
+ n = copy(b, r.s[int(off):])
+ if n < len(b) {
+ err = io.EOF
+ }
+ return
+}
+
func (r *Reader) ReadByte() (b byte, err error) {
if r.i >= len(r.s) {
return 0, io.EOF
package strings_test
import (
+ "fmt"
+ "io"
"os"
"strings"
"testing"
}
}
}
+
+func TestReaderAt(t *testing.T) {
+ r := strings.NewReader("0123456789")
+ tests := []struct {
+ off int64
+ n int
+ want string
+ wanterr interface{}
+ }{
+ {0, 10, "0123456789", nil},
+ {1, 10, "123456789", io.EOF},
+ {1, 9, "123456789", nil},
+ {11, 10, "", io.EOF},
+ {0, 0, "", nil},
+ {-1, 0, "", "strings: invalid offset"},
+ }
+ for i, tt := range tests {
+ b := make([]byte, tt.n)
+ rn, err := r.ReadAt(b, tt.off)
+ got := string(b[:rn])
+ if got != tt.want {
+ t.Errorf("%d. got %q; want %q", i, got, tt.want)
+ }
+ if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) {
+ t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr)
+ }
+ }
+}