FieldIdReader.kt
TLDR
This file contains the implementation of a FieldIdReader
class that is a simplified version of the FieldValuesReader
class. It provides methods to read an ID or skip a certain number of bytes.
Methods
readId
This method reads the ID value from the field values array based on the identifier byte size specified. It returns the read value and updates the position.
skipBytes
This method advances the position by the specified number of bytes.
Classes
FieldIdReader
This class represents a simplified version of the FieldValuesReader
class. It provides methods to read an ID or skip a certain number of bytes.
package shark.internal
import shark.HprofRecord.HeapDumpRecord.ObjectRecord.InstanceDumpRecord
/**
* Simplified version of [FieldValuesReader] class that can only read an ID or skip a certain
* amount of bytes.
*/
internal class FieldIdReader(
private val record: InstanceDumpRecord,
private val identifierByteSize: Int
) {
private var position = 0
fun readId(): Long {
// As long as we don't interpret IDs, reading signed values here is fine.
val value = when (identifierByteSize) {
1 -> readByteId(position, record.fieldValues)
2 -> readShortId(position, record.fieldValues)
4 -> readIntId(position, record.fieldValues)
8 -> readLongId(position, record.fieldValues)
else -> error("ID Length must be 1, 2, 4, or 8")
}
position += identifierByteSize
return value
}
fun skipBytes(count: Int) {
position += count
}
private fun readByteId(
index: Int,
array: ByteArray
) =
array[index].toLong()
private fun readShortId(
index: Int,
array: ByteArray
): Long {
var pos = index
return (array[pos++] and 0xff shl 8
or (array[pos] and 0xff)).toLong()
}
private fun readIntId(
index: Int,
array: ByteArray
): Long {
var pos = index
return (array[pos++] and 0xff shl 24
or (array[pos++] and 0xff shl 16)
or (array[pos++] and 0xff shl 8)
or (array[pos] and 0xff)).toLong()
}
private fun readLongId(
index: Int,
array: ByteArray
): Long {
var pos = index
return (array[pos++] and 0xffL shl 56
or (array[pos++] and 0xffL shl 48)
or (array[pos++] and 0xffL shl 40)
or (array[pos++] and 0xffL shl 32)
or (array[pos++] and 0xffL shl 24)
or (array[pos++] and 0xffL shl 16)
or (array[pos++] and 0xffL shl 8)
or (array[pos] and 0xffL))
}
@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
private inline infix fun Byte.and(other: Long): Long = toLong() and other
@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
private inline infix fun Byte.and(other: Int): Int = toInt() and other
}