All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.shark.internal.ByteSubArray.kt Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-8
Show newest version
package shark.internal

/**
 * Provides read access to a sub part of a larger array.
 */
internal class ByteSubArray(
  private val array: ByteArray,
  private val rangeStart: Int,
  size: Int,
  private val longIdentifiers: Boolean
) {

  private val endInclusive = size - 1

  private var currentIndex = 0

  fun readByte(): Byte {
    val index = currentIndex
    currentIndex++
    require(index in 0..endInclusive) {
      "Index $index should be between 0 and $endInclusive"
    }
    return array[rangeStart + index]
  }

  fun readId(): Long {
    return if (longIdentifiers) {
      readLong()
    } else {
      readInt().toLong()
    }
  }

  fun readInt(): Int {
    val index = currentIndex
    currentIndex += 4
    require(index >= 0 && index <= endInclusive - 3) {
      "Index $index should be between 0 and ${endInclusive - 3}"
    }
    return array.readInt(rangeStart + index)
  }

  fun readTruncatedLong(byteCount: Int): Long {
    val index = currentIndex
    currentIndex += byteCount
    require(index >= 0 && index <= endInclusive - (byteCount - 1)) {
      "Index $index should be between 0 and ${endInclusive - (byteCount - 1)}"
    }
    var pos = rangeStart + index
    val array = array

    var value = 0L

    var shift = (byteCount - 1) * 8
    while (shift >= 8) {
      value = value or (array[pos++] and 0xffL shl shift)
      shift -= 8
    }
    value = value or (array[pos] and 0xffL)
    return value
  }

  fun readLong(): Long {
    val index = currentIndex
    currentIndex += 8
    require(index >= 0 && index <= endInclusive - 7) {
      "Index $index should be between 0 and ${endInclusive - 7}"
    }
    return array.readLong(rangeStart + index)
  }
}

internal fun ByteArray.readShort(index: Int): Short {
  var pos = index
  val array = this
  val valueAsInt = array[pos++] and 0xff shl 8 or (array[pos] and 0xff)
  return valueAsInt.toShort()
}

internal fun ByteArray.readInt(index: Int): Int {
  var pos = index
  val array = this
  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))
}

internal fun ByteArray.readLong(index: Int): Long {
  var pos = index
  val array = this
  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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy