EOF handling

master
Jordan Orelli 8 years ago
parent 68cfde6207
commit a06c68d2e7

@ -32,6 +32,13 @@ func bail(status int, t string, args ...interface{}) {
os.Exit(status) os.Exit(status)
} }
func wrap(err error, t string, args ...interface{}) error {
if err == io.EOF {
return io.EOF
}
return fmt.Errorf(t+": %v", append(args, err)...)
}
type options struct { type options struct {
b bool // bzip compression flag b bool // bzip compression flag
v bool // verbose flag v bool // verbose flag
@ -45,7 +52,7 @@ func (o options) input() (io.Reader, error) {
} else { } else {
fi, err := os.Open(o.f) fi, err := os.Open(o.f)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to open file %s: %v", o.f, err) return nil, wrap(err, "unable to open file %s", o.f)
} }
r = fi r = fi
} }
@ -72,5 +79,7 @@ func main() {
if err := p.start(); err != nil { if err := p.start(); err != nil {
bail(1, "parse error: %v", err) bail(1, "parse error: %v", err)
} }
p.run() if err := p.run(); err != nil && err != io.EOF {
bail(1, "run error: %v", err)
}
} }

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"io" "io"
// "github.com/golang/protobuf/proto"
) )
type parser struct { type parser struct {
@ -23,23 +22,22 @@ func newParser(r io.Reader) *parser {
func (p *parser) start() error { func (p *parser) start() error {
ok, err := p.checkHeader() ok, err := p.checkHeader()
if err != nil { if err != nil {
return fmt.Errorf("parser start error: %v", err) return wrap(err, "parser start error")
} }
if !ok { if !ok {
return fmt.Errorf("parser start error: invalid header") return fmt.Errorf("parser start error: invalid header")
} }
if _, err := p.source.Discard(8); err != nil { if _, err := p.source.Discard(8); err != nil {
return err return wrap(err, "parser start error")
} }
return nil return nil
} }
func (p *parser) run() { func (p *parser) run() error {
for { for {
msg, err := p.readMessage() msg, err := p.readMessage()
if err != nil { if err != nil {
fmt.Printf("error: %v\n", err) return wrap(err, "read message error in run loop")
return
} }
fmt.Println(msg) fmt.Println(msg)
} }
@ -58,7 +56,7 @@ func (p *parser) decodeVarint() (uint64, error) {
// would require 10 bytes. // would require 10 bytes.
buf, err := p.source.Peek(10) buf, err := p.source.Peek(10)
if err != nil { if err != nil {
return 0, fmt.Errorf("decode varint couldn't peek 9 bytes: %v", err) return 0, wrap(err, "decode varint couldn't peek 10 bytes")
} }
var x uint64 var x uint64
@ -67,7 +65,7 @@ func (p *parser) decodeVarint() (uint64, error) {
// when msb is 0, we're at the last byte of the value // when msb is 0, we're at the last byte of the value
if b < 0x80 { if b < 0x80 {
if _, err := p.source.Discard(i + 1); err != nil { if _, err := p.source.Discard(i + 1); err != nil {
return 0, fmt.Errorf("decode varint couldn't discard %d bytes: %v", i, err) return 0, wrap(err, "decode varint couldn't discard %d bytes", i)
} }
return x | uint64(b)<<s, nil return x | uint64(b)<<s, nil
} }
@ -90,7 +88,7 @@ func (p *parser) readn(n int) ([]byte, error) {
} }
buf := p.scratch[:n] buf := p.scratch[:n]
if _, err := io.ReadFull(p.source, buf); err != nil { if _, err := io.ReadFull(p.source, buf); err != nil {
return nil, fmt.Errorf("error reading %d bytes: %v", n, err) return nil, wrap(err, "error reading %d bytes", n)
} }
return buf, nil return buf, nil
} }
@ -99,7 +97,7 @@ func (p *parser) readn(n int) ([]byte, error) {
func (p *parser) checkHeader() (bool, error) { func (p *parser) checkHeader() (bool, error) {
buf, err := p.readn(8) buf, err := p.readn(8)
if err != nil { if err != nil {
return false, fmt.Errorf("unable to read header bytes: %v", err) return false, wrap(err, "unable to read header bytes")
} }
return string(buf) == replayHeader, nil return string(buf) == replayHeader, nil
} }
@ -107,7 +105,7 @@ func (p *parser) checkHeader() (bool, error) {
func (p *parser) readCommand() (EDemoCommands, bool, error) { func (p *parser) readCommand() (EDemoCommands, bool, error) {
n, err := p.decodeVarint() n, err := p.decodeVarint()
if err != nil { if err != nil {
return EDemoCommands_DEM_Error, false, fmt.Errorf("readCommand couldn't read varint: %v", err) return EDemoCommands_DEM_Error, false, wrap(err, "readCommand couldn't read varint")
} }
compressed := false compressed := false
@ -135,23 +133,23 @@ func (m *message) String() string {
func (p *parser) readMessage() (*message, error) { func (p *parser) readMessage() (*message, error) {
cmd, compressed, err := p.readCommand() cmd, compressed, err := p.readCommand()
if err != nil { if err != nil {
return nil, fmt.Errorf("readMessage couldn't get a command: %v", err) return nil, wrap(err, "readMessage couldn't get a command")
} }
tick, err := p.decodeVarint() tick, err := p.decodeVarint()
if err != nil { if err != nil {
return nil, fmt.Errorf("readMessage couldn't read the tick value: %v", err) return nil, wrap(err, "readMessage couldn't read the tick value")
} }
size, err := p.decodeVarint() size, err := p.decodeVarint()
if err != nil { if err != nil {
return nil, fmt.Errorf("readMessage couldn't read the size value: %v", err) return nil, wrap(err, "readMessage couldn't read the size value")
} }
if size > 0 { if size > 0 {
buf, err := p.readn(int(size)) buf, err := p.readn(int(size))
if err != nil { if err != nil {
return nil, fmt.Errorf("readMessage couldn't read message body: %v", err) return nil, wrap(err, "readMessage couldn't read message body")
} }
return &message{cmd, int64(tick), compressed, buf}, nil return &message{cmd, int64(tick), compressed, buf}, nil
} }

Loading…
Cancel
Save