1
2
3
4
5 package raw
6
7 import (
8 "encoding/binary"
9 "fmt"
10 "io"
11
12 "internal/trace/event"
13 "internal/trace/version"
14 )
15
16
17
18
19
20
21
22 type Writer struct {
23 w io.Writer
24 buf []byte
25 v version.Version
26 specs []event.Spec
27 }
28
29
30 func NewWriter(w io.Writer, v version.Version) (*Writer, error) {
31 _, err := version.WriteHeader(w, v)
32 return &Writer{w: w, v: v, specs: v.Specs()}, err
33 }
34
35
36 func (w *Writer) WriteEvent(e Event) error {
37
38 if e.Version != w.v {
39 return fmt.Errorf("mismatched version between writer (go 1.%d) and event (go 1.%d)", w.v, e.Version)
40 }
41
42
43 w.buf = append(w.buf, uint8(e.Ev))
44
45
46 spec := w.specs[e.Ev]
47 for _, arg := range e.Args[:len(spec.Args)] {
48 w.buf = binary.AppendUvarint(w.buf, arg)
49 }
50 if spec.IsStack {
51 frameArgs := e.Args[len(spec.Args):]
52 for i := 0; i < len(frameArgs); i++ {
53 w.buf = binary.AppendUvarint(w.buf, frameArgs[i])
54 }
55 }
56
57
58 if spec.HasData {
59 w.buf = binary.AppendUvarint(w.buf, uint64(len(e.Data)))
60 }
61
62
63 _, err := w.w.Write(w.buf)
64 w.buf = w.buf[:0]
65 if err != nil {
66 return err
67 }
68
69
70 if spec.HasData {
71 _, err := w.w.Write(e.Data)
72 return err
73 }
74 return nil
75 }
76
View as plain text