Source file src/internal/trace/raw/reader.go

     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  package raw
     6  
     7  import (
     8  	"bufio"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"io"
    12  
    13  	"internal/trace/event"
    14  	"internal/trace/version"
    15  )
    16  
    17  // Reader parses trace bytes with only very basic validation
    18  // into an event stream.
    19  type Reader struct {
    20  	r     *bufio.Reader
    21  	v     version.Version
    22  	specs []event.Spec
    23  }
    24  
    25  // NewReader creates a new reader for the trace wire format.
    26  func NewReader(r io.Reader) (*Reader, error) {
    27  	br := bufio.NewReader(r)
    28  	v, err := version.ReadHeader(br)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	return &Reader{r: br, v: v, specs: v.Specs()}, nil
    33  }
    34  
    35  // Version returns the version of the trace that we're reading.
    36  func (r *Reader) Version() version.Version {
    37  	return r.v
    38  }
    39  
    40  // ReadEvent reads and returns the next trace event in the byte stream.
    41  func (r *Reader) ReadEvent() (Event, error) {
    42  	evb, err := r.r.ReadByte()
    43  	if err == io.EOF {
    44  		return Event{}, io.EOF
    45  	}
    46  	if err != nil {
    47  		return Event{}, err
    48  	}
    49  	if int(evb) >= len(r.specs) || evb == 0 {
    50  		return Event{}, fmt.Errorf("invalid event type: %d", evb)
    51  	}
    52  	ev := event.Type(evb)
    53  	spec := r.specs[ev]
    54  	args, err := r.readArgs(len(spec.Args))
    55  	if err != nil {
    56  		return Event{}, err
    57  	}
    58  	if spec.IsStack {
    59  		len := int(args[1])
    60  		for i := 0; i < len; i++ {
    61  			// Each stack frame has four args: pc, func ID, file ID, line number.
    62  			frame, err := r.readArgs(4)
    63  			if err != nil {
    64  				return Event{}, err
    65  			}
    66  			args = append(args, frame...)
    67  		}
    68  	}
    69  	var data []byte
    70  	if spec.HasData {
    71  		data, err = r.readData()
    72  		if err != nil {
    73  			return Event{}, err
    74  		}
    75  	}
    76  	return Event{
    77  		Version: r.v,
    78  		Ev:      ev,
    79  		Args:    args,
    80  		Data:    data,
    81  	}, nil
    82  }
    83  
    84  func (r *Reader) readArgs(n int) ([]uint64, error) {
    85  	var args []uint64
    86  	for i := 0; i < n; i++ {
    87  		val, err := binary.ReadUvarint(r.r)
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  		args = append(args, val)
    92  	}
    93  	return args, nil
    94  }
    95  
    96  func (r *Reader) readData() ([]byte, error) {
    97  	len, err := binary.ReadUvarint(r.r)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	var data []byte
   102  	for i := 0; i < int(len); i++ {
   103  		b, err := r.r.ReadByte()
   104  		if err != nil {
   105  			return nil, err
   106  		}
   107  		data = append(data, b)
   108  	}
   109  	return data, nil
   110  }
   111  

View as plain text