value.mx raw

   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 trace
   6  
   7  import (
   8  	"fmt"
   9  	"unsafe"
  10  )
  11  
  12  // Value is a dynamically-typed value obtained from a trace.
  13  type Value struct {
  14  	kind    ValueKind
  15  	pointer unsafe.Pointer
  16  	scalar  uint64
  17  }
  18  
  19  // ValueKind is the type of a dynamically-typed value from a trace.
  20  type ValueKind uint8
  21  
  22  const (
  23  	ValueBad ValueKind = iota
  24  	ValueUint64
  25  	ValueString
  26  )
  27  
  28  // Kind returns the ValueKind of the value.
  29  //
  30  // It represents the underlying structure of the value.
  31  //
  32  // New ValueKinds may be added in the future. Users of this type must be robust
  33  // to that possibility.
  34  func (v Value) Kind() ValueKind {
  35  	return v.kind
  36  }
  37  
  38  // Uint64 returns the uint64 value for a ValueUint64.
  39  //
  40  // Panics if this Value's Kind is not ValueUint64.
  41  func (v Value) Uint64() uint64 {
  42  	if v.kind != ValueUint64 {
  43  		panic("Uint64 called on Value of a different Kind")
  44  	}
  45  	return v.scalar
  46  }
  47  
  48  // String returns the string value for a ValueString, and otherwise
  49  // a string representation of the value for other kinds of values.
  50  func (v Value) String() string {
  51  	if v.kind == ValueString {
  52  		return unsafe.String((*byte)(v.pointer), int(v.scalar))
  53  	}
  54  	switch v.kind {
  55  	case ValueUint64:
  56  		return fmt.Sprintf("Value{Uint64(%d)}", v.Uint64())
  57  	}
  58  	return "Value{Bad}"
  59  }
  60  
  61  func uint64Value(x uint64) Value {
  62  	return Value{kind: ValueUint64, scalar: x}
  63  }
  64  
  65  func stringValue(s []byte) Value {
  66  	return Value{kind: ValueString, scalar: uint64(len(s)), pointer: unsafe.Pointer(unsafe.StringData(s))}
  67  }
  68