diff --git a/main.go b/main.go index fb533fb..fa18eb8 100644 --- a/main.go +++ b/main.go @@ -69,7 +69,7 @@ func main() { } p := newParser(r) - if _, err := p.checkHeader(); err != nil { + if err := p.start(); err != nil { bail(1, "parse error: %v", err) } } diff --git a/parser.go b/parser.go index 7788b4e..dfa01c9 100644 --- a/parser.go +++ b/parser.go @@ -8,17 +8,39 @@ import ( type parser struct { // the source of replay bytes. Must NOT be compressed. source io.Reader + + // re-useable scratch buffer. Contents never guaranteed to be clean. + scratch []byte } func newParser(r io.Reader) *parser { - return &parser{source: r} + return &parser{source: r, scratch: make([]byte, 1<<10)} +} + +func (p *parser) start() error { + ok, err := p.checkHeader() + if err != nil { + return fmt.Errorf("parser start error: %v", err) + } + if !ok { + return fmt.Errorf("parser start error: invalid header") + } + return nil } // checks whether we have an acceptable header at the current reader position. func (p *parser) checkHeader() (bool, error) { - buf := make([]byte, 8) + buf := p.scratch[:8] if _, err := p.source.Read(buf); err != nil { return false, fmt.Errorf("unable to read header bytes: %v", err) } return string(buf) == replay_header, nil } + +// skips n bytes in the underlying source +func (p *parser) skip(n int) error { + if _, err := p.source.Read(p.scratch[:n]); err != nil { + return fmt.Errorf("unable to skip %d bytes: %v", n, err) + } + return nil +}