xref: /aosp_15_r20/external/leakcanary2/shark-graph/src/main/java/shark/HeapValue.kt (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)
1 package shark
2 
3 import shark.ValueHolder.BooleanHolder
4 import shark.ValueHolder.ByteHolder
5 import shark.ValueHolder.CharHolder
6 import shark.ValueHolder.DoubleHolder
7 import shark.ValueHolder.FloatHolder
8 import shark.ValueHolder.IntHolder
9 import shark.ValueHolder.LongHolder
10 import shark.ValueHolder.ReferenceHolder
11 import shark.ValueHolder.ShortHolder
12 
13 /**
14  * Represents a value in the heap dump, which can be an object reference or
15  * a primitive type.
16  */
17 class HeapValue(
18   /**
19    * The graph of objects in the heap, which you can use to navigate the heap.
20    */
21   val graph: HeapGraph,
22   /**
23    * Holds the actual value that this [HeapValue] represents.
24    */
25   val holder: ValueHolder
26 ) {
27 
28   /**
29    * This [HeapValue] as a [Boolean] if it represents one, or null otherwise.
30    */
31   val asBoolean: Boolean?
32     get() = if (holder is BooleanHolder) holder.value else null
33 
34   /**
35    * This [HeapValue] as a [Char] if it represents one, or null otherwise.
36    */
37   val asChar: Char?
38     get() = if (holder is CharHolder) holder.value else null
39 
40   /**
41    * This [HeapValue] as a [Float] if it represents one, or null otherwise.
42    */
43   val asFloat: Float?
44     get() = if (holder is FloatHolder) holder.value else null
45 
46   /**
47    * This [HeapValue] as a [Double] if it represents one, or null otherwise.
48    */
49   val asDouble: Double?
50     get() = if (holder is DoubleHolder) holder.value else null
51 
52   /**
53    * This [HeapValue] as a [Byte] if it represents one, or null otherwise.
54    */
55   val asByte: Byte?
56     get() = if (holder is ByteHolder) holder.value else null
57 
58   /**
59    * This [HeapValue] as a [Short] if it represents one, or null otherwise.
60    */
61   val asShort: Short?
62     get() = if (holder is ShortHolder) holder.value else null
63 
64   /**
65    * This [HeapValue] as an [Int] if it represents one, or null otherwise.
66    */
67   val asInt: Int?
68     get() = if (holder is IntHolder) holder.value else null
69 
70   /**
71    * This [HeapValue] as a [Long] if it represents one, or null otherwise.
72    */
73   val asLong: Long?
74     get() = if (holder is LongHolder) holder.value else null
75 
76   /**
77    * This [HeapValue] as a [Long] if it represents an object reference, or null otherwise.
78    */
79   val asObjectId: Long?
80     get() = if (holder is ReferenceHolder) holder.value else null
81 
82   /**
83    * This [HeapValue] as a [Long] if it represents a non null object reference, or null otherwise.
84    */
85   val asNonNullObjectId: Long?
86     get() = if (holder is ReferenceHolder && !holder.isNull) holder.value else null
87 
88   /**
89    * True is this [HeapValue] represents a null object reference, false otherwise.
90    */
91   val isNullReference: Boolean
92     get() = holder is ReferenceHolder && holder.isNull
93 
94   /**
95    * True is this [HeapValue] represents a non null object reference, false otherwise.
96    */
97   val isNonNullReference: Boolean
98     get() = holder is ReferenceHolder && !holder.isNull
99 
100   /**
101    * The [HeapObject] referenced by this [HeapValue] if it represents a non null object reference,
102    * or null otherwise.
103    */
104   val asObject: HeapObject?
105     get() {
106       return if (holder is ReferenceHolder && !holder.isNull) {
107         return graph.findObjectById(holder.value)
108       } else {
109         null
110       }
111     }
112 
113   /**
114    * If this [HeapValue] if it represents a non null object reference to an instance of the
115    * [String] class that exists in the heap dump, returns a [String] instance with content that
116    * matches the string in the heap dump. Otherwise returns null.
117    *
118    * This may trigger IO reads.
119    */
readAsJavaStringnull120   fun readAsJavaString(): String? {
121     if (holder is ReferenceHolder && !holder.isNull) {
122       val heapObject = graph.findObjectByIdOrNull(holder.value)
123       return heapObject?.asInstance?.readAsJavaString()
124     }
125     return null
126   }
127 }
128