1
2
3
4
5 package raw
6
7 import (
8 "bufio"
9 "encoding/binary"
10 "fmt"
11 "io"
12
13 "internal/trace/event"
14 "internal/trace/version"
15 )
16
17
18
19 type Reader struct {
20 r *bufio.Reader
21 v version.Version
22 specs []event.Spec
23 }
24
25
26 func NewReader(r io.Reader) (*Reader, error) {
27 br := bufio.NewReader(r)
28 v, err := version.ReadHeader(br)
29 if err != nil {
30 return nil, err
31 }
32 return &Reader{r: br, v: v, specs: v.Specs()}, nil
33 }
34
35
36 func (r *Reader) Version() version.Version {
37 return r.v
38 }
39
40
41 func (r *Reader) ReadEvent() (Event, error) {
42 evb, err := r.r.ReadByte()
43 if err == io.EOF {
44 return Event{}, io.EOF
45 }
46 if err != nil {
47 return Event{}, err
48 }
49 if int(evb) >= len(r.specs) || evb == 0 {
50 return Event{}, fmt.Errorf("invalid event type: %d", evb)
51 }
52 ev := event.Type(evb)
53 spec := r.specs[ev]
54 args, err := r.readArgs(len(spec.Args))
55 if err != nil {
56 return Event{}, err
57 }
58 if spec.IsStack {
59 len := int(args[1])
60 for i := 0; i < len; i++ {
61
62 frame, err := r.readArgs(4)
63 if err != nil {
64 return Event{}, err
65 }
66 args = append(args, frame...)
67 }
68 }
69 var data []byte
70 if spec.HasData {
71 data, err = r.readData()
72 if err != nil {
73 return Event{}, err
74 }
75 }
76 return Event{
77 Version: r.v,
78 Ev: ev,
79 Args: args,
80 Data: data,
81 }, nil
82 }
83
84 func (r *Reader) readArgs(n int) ([]uint64, error) {
85 var args []uint64
86 for i := 0; i < n; i++ {
87 val, err := binary.ReadUvarint(r.r)
88 if err != nil {
89 return nil, err
90 }
91 args = append(args, val)
92 }
93 return args, nil
94 }
95
96 func (r *Reader) readData() ([]byte, error) {
97 len, err := binary.ReadUvarint(r.r)
98 if err != nil {
99 return nil, err
100 }
101 var data []byte
102 for i := 0; i < int(len); i++ {
103 b, err := r.r.ReadByte()
104 if err != nil {
105 return nil, err
106 }
107 data = append(data, b)
108 }
109 return data, nil
110 }
111
View as plain text