diff --git a/codec/codecutil/bytescanner.go b/codec/codecutil/bytescanner.go index 981bd6e0..03f825d6 100644 --- a/codec/codecutil/bytescanner.go +++ b/codec/codecutil/bytescanner.go @@ -23,7 +23,7 @@ LICENSE */ // Package bytescan implements a byte-level scanner. -package bytescan +package codecutil import "io" diff --git a/codec/codecutil/bytescanner_test.go b/codec/codecutil/bytescanner_test.go index 64c17c31..68db0006 100644 --- a/codec/codecutil/bytescanner_test.go +++ b/codec/codecutil/bytescanner_test.go @@ -25,7 +25,7 @@ LICENSE in gpl.txt. If not, see http://www.gnu.org/licenses. */ -package bytescan +package codecutil import ( "bytes" diff --git a/codec/h264/lex.go b/codec/h264/lex.go index 3976cef1..9a071715 100644 --- a/codec/h264/lex.go +++ b/codec/h264/lex.go @@ -32,6 +32,8 @@ package h264 import ( "io" "time" + + "bitbucket.org/ausocean/av/codec/codecutil" ) var noDelay = make(chan time.Time) @@ -58,7 +60,7 @@ func Lex(dst io.Writer, src io.Reader, delay time.Duration) error { const bufSize = 8 << 10 - c := newScanner(src, make([]byte, 4<<10)) // Standard file buffer size. + c := codecutil.NewByteScanner(src, make([]byte, 4<<10)) // Standard file buffer size. buf := make([]byte, len(h264Prefix), bufSize) copy(buf, h264Prefix[:]) @@ -67,7 +69,7 @@ outer: for { var b byte var err error - buf, b, err = c.scanUntilZeroInto(buf) + buf, b, err = c.ScanUntil(buf, 0x00) if err != nil { if err != io.EOF { return err @@ -76,7 +78,7 @@ outer: } for n := 1; b == 0x0 && n < 4; n++ { - b, err = c.readByte() + b, err = c.ReadByte() if err != nil { if err != io.EOF { return err @@ -101,7 +103,7 @@ outer: writeOut = false } - b, err = c.readByte() + b, err = c.ReadByte() if err != nil { if err != io.EOF { return err @@ -131,70 +133,3 @@ outer: _, err := dst.Write(buf) return err } - -// scanner is a byte scanner. -type scanner struct { - buf []byte - off int - - // r is the source of data for the scanner. - r io.Reader -} - -// newScanner returns a scanner initialised with an io.Reader and a read buffer. -func newScanner(r io.Reader, buf []byte) *scanner { - return &scanner{r: r, buf: buf[:0]} -} - -// scanUntilZeroInto scans the scanner's underlying io.Reader until a zero byte -// has been read, appending all read bytes to dst. The resulting appended data, -// the last read byte and whether the last read byte was zero are returned. -func (c *scanner) scanUntilZeroInto(dst []byte) (res []byte, b byte, err error) { -outer: - for { - var i int - for i, b = range c.buf[c.off:] { - if b != 0x0 { - continue - } - dst = append(dst, c.buf[c.off:c.off+i+1]...) - c.off += i + 1 - break outer - } - dst = append(dst, c.buf[c.off:]...) - err = c.reload() - if err != nil { - break - } - } - return dst, b, err -} - -// readByte is an unexported ReadByte. -func (c *scanner) readByte() (byte, error) { - if c.off >= len(c.buf) { - err := c.reload() - if err != nil { - return 0, err - } - } - b := c.buf[c.off] - c.off++ - return b, nil -} - -// reload re-fills the scanner's buffer. -func (c *scanner) reload() error { - n, err := c.r.Read(c.buf[:cap(c.buf)]) - c.buf = c.buf[:n] - if err != nil { - if err != io.EOF { - return err - } - if n == 0 { - return io.EOF - } - } - c.off = 0 - return nil -} diff --git a/codec/h264/lex_test.go b/codec/h264/lex_test.go index d584ce18..d2eeae2a 100644 --- a/codec/h264/lex_test.go +++ b/codec/h264/lex_test.go @@ -30,9 +30,6 @@ LICENSE package h264 import ( - "bytes" - "reflect" - "testing" "time" ) @@ -223,50 +220,3 @@ func TestH264(t *testing.T) { } } */ -type chunkEncoder [][]byte - -func (e *chunkEncoder) Encode(b []byte) error { - *e = append(*e, b) - return nil -} - -func (*chunkEncoder) Stream() <-chan []byte { panic("INVALID USE") } - -func TestScannerReadByte(t *testing.T) { - data := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") - - for _, size := range []int{1, 2, 8, 1 << 10} { - r := newScanner(bytes.NewReader(data), make([]byte, size)) - var got []byte - for { - b, err := r.readByte() - if err != nil { - break - } - got = append(got, b) - } - if !bytes.Equal(got, data) { - t.Errorf("unexpected result for buffer size %d:\ngot :%q\nwant:%q", size, got, data) - } - } -} - -func TestScannerScanUntilZero(t *testing.T) { - data := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit,\x00 sed do eiusmod tempor incididunt ut \x00labore et dolore magna aliqua.") - - for _, size := range []int{1, 2, 8, 1 << 10} { - r := newScanner(bytes.NewReader(data), make([]byte, size)) - var got [][]byte - for { - buf, _, err := r.scanUntilZeroInto(nil) - got = append(got, buf) - if err != nil { - break - } - } - want := bytes.SplitAfter(data, []byte{0}) - if !reflect.DeepEqual(got, want) { - t.Errorf("unexpected result for buffer zie %d:\ngot :%q\nwant:%q", size, got, want) - } - } -} diff --git a/codec/mjpeg/lex.go b/codec/mjpeg/lex.go index 09ee2513..da2ecae1 100644 --- a/codec/mjpeg/lex.go +++ b/codec/mjpeg/lex.go @@ -87,70 +87,3 @@ func Lex(dst io.Writer, src io.Reader, delay time.Duration) error { } } } - -// scanner is a byte scanner. -type scanner struct { - buf []byte - off int - - // r is the source of data for the scanner. - r io.Reader -} - -// newScanner returns a scanner initialised with an io.Reader and a read buffer. -func newScanner(r io.Reader, buf []byte) *scanner { - return &scanner{r: r, buf: buf[:0]} -} - -// scanUntilZeroInto scans the scanner's underlying io.Reader until a zero byte -// has been read, appending all read bytes to dst. The resulting appended data, -// the last read byte and whether the last read byte was zero are returned. -func (c *scanner) scanUntilZeroInto(dst []byte) (res []byte, b byte, err error) { -outer: - for { - var i int - for i, b = range c.buf[c.off:] { - if b != 0x0 { - continue - } - dst = append(dst, c.buf[c.off:c.off+i+1]...) - c.off += i + 1 - break outer - } - dst = append(dst, c.buf[c.off:]...) - err = c.reload() - if err != nil { - break - } - } - return dst, b, err -} - -// readByte is an unexported ReadByte. -func (c *scanner) readByte() (byte, error) { - if c.off >= len(c.buf) { - err := c.reload() - if err != nil { - return 0, err - } - } - b := c.buf[c.off] - c.off++ - return b, nil -} - -// reload re-fills the scanner's buffer. -func (c *scanner) reload() error { - n, err := c.r.Read(c.buf[:cap(c.buf)]) - c.buf = c.buf[:n] - if err != nil { - if err != io.EOF { - return err - } - if n == 0 { - return io.EOF - } - } - c.off = 0 - return nil -} diff --git a/codec/mjpeg/lex_test.go b/codec/mjpeg/lex_test.go index 59b4bd25..fd8b6f86 100644 --- a/codec/mjpeg/lex_test.go +++ b/codec/mjpeg/lex_test.go @@ -30,9 +30,6 @@ LICENSE package mjpeg import ( - "bytes" - "reflect" - "testing" "time" ) @@ -115,51 +112,3 @@ func Lex(t *testing.T) { } } */ - -type chunkEncoder [][]byte - -func (e *chunkEncoder) Encode(b []byte) error { - *e = append(*e, b) - return nil -} - -func (*chunkEncoder) Stream() <-chan []byte { panic("INVALID USE") } - -func TestScannerReadByte(t *testing.T) { - data := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") - - for _, size := range []int{1, 2, 8, 1 << 10} { - r := newScanner(bytes.NewReader(data), make([]byte, size)) - var got []byte - for { - b, err := r.readByte() - if err != nil { - break - } - got = append(got, b) - } - if !bytes.Equal(got, data) { - t.Errorf("unexpected result for buffer size %d:\ngot :%q\nwant:%q", size, got, data) - } - } -} - -func TestScannerScanUntilZero(t *testing.T) { - data := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit,\x00 sed do eiusmod tempor incididunt ut \x00labore et dolore magna aliqua.") - - for _, size := range []int{1, 2, 8, 1 << 10} { - r := newScanner(bytes.NewReader(data), make([]byte, size)) - var got [][]byte - for { - buf, _, err := r.scanUntilZeroInto(nil) - got = append(got, buf) - if err != nil { - break - } - } - want := bytes.SplitAfter(data, []byte{0}) - if !reflect.DeepEqual(got, want) { - t.Errorf("unexpected result for buffer zie %d:\ngot :%q\nwant:%q", size, got, want) - } - } -}