golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/trace/internal/raw/reader.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 "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 // Reader parses trace bytes with only very basic validation 22 // into an event stream. 23 type Reader struct { 24 r *bufio.Reader 25 v version.Version 26 specs []event.Spec 27 } 28 29 // NewReader creates a new reader for the trace wire format. 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 // Version returns the version of the trace that we're reading. 40 func (r *Reader) Version() version.Version { 41 return r.v 42 } 43 44 // ReadEvent reads and returns the next trace event in the byte stream. 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 // Each stack frame has four args: pc, func ID, file ID, line number. 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 }