main

square/leakcanary

Last updated at: 29/12/2023 09:39

HeapValue.kt

TLDR

The provided file HeapValue.kt is a Kotlin class in the shark package. It represents a value in a heap dump, which can be an object reference or a primitive type. It contains various properties and methods to work with and manipulate heap values.

Methods

readAsJavaString

This method reads the HeapValue as a Java String if it represents a non-null object reference to an instance of the String class in the heap dump. It returns a String instance with content that matches the string in the heap dump. If the HeapValue does not represent a valid object reference or the referenced object is not a String instance, it returns null.

Classes

None

package shark

import shark.ValueHolder.BooleanHolder
import shark.ValueHolder.ByteHolder
import shark.ValueHolder.CharHolder
import shark.ValueHolder.DoubleHolder
import shark.ValueHolder.FloatHolder
import shark.ValueHolder.IntHolder
import shark.ValueHolder.LongHolder
import shark.ValueHolder.ReferenceHolder
import shark.ValueHolder.ShortHolder

/**
 * Represents a value in the heap dump, which can be an object reference or
 * a primitive type.
 */
class HeapValue(
  /**
   * The graph of objects in the heap, which you can use to navigate the heap.
   */
  val graph: HeapGraph,
  /**
   * Holds the actual value that this [HeapValue] represents.
   */
  val holder: ValueHolder
) {

  /**
   * This [HeapValue] as a [Boolean] if it represents one, or null otherwise.
   */
  val asBoolean: Boolean?
    get() = if (holder is BooleanHolder) holder.value else null

  /**
   * This [HeapValue] as a [Char] if it represents one, or null otherwise.
   */
  val asChar: Char?
    get() = if (holder is CharHolder) holder.value else null

  /**
   * This [HeapValue] as a [Float] if it represents one, or null otherwise.
   */
  val asFloat: Float?
    get() = if (holder is FloatHolder) holder.value else null

  /**
   * This [HeapValue] as a [Double] if it represents one, or null otherwise.
   */
  val asDouble: Double?
    get() = if (holder is DoubleHolder) holder.value else null

  /**
   * This [HeapValue] as a [Byte] if it represents one, or null otherwise.
   */
  val asByte: Byte?
    get() = if (holder is ByteHolder) holder.value else null

  /**
   * This [HeapValue] as a [Short] if it represents one, or null otherwise.
   */
  val asShort: Short?
    get() = if (holder is ShortHolder) holder.value else null

  /**
   * This [HeapValue] as an [Int] if it represents one, or null otherwise.
   */
  val asInt: Int?
    get() = if (holder is IntHolder) holder.value else null

  /**
   * This [HeapValue] as a [Long] if it represents one, or null otherwise.
   */
  val asLong: Long?
    get() = if (holder is LongHolder) holder.value else null

  /**
   * This [HeapValue] as a [Long] if it represents an object reference, or null otherwise.
   */
  val asObjectId: Long?
    get() = if (holder is ReferenceHolder) holder.value else null

  /**
   * This [HeapValue] as a [Long] if it represents a non null object reference, or null otherwise.
   */
  val asNonNullObjectId: Long?
    get() = if (holder is ReferenceHolder && !holder.isNull) holder.value else null

  /**
   * True is this [HeapValue] represents a null object reference, false otherwise.
   */
  val isNullReference: Boolean
    get() = holder is ReferenceHolder && holder.isNull

  /**
   * True is this [HeapValue] represents a non null object reference, false otherwise.
   */
  val isNonNullReference: Boolean
    get() = holder is ReferenceHolder && !holder.isNull

  /**
   * The [HeapObject] referenced by this [HeapValue] if it represents a non null object reference,
   * or null otherwise.
   */
  val asObject: HeapObject?
    get() {
      return if (holder is ReferenceHolder && !holder.isNull) {
        return graph.findObjectById(holder.value)
      } else {
        null
      }
    }

  /**
   * If this [HeapValue] if it represents a non null object reference to an instance of the
   * [String] class that exists in the heap dump, returns a [String] instance with content that
   * matches the string in the heap dump. Otherwise returns null.
   *
   * This may trigger IO reads.
   */
  fun readAsJavaString(): String? {
    if (holder is ReferenceHolder && !holder.isNull) {
      val heapObject = graph.findObjectByIdOrNull(holder.value)
      return heapObject?.asInstance?.readAsJavaString()
    }
    return null
  }
}