diff --git a/datagram.go b/datagram.go index 3ec0df2..63712b6 100644 --- a/datagram.go +++ b/datagram.go @@ -21,12 +21,13 @@ func (g dataGram) String() string { return fmt.Sprintf("{dataGram cmd: %v tick: %v size: %d body: %x}", g.cmd, g.tick, len(g.body), g.body) } -func (g *dataGram) Open(m *messageFactory) (proto.Message, error) { +func (g *dataGram) Open(m *messageFactory, pbuf *proto.Buffer) (proto.Message, error) { msg, err := m.BuildDatagram(g.cmd) if err != nil { return nil, err } - if err := proto.Unmarshal(g.body, msg); err != nil { + pbuf.SetBuf(g.body) + if err := pbuf.Unmarshal(msg); err != nil { return nil, err } return msg, nil diff --git a/parser.go b/parser.go index c50afe0..7f02bc0 100644 --- a/parser.go +++ b/parser.go @@ -17,11 +17,14 @@ type parser struct { dumpDatagrams bool dumpPackets bool + + scratch []byte + pbuf *proto.Buffer } func newParser(r io.Reader) *parser { br := bufio.NewReaderSize(r, 1<<16) - return &parser{source: br} + return &parser{source: br, scratch: make([]byte, 1<<17), pbuf: new(proto.Buffer)} } func (p *parser) start() error { @@ -57,7 +60,7 @@ func (p *parser) handleDataGram(d *dataGram) error { return nil } - msg, err := d.Open(&messages) + msg, err := d.Open(&messages, p.pbuf) if err != nil { fmt.Printf("datagram open error: %v\n", err) return nil @@ -75,8 +78,9 @@ func (p *parser) handleDemoPacket(packet *dota.CDemoPacket) error { for { t := entityType(br.ReadUBitVar()) s := br.ReadVarInt() - b := make([]byte, s) + b := p.scratch[:s] br.Read(b) + p.pbuf.SetBuf(b) switch err := br.Err(); err { case nil: break @@ -93,7 +97,7 @@ func (p *parser) handleDemoPacket(packet *dota.CDemoPacket) error { fmt.Printf("\tskipping entity of size %d, type %s: %v\n", len(b), t, err) continue } - if err := proto.Unmarshal(b, e); err != nil { + if err := p.pbuf.Unmarshal(e); err != nil { fmt.Printf("entity unmarshal error: %v\n", err) } }