Skip to content

Commit af4be3d

Browse files
committed
add Parse() & ParseFile() utility funcs
1 parent b43555e commit af4be3d

File tree

3 files changed

+78
-40
lines changed

3 files changed

+78
-40
lines changed

README.md

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -80,39 +80,32 @@ Check out the [godoc of the `events` package](https://godoc.org/github.com/marku
8080
package main
8181

8282
import (
83-
"fmt"
8483
"log"
85-
"os"
8684

87-
dem "github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs"
85+
demoinfocs "github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs"
8886
events "github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs/events"
8987
)
9088

9189
func main() {
92-
f, err := os.Open("/path/to/demo.dem")
93-
if err != nil {
94-
log.Panic("failed to open demo file: ", err)
95-
}
96-
defer f.Close()
97-
98-
p := dem.NewParser(f)
99-
defer p.Close()
100-
101-
// Register handler on kill events
102-
p.RegisterEventHandler(func(e events.Kill) {
90+
onKill := func(kill events.Kill) {
10391
var hs string
104-
if e.IsHeadshot {
92+
if kill.IsHeadshot {
10593
hs = " (HS)"
10694
}
95+
10796
var wallBang string
108-
if e.PenetratedObjects > 0 {
97+
if kill.PenetratedObjects > 0 {
10998
wallBang = " (WB)"
11099
}
111-
fmt.Printf("%s <%v%s%s> %s\n", e.Killer, e.Weapon, hs, wallBang, e.Victim)
112-
})
113100

114-
// Parse to end
115-
err = p.ParseToEnd()
101+
log.Printf("%s <%v%s%s> %s\n", kill.Killer, kill.Weapon, hs, wallBang, kill.Victim)
102+
}
103+
104+
err := demoinfocs.ParseFile("/path/to/demo.dem", func(p demoinfocs.Parser) error {
105+
p.RegisterEventHandler(onKill)
106+
107+
return nil
108+
})
116109
if err != nil {
117110
log.Panic("failed to parse demo: ", err)
118111
}

pkg/demoinfocs/examples_test.go

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package demoinfocs_test
22

33
import (
4-
"fmt"
54
"log"
6-
"os"
75
"testing"
86

97
demoinfocs "github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs"
@@ -15,33 +13,25 @@ This will print all kills of a demo in the format '[[killer]] <[[weapon]] [(HS)]
1513
*/
1614
//noinspection GoUnhandledErrorResult
1715
func ExampleParser() {
18-
f, err := os.Open("../../test/cs-demos/s2/s2.dem")
19-
if err != nil {
20-
log.Panic("failed to open demo file: ", err)
21-
}
22-
23-
defer f.Close()
24-
25-
p := demoinfocs.NewParser(f)
26-
defer p.Close()
27-
28-
// Register handler on kill events
29-
p.RegisterEventHandler(func(e events.Kill) {
16+
onKill := func(kill events.Kill) {
3017
var hs string
31-
if e.IsHeadshot {
18+
if kill.IsHeadshot {
3219
hs = " (HS)"
3320
}
3421

3522
var wallBang string
36-
if e.PenetratedObjects > 0 {
23+
if kill.PenetratedObjects > 0 {
3724
wallBang = " (WB)"
3825
}
3926

40-
fmt.Printf("%s <%v%s%s> %s\n", e.Killer, e.Weapon, hs, wallBang, e.Victim)
41-
})
27+
log.Printf("%s <%v%s%s> %s\n", kill.Killer, kill.Weapon, hs, wallBang, kill.Victim)
28+
}
4229

43-
// Parse to end
44-
err = p.ParseToEnd()
30+
err := demoinfocs.ParseFile("../../test/cs-demos/s2/s2.dem", func(p demoinfocs.Parser) error {
31+
p.RegisterEventHandler(onKill)
32+
33+
return nil
34+
})
4535
if err != nil {
4636
log.Panic("failed to parse demo: ", err)
4737
}

pkg/demoinfocs/parser.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
_ "embed"
55
"fmt"
66
"io"
7+
"os"
78
"runtime/debug"
89
"sync"
910
"time"
@@ -350,6 +351,60 @@ func NewCSTVBroadcastParserWithConfig(baseUrl string, config ParserConfig) (Pars
350351
return NewParserWithConfig(r, config), nil
351352
}
352353

354+
type ConfigureParserCallback func(Parser) error
355+
356+
// ParseWithConfig parses a demo from the given io.Reader with a custom configuration.
357+
// The handler is called with the Parser instance.
358+
//
359+
// Returns an error if the parser encounters an error.
360+
func ParseWithConfig(r io.Reader, config ParserConfig, configure ConfigureParserCallback) error {
361+
p := NewParserWithConfig(r, config)
362+
defer p.Close()
363+
364+
err := configure(p)
365+
if err != nil {
366+
return fmt.Errorf("failed to configure parser: %w", err)
367+
}
368+
369+
err = p.ParseToEnd()
370+
if err != nil {
371+
return fmt.Errorf("failed to parse demo: %w", err)
372+
}
373+
374+
return nil
375+
}
376+
377+
// Parse parses a demo from the given io.Reader.
378+
// The handler is called with the Parser instance.
379+
//
380+
// Returns an error if the parser encounters an error.
381+
func Parse(r io.Reader, configure ConfigureParserCallback) error {
382+
return ParseWithConfig(r, DefaultParserConfig, configure)
383+
}
384+
385+
// ParseFileWithConfig parses a demo file at the given path with a custom configuration.
386+
// The handler is called with the Parser instance.
387+
//
388+
// Returns an error if the file can't be opened or if the parser encounters an error.
389+
func ParseFileWithConfig(path string, config ParserConfig, configure ConfigureParserCallback) error {
390+
f, err := os.Open(path)
391+
if err != nil {
392+
return fmt.Errorf("failed to open file: %w", err)
393+
}
394+
395+
defer f.Close()
396+
397+
return ParseWithConfig(f, config, configure)
398+
}
399+
400+
// ParseFile parses a demo file at the given path.
401+
// The handler is called with the Parser instance.
402+
//
403+
// Returns an error if the file can't be opened or if the parser encounters an error.
404+
func ParseFile(path string, configure ConfigureParserCallback) error {
405+
return ParseFileWithConfig(path, DefaultParserConfig, configure)
406+
}
407+
353408
// ParserConfig contains the configuration for creating a new Parser.
354409
type ParserConfig struct {
355410
// MsgQueueBufferSize defines the size of the internal net-message queue.

0 commit comments

Comments
 (0)