1
2
3
4
5 package trace
6
7 import (
8 "fmt"
9 "unsafe"
10 )
11
12
13 type Value struct {
14 kind ValueKind
15 pointer unsafe.Pointer
16 scalar uint64
17 }
18
19
20 type ValueKind uint8
21
22 const (
23 ValueBad ValueKind = iota
24 ValueUint64
25 ValueString
26 )
27
28
29
30
31
32
33
34 func (v Value) Kind() ValueKind {
35 return v.kind
36 }
37
38
39
40
41 func (v Value) ToUint64() uint64 {
42 if v.kind != ValueUint64 {
43 panic("ToUint64 called on Value of a different Kind")
44 }
45 return v.scalar
46 }
47
48
49
50
51 func (v Value) ToString() string {
52 if v.kind != ValueString {
53 panic("ToString called on Value of a different Kind")
54 }
55 return unsafe.String((*byte)(v.pointer), int(v.scalar))
56 }
57
58 func uint64Value(x uint64) Value {
59 return Value{kind: ValueUint64, scalar: x}
60 }
61
62 func stringValue(s string) Value {
63 return Value{kind: ValueString, scalar: uint64(len(s)), pointer: unsafe.Pointer(unsafe.StringData(s))}
64 }
65
66
67 func (v Value) String() string {
68 switch v.Kind() {
69 case ValueUint64:
70 return fmt.Sprintf("Value{Uint64(%d)}", v.ToUint64())
71 case ValueString:
72 return fmt.Sprintf("Value{String(%s)}", v.ToString())
73 }
74 return "Value{Bad}"
75 }
76
View as plain text