codecutil: added ByteLexer struct for configuring buffer size

This commit is contained in:
Trek H 2019-06-18 14:50:36 +09:30
parent bcd59b98d2
commit b418944daa
2 changed files with 23 additions and 8 deletions

View File

@ -30,11 +30,21 @@ import (
"time" "time"
) )
// LexBytes reads n bytes from src and writes them to dst every t seconds. // ByteLexer is used to lex a certain number of bytes per a given delay, the number is configured upon construction.
func LexBytes(dst io.Writer, src io.Reader, t time.Duration, n int) error { type ByteLexer struct {
if n <= 0 { bufSize int
return fmt.Errorf("invalid buffer size: %v", n)
} }
// NewByteLexer returns a pointer to a ByteLexer with the given buffer size.
func NewByteLexer(bufSize int) (*ByteLexer, error) {
if bufSize <= 0 {
return nil, fmt.Errorf("invalid buffer size: %v", bufSize)
}
return &ByteLexer{bufSize: bufSize}, nil
}
// Lex reads l.bufSize bytes from src and writes them to dst every t seconds.
func (l *ByteLexer) Lex(dst io.Writer, src io.Reader, t time.Duration) error {
if t < 0 { if t < 0 {
return fmt.Errorf("invalid delay: %v", t) return fmt.Errorf("invalid delay: %v", t)
} }
@ -45,7 +55,7 @@ func LexBytes(dst io.Writer, src io.Reader, t time.Duration, n int) error {
tick = ticker.C tick = ticker.C
} }
buf := make([]byte, n) buf := make([]byte, l.bufSize)
for { for {
if t != 0 { if t != 0 {
<-tick <-tick

View File

@ -47,15 +47,20 @@ var lexTests = []struct {
{[]byte{0x10, 0x00, 0xf3, 0x45, 0xfe, 0xd2, 0xaa, 0x4e}, time.Millisecond, 15, false}, {[]byte{0x10, 0x00, 0xf3, 0x45, 0xfe, 0xd2, 0xaa, 0x4e}, time.Millisecond, 15, false},
} }
func TestLexBytes(t *testing.T) { func TestByteLexer(t *testing.T) {
for i, tt := range lexTests { for i, tt := range lexTests {
t.Run(strconv.Itoa(i), func(t *testing.T) { t.Run(strconv.Itoa(i), func(t *testing.T) {
dst := bytes.NewBuffer([]byte{}) dst := bytes.NewBuffer([]byte{})
err := LexBytes(dst, bytes.NewReader(tt.data), tt.t, tt.n) l, err := NewByteLexer(tt.n)
if err != nil && err != io.EOF { if err != nil {
if !tt.fail { if !tt.fail {
t.Errorf("unexpected error: %v", err.Error()) t.Errorf("unexpected error: %v", err.Error())
} }
return
}
err = l.Lex(dst, bytes.NewReader(tt.data), tt.t)
if err != nil && err != io.EOF {
t.Errorf("unexpected error: %v", err.Error())
} else if !bytes.Equal(dst.Bytes(), tt.data) { } else if !bytes.Equal(dst.Bytes(), tt.data) {
t.Errorf("data before and after lex are not equal: want %v, got %v", tt.data, dst.Bytes()) t.Errorf("data before and after lex are not equal: want %v, got %v", tt.data, dst.Bytes())
} }