parent
b26f4bdd6a
commit
711d568036
@ -1,41 +0,0 @@ |
||||
package garage |
||||
|
||||
import "io" |
||||
|
||||
type infiniteReader struct { |
||||
b []byte |
||||
i int |
||||
} |
||||
|
||||
// NewInfiniteReader returns a reader which will produce the given bytes in
|
||||
// repetition. len(b) must be greater than 0.
|
||||
func NewInfiniteReader(b []byte) io.Reader { |
||||
|
||||
if len(b) == 0 { |
||||
panic("len(b) must be greater than 0") |
||||
} |
||||
|
||||
return &infiniteReader{b: b} |
||||
} |
||||
|
||||
func (r *infiniteReader) Read(b []byte) (int, error) { |
||||
|
||||
// here, have a puzzle
|
||||
|
||||
var n int |
||||
|
||||
for { |
||||
|
||||
n += copy(b[n:], r.b[r.i:]) |
||||
|
||||
if r.i > 0 { |
||||
n += copy(b[n:], r.b[:r.i]) |
||||
} |
||||
|
||||
r.i = (r.i + n) % len(r.b) |
||||
|
||||
if n >= len(b) { |
||||
return n, nil |
||||
} |
||||
} |
||||
} |
@ -1,101 +0,0 @@ |
||||
package garage |
||||
|
||||
import ( |
||||
"bytes" |
||||
"strconv" |
||||
"testing" |
||||
) |
||||
|
||||
func TestInfiniteReader(t *testing.T) { |
||||
|
||||
tests := []struct { |
||||
in []byte |
||||
size int |
||||
exp []string |
||||
}{ |
||||
{ |
||||
in: []byte("a"), |
||||
size: 1, |
||||
exp: []string{"a"}, |
||||
}, |
||||
{ |
||||
in: []byte("ab"), |
||||
size: 1, |
||||
exp: []string{"a", "b"}, |
||||
}, |
||||
{ |
||||
in: []byte("ab"), |
||||
size: 2, |
||||
exp: []string{"ab"}, |
||||
}, |
||||
{ |
||||
in: []byte("ab"), |
||||
size: 3, |
||||
exp: []string{"aba", "bab"}, |
||||
}, |
||||
{ |
||||
in: []byte("ab"), |
||||
size: 4, |
||||
exp: []string{"abab"}, |
||||
}, |
||||
{ |
||||
in: []byte("ab"), |
||||
size: 5, |
||||
exp: []string{"ababa", "babab"}, |
||||
}, |
||||
{ |
||||
in: []byte("abc"), |
||||
size: 1, |
||||
exp: []string{"a", "b", "c"}, |
||||
}, |
||||
{ |
||||
in: []byte("abc"), |
||||
size: 2, |
||||
exp: []string{"ab", "ca", "bc"}, |
||||
}, |
||||
{ |
||||
in: []byte("abc"), |
||||
size: 3, |
||||
exp: []string{"abc"}, |
||||
}, |
||||
{ |
||||
in: []byte("abc"), |
||||
size: 4, |
||||
exp: []string{"abca", "bcab", "cabc"}, |
||||
}, |
||||
{ |
||||
in: []byte("abc"), |
||||
size: 5, |
||||
exp: []string{"abcab", "cabca", "bcabc"}, |
||||
}, |
||||
} |
||||
|
||||
for i, test := range tests { |
||||
t.Run(strconv.Itoa(i), func(t *testing.T) { |
||||
|
||||
r := NewInfiniteReader(test.in) |
||||
buf := make([]byte, test.size) |
||||
|
||||
assertRead := func(expBuf []byte) { |
||||
|
||||
n, err := r.Read(buf) |
||||
|
||||
if !bytes.Equal(buf, expBuf) { |
||||
t.Fatalf("expected bytes %q, got %q", expBuf, buf) |
||||
|
||||
} else if n != len(buf) { |
||||
t.Fatalf("expected n %d, got %d", len(buf), n) |
||||
|
||||
} else if err != nil { |
||||
t.Fatalf("unexpected error: %v", err) |
||||
} |
||||
} |
||||
|
||||
for i := 0; i < 3; i++ { |
||||
for _, expStr := range test.exp { |
||||
assertRead([]byte(expStr)) |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
} |
Loading…
Reference in new issue