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