golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/trace/internal/raw/writer.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Code generated by "gen.bash" from internal/trace/v2; DO NOT EDIT. 6 7 //go:build go1.21 8 9 package raw 10 11 import ( 12 "encoding/binary" 13 "fmt" 14 "io" 15 16 "golang.org/x/exp/trace/internal/event" 17 "golang.org/x/exp/trace/internal/version" 18 ) 19 20 // Writer emits the wire format of a trace. 21 // 22 // It may not produce a byte-for-byte compatible trace from what is 23 // produced by the runtime, because it may be missing extra padding 24 // in the LEB128 encoding that the runtime adds but isn't necessary 25 // when you know the data up-front. 26 type Writer struct { 27 w io.Writer 28 buf []byte 29 v version.Version 30 specs []event.Spec 31 } 32 33 // NewWriter creates a new byte format writer. 34 func NewWriter(w io.Writer, v version.Version) (*Writer, error) { 35 _, err := version.WriteHeader(w, v) 36 return &Writer{w: w, v: v, specs: v.Specs()}, err 37 } 38 39 // WriteEvent writes a single event to the trace wire format stream. 40 func (w *Writer) WriteEvent(e Event) error { 41 // Check version. 42 if e.Version != w.v { 43 return fmt.Errorf("mismatched version between writer (go 1.%d) and event (go 1.%d)", w.v, e.Version) 44 } 45 46 // Write event header byte. 47 w.buf = append(w.buf, uint8(e.Ev)) 48 49 // Write out all arguments. 50 spec := w.specs[e.Ev] 51 for _, arg := range e.Args[:len(spec.Args)] { 52 w.buf = binary.AppendUvarint(w.buf, arg) 53 } 54 if spec.IsStack { 55 frameArgs := e.Args[len(spec.Args):] 56 for i := 0; i < len(frameArgs); i++ { 57 w.buf = binary.AppendUvarint(w.buf, frameArgs[i]) 58 } 59 } 60 61 // Write out the length of the data. 62 if spec.HasData { 63 w.buf = binary.AppendUvarint(w.buf, uint64(len(e.Data))) 64 } 65 66 // Write out varint events. 67 _, err := w.w.Write(w.buf) 68 w.buf = w.buf[:0] 69 if err != nil { 70 return err 71 } 72 73 // Write out data. 74 if spec.HasData { 75 _, err := w.w.Write(e.Data) 76 return err 77 } 78 return nil 79 }