1package trace
2
3import "bytes"
4
5// Writer is a test trace writer.
6type Writer struct {
7	bytes.Buffer
8}
9
10func NewWriter() *Writer {
11	w := new(Writer)
12	w.Write([]byte("go 1.9 trace\x00\x00\x00\x00"))
13	return w
14}
15
16// Emit writes an event record to the trace.
17// See Event types for valid types and required arguments.
18func (w *Writer) Emit(typ byte, args ...uint64) {
19	nargs := byte(len(args)) - 1
20	if nargs > 3 {
21		nargs = 3
22	}
23	buf := []byte{typ | nargs<<6}
24	if nargs == 3 {
25		buf = append(buf, 0)
26	}
27	for _, a := range args {
28		buf = appendVarint(buf, a)
29	}
30	if nargs == 3 {
31		buf[1] = byte(len(buf) - 2)
32	}
33	n, err := w.Write(buf)
34	if n != len(buf) || err != nil {
35		panic("failed to write")
36	}
37}
38
39func appendVarint(buf []byte, v uint64) []byte {
40	for ; v >= 0x80; v >>= 7 {
41		buf = append(buf, 0x80|byte(v))
42	}
43	buf = append(buf, byte(v))
44	return buf
45}
46