Make linter happy, I guess.

This commit is contained in:
KotlinGeekDev
2026-01-16 16:10:58 +01:00
parent a9f6ebde83
commit db536289c4
4 changed files with 508 additions and 517 deletions
@@ -31,33 +31,21 @@ import kotlin.collections.set
actual class LargeCache<K, V> : ICacheOperations<K, V> { actual class LargeCache<K, V> : ICacheOperations<K, V> {
private val concurrentMap = cacheMapOf<K, V>() private val concurrentMap = cacheMapOf<K, V>()
actual fun keys(): Set<K> { actual fun keys(): Set<K> = concurrentMap.keys
return concurrentMap.keys
}
actual fun values(): Iterable<V> { actual fun values(): Iterable<V> = concurrentMap.values
return concurrentMap.values
}
actual fun get(key: K): V? { actual fun get(key: K): V? = concurrentMap[key]
return concurrentMap[key]
}
actual fun remove(key: K): V? { actual fun remove(key: K): V? = concurrentMap.remove(key)
return concurrentMap.remove(key)
}
actual fun isEmpty(): Boolean { actual fun isEmpty(): Boolean = concurrentMap.isEmpty()
return concurrentMap.isEmpty()
}
actual fun clear() { actual fun clear() {
concurrentMap.clear() concurrentMap.clear()
} }
actual fun containsKey(key: K): Boolean { actual fun containsKey(key: K): Boolean = concurrentMap.containsKey(key)
return concurrentMap.containsKey(key)
}
actual fun put( actual fun put(
key: K, key: K,
@@ -84,8 +72,8 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
actual fun createIfAbsent( actual fun createIfAbsent(
key: K, key: K,
builder: (K) -> V, builder: (K) -> V,
): Boolean { ): Boolean =
return runBlocking { runBlocking {
val value = concurrentMap.get(key) val value = concurrentMap.get(key)
if (value != null) { if (value != null) {
false false
@@ -95,49 +83,34 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
concurrentMap[key] == null concurrentMap[key] == null
} }
} }
}
actual override fun size(): Int { actual override fun size(): Int = concurrentMap.size
return concurrentMap.size
}
actual override fun forEach(consumer: ICacheBiConsumer<K, V>) { actual override fun forEach(consumer: ICacheBiConsumer<K, V>) {
concurrentMap.forEach { consumer.accept(it.key, it.value) } concurrentMap.forEach { consumer.accept(it.key, it.value) }
} }
actual override fun filter(consumer: CacheCollectors.BiFilter<K, V>): List<V> { actual override fun filter(consumer: CacheCollectors.BiFilter<K, V>): List<V> =
return concurrentMap concurrentMap
.filter { consumer.filter(it.key, it.value) } .filter { consumer.filter(it.key, it.value) }
.values .values
.toList() .toList()
}
actual override fun filterIntoSet(consumer: CacheCollectors.BiFilter<K, V>): Set<V> { actual override fun filterIntoSet(consumer: CacheCollectors.BiFilter<K, V>): Set<V> =
return concurrentMap concurrentMap
.filter { consumer.filter(it.key, it.value) } .filter { consumer.filter(it.key, it.value) }
.values .values
.toSet() .toSet()
}
actual override fun <R> map(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): List<R> { actual override fun <R> map(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): List<R> = concurrentMap.map { consumer.map(it.key, it.value) }
return concurrentMap.map { consumer.map(it.key, it.value) }
}
actual override fun <R> mapNotNull(consumer: CacheCollectors.BiMapper<K, V, R?>): List<R> { actual override fun <R> mapNotNull(consumer: CacheCollectors.BiMapper<K, V, R?>): List<R> = concurrentMap.mapNotNull { consumer.map(it.key, it.value) }
return concurrentMap.mapNotNull { consumer.map(it.key, it.value) }
}
actual override fun <R> mapNotNullIntoSet(consumer: CacheCollectors.BiMapper<K, V, R?>): Set<R> { actual override fun <R> mapNotNullIntoSet(consumer: CacheCollectors.BiMapper<K, V, R?>): Set<R> = mapNotNull(consumer).toSet()
return mapNotNull(consumer).toSet()
}
actual override fun <R> mapFlatten(consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>): List<R> { actual override fun <R> mapFlatten(consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>): List<R> = concurrentMap.flatMap { consumer.map(it.key, it.value) as Iterable<R> }
return concurrentMap.flatMap { consumer.map(it.key, it.value) as Iterable<R> }
}
actual override fun <R> mapFlattenIntoSet(consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>): Set<R> { actual override fun <R> mapFlattenIntoSet(consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>): Set<R> = mapFlatten(consumer).toSet()
return mapFlatten(consumer).toSet()
}
actual override fun maxOrNullOf( actual override fun maxOrNullOf(
filter: CacheCollectors.BiFilter<K, V>, filter: CacheCollectors.BiFilter<K, V>,
@@ -157,36 +130,22 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
// return concurrentMap.map { consumer.map(it.key, it.value) }.sum() // return concurrentMap.map { consumer.map(it.key, it.value) }.sum()
} }
actual override fun sumOfLong(consumer: CacheCollectors.BiSumOfLong<K, V>): Long { actual override fun sumOfLong(consumer: CacheCollectors.BiSumOfLong<K, V>): Long = concurrentMap.sumOfLong(consumer)
return concurrentMap.sumOfLong(consumer)
}
actual override fun <R> groupBy(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): Map<R, List<V>> { actual override fun <R> groupBy(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): Map<R, List<V>> = concurrentMap.groupBy(consumer)
return concurrentMap.groupBy(consumer)
}
actual override fun <R> countByGroup(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): Map<R, Int> { actual override fun <R> countByGroup(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): Map<R, Int> = concurrentMap.countByGroup(consumer)
return concurrentMap.countByGroup(consumer)
}
actual override fun <R> sumByGroup( actual override fun <R> sumByGroup(
groupMap: CacheCollectors.BiNotNullMapper<K, V, R>, groupMap: CacheCollectors.BiNotNullMapper<K, V, R>,
sumOf: CacheCollectors.BiNotNullMapper<K, V, Long>, sumOf: CacheCollectors.BiNotNullMapper<K, V, Long>,
): Map<R, Long> { ): Map<R, Long> = concurrentMap.sumByGroup(groupMap, sumOf)
return concurrentMap.sumByGroup(groupMap, sumOf)
}
actual override fun count(consumer: CacheCollectors.BiFilter<K, V>): Int { actual override fun count(consumer: CacheCollectors.BiFilter<K, V>): Int = concurrentMap.count { consumer.filter(it.key, it.value) }
return concurrentMap.count { consumer.filter(it.key, it.value) }
}
actual override fun <T, U> associate(transform: (K, V) -> Pair<T, U>): Map<T, U> { actual override fun <T, U> associate(transform: (K, V) -> Pair<T, U>): Map<T, U> = concurrentMap.associate(transform)
return concurrentMap.associate(transform)
}
actual override fun <U> associateWith(transform: (K, V) -> U?): Map<K, U?> { actual override fun <U> associateWith(transform: (K, V) -> U?): Map<K, U?> = concurrentMap.associateWith(transform)
return concurrentMap.associateWith(transform)
}
actual override fun filter( actual override fun filter(
from: K, from: K,
@@ -201,9 +160,7 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiFilter<K, V>, consumer: CacheCollectors.BiFilter<K, V>,
): Set<V> { ): Set<V> = filter(from, to, consumer).toSet()
return filter(from, to, consumer).toSet()
}
actual override fun <R> map( actual override fun <R> map(
from: K, from: K,
@@ -218,33 +175,25 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiMapper<K, V, R?>, consumer: CacheCollectors.BiMapper<K, V, R?>,
): List<R> { ): List<R> = concurrentMap.subMapAlt(from, to).mapNotNull { consumer.map(it.key, it.value) }
return concurrentMap.subMapAlt(from, to).mapNotNull { consumer.map(it.key, it.value) }
}
actual override fun <R> mapNotNullIntoSet( actual override fun <R> mapNotNullIntoSet(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiMapper<K, V, R?>, consumer: CacheCollectors.BiMapper<K, V, R?>,
): Set<R> { ): Set<R> = mapNotNull(from, to, consumer).toSet()
return mapNotNull(from, to, consumer).toSet()
}
actual override fun <R> mapFlatten( actual override fun <R> mapFlatten(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>, consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>,
): List<R> { ): List<R> = concurrentMap.subMapAlt(from, to).flatMap { consumer.map(it.key, it.value) as Iterable<R> }
return concurrentMap.subMapAlt(from, to).flatMap { consumer.map(it.key, it.value) as Iterable<R> }
}
actual override fun <R> mapFlattenIntoSet( actual override fun <R> mapFlattenIntoSet(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>, consumer: CacheCollectors.BiMapper<K, V, Collection<R>?>,
): Set<R> { ): Set<R> = mapFlatten(from, to, consumer).toSet()
return mapFlatten(from, to, consumer).toSet()
}
actual override fun maxOrNullOf( actual override fun maxOrNullOf(
from: K, from: K,
@@ -260,66 +209,50 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiSumOf<K, V>, consumer: CacheCollectors.BiSumOf<K, V>,
): Int { ): Int = concurrentMap.subMapAlt(from, to).sumOf(consumer)
return concurrentMap.subMapAlt(from, to).sumOf(consumer)
}
actual override fun sumOfLong( actual override fun sumOfLong(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiSumOfLong<K, V>, consumer: CacheCollectors.BiSumOfLong<K, V>,
): Long { ): Long = concurrentMap.subMapAlt(from, to).sumOfLong(consumer)
return concurrentMap.subMapAlt(from, to).sumOfLong(consumer)
}
actual override fun <R> groupBy( actual override fun <R> groupBy(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiNotNullMapper<K, V, R>, consumer: CacheCollectors.BiNotNullMapper<K, V, R>,
): Map<R, List<V>> { ): Map<R, List<V>> = concurrentMap.subMapAlt(from, to).groupBy(consumer)
return concurrentMap.subMapAlt(from, to).groupBy(consumer)
}
actual override fun <R> countByGroup( actual override fun <R> countByGroup(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiNotNullMapper<K, V, R>, consumer: CacheCollectors.BiNotNullMapper<K, V, R>,
): Map<R, Int> { ): Map<R, Int> = concurrentMap.subMapAlt(from, to).countByGroup(consumer)
return concurrentMap.subMapAlt(from, to).countByGroup(consumer)
}
actual override fun <R> sumByGroup( actual override fun <R> sumByGroup(
from: K, from: K,
to: K, to: K,
groupMap: CacheCollectors.BiNotNullMapper<K, V, R>, groupMap: CacheCollectors.BiNotNullMapper<K, V, R>,
sumOf: CacheCollectors.BiNotNullMapper<K, V, Long>, sumOf: CacheCollectors.BiNotNullMapper<K, V, Long>,
): Map<R, Long> { ): Map<R, Long> = concurrentMap.subMapAlt(from, to).sumByGroup(groupMap, sumOf)
return concurrentMap.subMapAlt(from, to).sumByGroup(groupMap, sumOf)
}
actual override fun count( actual override fun count(
from: K, from: K,
to: K, to: K,
consumer: CacheCollectors.BiFilter<K, V>, consumer: CacheCollectors.BiFilter<K, V>,
): Int { ): Int = concurrentMap.subMapAlt(from, to).count { consumer.filter(it.key, it.value) }
return concurrentMap.subMapAlt(from, to).count { consumer.filter(it.key, it.value) }
}
actual override fun <T, U> associate( actual override fun <T, U> associate(
from: K, from: K,
to: K, to: K,
transform: (K, V) -> Pair<T, U>, transform: (K, V) -> Pair<T, U>,
): Map<T, U> { ): Map<T, U> = concurrentMap.subMapAlt(from, to).associate(transform)
return concurrentMap.subMapAlt(from, to).associate(transform)
}
actual override fun <U> associateWith( actual override fun <U> associateWith(
from: K, from: K,
to: K, to: K,
transform: (K, V) -> U?, transform: (K, V) -> U?,
): Map<K, U?> { ): Map<K, U?> = concurrentMap.subMapAlt(from, to).associateWith(transform)
return concurrentMap.subMapAlt(from, to).associateWith(transform)
}
actual override fun joinToString( actual override fun joinToString(
separator: CharSequence, separator: CharSequence,
@@ -354,9 +287,14 @@ actual class LargeCache<K, V> : ICacheOperations<K, V> {
// Different subMap implementations below. Investigating their performance for now. // Different subMap implementations below. Investigating their performance for now.
fun <K, V> CacheMap<K, V>.subMapSlow(from: K, to: K, toInclusive: Boolean = true): Map<K, V> { fun <K, V> CacheMap<K, V>.subMapSlow(
from: K,
to: K,
toInclusive: Boolean = true,
): Map<K, V> {
val transientList = toList() val transientList = toList()
val transientSubList = transientList.subList( val transientSubList =
transientList.subList(
fromIndex = transientList.indexOf(Pair(from, getValue(from))), fromIndex = transientList.indexOf(Pair(from, getValue(from))),
toIndex = transientList.indexOf(Pair(to, getValue(to))), toIndex = transientList.indexOf(Pair(to, getValue(to))),
) )
@@ -365,7 +303,11 @@ fun <K, V> CacheMap<K, V>.subMapSlow(from: K, to: K, toInclusive: Boolean = true
return if (toInclusive) completeSubList.toMap() else transientSubList.toMap() return if (toInclusive) completeSubList.toMap() else transientSubList.toMap()
} }
fun <K, V> CacheMap<K, V>.subMapAlt(from: K, to: K, toInclusive: Boolean = true): Map<K, V> { fun <K, V> CacheMap<K, V>.subMapAlt(
from: K,
to: K,
toInclusive: Boolean = true,
): Map<K, V> {
val resultMap = hashMapOf<K, V>() val resultMap = hashMapOf<K, V>()
val keySet = keys val keySet = keys
val fromIndex = keySet.indexOf(from) val fromIndex = keySet.indexOf(from)
@@ -388,45 +330,39 @@ fun <K, V> Map<K, V>.maxOrNullOf(
filter: CacheCollectors.BiFilter<K, V>, filter: CacheCollectors.BiFilter<K, V>,
comparator: Comparator<V>, comparator: Comparator<V>,
): V? { ): V? {
var _maxK: K? = null var maxK: K? = null
var _maxV: V? = null var maxV: V? = null
val maxK: K? = _maxK val finalMaxK: K? = maxK
val maxV: V? = _maxV val finalMaxV: V? = maxV
forEach { forEach {
if (filter.filter(it.key, it.value)) { if (filter.filter(it.key, it.value)) {
if (_maxK == null || (_maxV != null && comparator.compare(it.value, _maxV) > 0)) { if (maxK == null || (maxV != null && comparator.compare(it.value, maxV) > 0)) {
_maxK = it.key maxK = it.key
_maxV = it.value maxV = it.value
} }
} }
} }
return maxV return finalMaxV
} }
fun <K,V> Map<K, V>.sumOf( fun <K, V> Map<K, V>.sumOf(consumer: CacheCollectors.BiSumOf<K, V>): Int {
consumer: CacheCollectors.BiSumOf<K, V>,
): Int {
var sum = 0 var sum = 0
val totalSum = sum val totalSum = sum
forEach { sum += consumer.map(it.key, it.value) } forEach { sum += consumer.map(it.key, it.value) }
return totalSum return totalSum
} }
fun <K,V> Map<K, V>.sumOfLong( fun <K, V> Map<K, V>.sumOfLong(consumer: CacheCollectors.BiSumOfLong<K, V>): Long {
consumer: CacheCollectors.BiSumOfLong<K, V>,
): Long {
var sum = 0L var sum = 0L
val totalSum = sum val totalSum = sum
forEach { sum += consumer.map(it.key, it.value) } forEach { sum += consumer.map(it.key, it.value) }
return totalSum return totalSum
} }
fun <K, V, R> Map<K, V>.groupBy( fun <K, V, R> Map<K, V>.groupBy(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): Map<R, List<V>> {
consumer: CacheCollectors.BiNotNullMapper<K, V, R>
): Map<R, List<V>> {
val results = HashMap<R, ArrayList<V>>() val results = HashMap<R, ArrayList<V>>()
forEach { forEach {
val group = consumer.map(it.key, it.value) val group = consumer.map(it.key, it.value)
@@ -443,9 +379,7 @@ fun <K, V, R> Map<K, V>.groupBy(
return results return results
} }
fun <K, V, R> Map<K, V>.countByGroup( fun <K, V, R> Map<K, V>.countByGroup(consumer: CacheCollectors.BiNotNullMapper<K, V, R>): Map<R, Int> {
consumer: CacheCollectors.BiNotNullMapper<K, V, R>
): Map<R, Int> {
val results = HashMap<R, Int>() val results = HashMap<R, Int>()
forEach { forEach {
val group = consumer.map(it.key, it.value) val group = consumer.map(it.key, it.value)
@@ -26,7 +26,7 @@ abstract class Buffer<Element, Array> internal constructor(
pos: Int, pos: Int,
lim: Int, lim: Int,
cap: Int, cap: Int,
var order: ByteOrder = ByteOrder.LittleEndian var order: ByteOrder = ByteOrder.LittleEndian,
) { ) {
enum class ByteOrder { LittleEndian, BigEndian } enum class ByteOrder { LittleEndian, BigEndian }
@@ -44,10 +44,11 @@ abstract class Buffer<Element, Array> internal constructor(
* If the preconditions on <tt>newPosition</tt> do not hold * If the preconditions on <tt>newPosition</tt> do not hold
*/ */
set(newPosition) { set(newPosition) {
if (newPosition > limit || newPosition < 0) if (newPosition !in 0..limit) {
throw IllegalArgumentException("Position $newPosition exceeds limit:$limit") throw IllegalArgumentException("Position $newPosition exceeds limit:$limit")
}
field = newPosition field = newPosition
if (mark > position) mark = noMark if (mark > position) mark = NO_MARK
} }
var limit = lim var limit = lim
@@ -66,8 +67,9 @@ abstract class Buffer<Element, Array> internal constructor(
* If the preconditions on <tt>newLimit</tt> do not hold * If the preconditions on <tt>newLimit</tt> do not hold
*/ */
set(newLimit) { set(newLimit) {
if (newLimit > capacity || newLimit < 0) if (newLimit !in 0..capacity) {
throw IllegalArgumentException("limit $newLimit exceeds capacity $capacity") throw IllegalArgumentException("limit $newLimit exceeds capacity $capacity")
}
field = newLimit field = newLimit
if (position > limit) position = limit if (position > limit) position = limit
if (mark > limit) mark = -1 if (mark > limit) mark = -1
@@ -76,8 +78,9 @@ abstract class Buffer<Element, Array> internal constructor(
internal set internal set
var mark = markPosition var mark = markPosition
set(value) { set(value) {
if (mark < -1 || mark > position) if (mark < -1 || mark > position) {
throw IllegalArgumentException("Mark $mark out of range of 0 to $position") throw IllegalArgumentException("Mark $mark out of range of 0 to $position")
}
field = value field = value
} }
@@ -111,27 +114,32 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
abstract var byte: Element abstract var byte: Element
/** // The following functions are all usable by subclasses to encode/decode basic types
* The following functions are all usable by subclasses to encode/decode basic types // in and Endian-aware fashion. In all cases an exception is thrown if remaining() < length
* in and Endian-aware fashion. In all cases an exception is thrown if remaining() < length // to be read/written. Position will be incremented by the appropriate length for both gets
* to be read/written. Position will be incremented by the appropriate length for both gets // and sets.
* and sets. //
* // For some reason, the ByteArray in Kotlin Native is the only implementation that provides
* For some reason, the ByteArray in Kotlin Native is the only implementation that provides // similar function, but assumes all is Little Endian. Since these are not available in the
* similar function, but assumes all is Little Endian. Since these are not available in the // common stdlib, they are not used even for little endian.
* common stdlib, they are not used even for little endian.
*/
/** /**
* Read or write a two-byte Char at the current position. Position will increment by 2. * Read or write a two-byte Char at the current position. Position will increment by 2.
*/ */
var char: Char var char: Char
get() { get() {
val c = when (order) { val c =
ByteOrder.LittleEndian -> ((getElementAsInt(position + 1) shl 8) or when (order) {
getElementAsInt(position)).toChar() ByteOrder.LittleEndian ->
ByteOrder.BigEndian -> ((getElementAsInt(position) shl 8) or (
getElementAsInt(position + 1)).toChar() (getElementAsInt(position + 1) shl 8) or
getElementAsInt(position)
).toChar()
ByteOrder.BigEndian ->
(
(getElementAsInt(position) shl 8) or
getElementAsInt(position + 1)
).toChar()
} }
position += 2 position += 2
return c return c
@@ -145,10 +153,11 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
var short: Short var short: Short
get() { get() {
if (remaining < shortLength) if (remaining < SHORT_LENGTH) {
throw IllegalArgumentException("Short requires $shortLength bytes. Position: $position, remaining:$remaining") throw IllegalArgumentException("Short requires $SHORT_LENGTH bytes. Position: $position, remaining:$remaining")
}
val s = getShortValue(position) val s = getShortValue(position)
position += shortLength position += SHORT_LENGTH
return s return s
} }
set(value) { set(value) {
@@ -160,10 +169,11 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
var ushort: UShort var ushort: UShort
get() { get() {
if (remaining < shortLength) if (remaining < SHORT_LENGTH) {
throw IllegalArgumentException("UShort requires $shortLength bytes. Position: $position, remaining:$remaining") throw IllegalArgumentException("UShort requires $SHORT_LENGTH bytes. Position: $position, remaining:$remaining")
}
val s = getUShortValue(position) val s = getUShortValue(position)
position += shortLength position += SHORT_LENGTH
return s return s
} }
set(value) { set(value) {
@@ -175,10 +185,11 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
var int: Int var int: Int
get() { get() {
if (remaining < intLength) if (remaining < INT_LENGTH) {
throw IllegalArgumentException("Int requires $intLength bytes. Position: $position, remaining:$remaining") throw IllegalArgumentException("Int requires $INT_LENGTH bytes. Position: $position, remaining:$remaining")
}
val s = getIntValue(position) val s = getIntValue(position)
position += intLength position += INT_LENGTH
return s return s
} }
set(value) { set(value) {
@@ -190,10 +201,11 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
var uint: UInt var uint: UInt
get() { get() {
if (remaining < intLength) if (remaining < INT_LENGTH) {
throw IllegalArgumentException("UInt requires $intLength bytes. Position: $position, remaining:$remaining") throw IllegalArgumentException("UInt requires $INT_LENGTH bytes. Position: $position, remaining:$remaining")
}
val s = getUIntValue(position) val s = getUIntValue(position)
position += intLength position += INT_LENGTH
return s return s
} }
set(value) { set(value) {
@@ -205,10 +217,11 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
var long: Long var long: Long
get() { get() {
if (remaining < longLength) if (remaining < LONG_LENGTH) {
throw IllegalArgumentException("Long requires $longLength bytes. Position: $position, remaining:$remaining") throw IllegalArgumentException("Long requires $LONG_LENGTH bytes. Position: $position, remaining:$remaining")
}
val s = getLongValue(position) val s = getLongValue(position)
position += longLength position += LONG_LENGTH
return s return s
} }
set(value) { set(value) {
@@ -220,10 +233,11 @@ abstract class Buffer<Element, Array> internal constructor(
*/ */
var ulong: ULong var ulong: ULong
get() { get() {
if (remaining < longLength) if (remaining < LONG_LENGTH) {
throw IllegalArgumentException("ULong requires $longLength bytes. Position: $position, remaining:$remaining") throw IllegalArgumentException("ULong requires $LONG_LENGTH bytes. Position: $position, remaining:$remaining")
}
val s = getULongValue(position) val s = getULongValue(position)
position += longLength position += LONG_LENGTH
return s return s
} }
set(value) { set(value) {
@@ -250,8 +264,9 @@ abstract class Buffer<Element, Array> internal constructor(
limit = lim limit = lim
position = pos position = pos
if (mark >= 0) { if (mark >= 0) {
if (mark > pos) if (mark > pos) {
throw IllegalArgumentException("mark > position: ($mark > $pos)") throw IllegalArgumentException("mark > position: ($mark > $pos)")
}
this.mark = mark this.mark = mark
} }
} }
@@ -278,7 +293,7 @@ abstract class Buffer<Element, Array> internal constructor(
open fun clear() { open fun clear() {
position = 0 position = 0
limit = capacity limit = capacity
mark = noMark mark = NO_MARK
} }
/** /**
@@ -313,16 +328,14 @@ abstract class Buffer<Element, Array> internal constructor(
open fun flip(): Buffer<Element, Array> { open fun flip(): Buffer<Element, Array> {
limit = position limit = position
position = 0 position = 0
mark = noMark mark = NO_MARK
return this return this
} }
/** /**
* given the specified index into the backing array, return the current Element. Do not change position * given the specified index into the backing array, return the current Element. Do not change position
*/ */
fun get(index: Int): Element { fun get(index: Int): Element = getElementAt(index)
return getElementAt(index)
}
/** /**
* This is used by many of the accessor properties of the various types. It must return * This is used by many of the accessor properties of the various types. It must return
@@ -346,25 +359,41 @@ abstract class Buffer<Element, Array> internal constructor(
* given the specified index into the backing array, return the current Element. Do not change position * given the specified index into the backing array, return the current Element. Do not change position
*/ */
abstract fun getElementAt(index: Int): Element abstract fun getElementAt(index: Int): Element
abstract fun setElementAt(index: Int, element: Element)
abstract fun setElementAt(
index: Int,
element: Element,
)
abstract fun getElementAsInt(index: Int): Int abstract fun getElementAsInt(index: Int): Int
abstract fun getElementAsUInt(index: Int): UInt abstract fun getElementAsUInt(index: Int): UInt
abstract fun getElementAsLong(index: Int): Long abstract fun getElementAsLong(index: Int): Long
abstract fun getElementAsULong(index: Int): ULong abstract fun getElementAsULong(index: Int): ULong
/** /**
* Convenience method Sets the limit at position + length, then sets the position * Convenience method Sets the limit at position + length, then sets the position
*/ */
fun positionLimit(position: Int, length: Int) { fun positionLimit(
if (length < 0 || position < 0 || position + length > capacity) position: Int,
length: Int,
) {
if (length < 0 || position < 0 || position + length > capacity) {
throw IllegalArgumentException("Position: $position + length: $length = ${position + length} must be between 0 and $capacity") throw IllegalArgumentException("Position: $position + length: $length = ${position + length} must be between 0 and $capacity")
}
limit = position + length limit = position + length
this.position = position this.position = position
} }
fun positionLimit(position: Short, length: Short) { fun positionLimit(
if (length < 0 || position < 0 || position + length > capacity) position: Short,
length: Short,
) {
if (length < 0 || position < 0 || position + length > capacity) {
throw IllegalArgumentException("Position: $position + length: $length = ${position + length} must be between 0 and $capacity") throw IllegalArgumentException("Position: $position + length: $length = ${position + length} must be between 0 and $capacity")
}
limit = position + length limit = position + length
this.position = position.toInt() this.position = position.toInt()
} }
@@ -399,7 +428,7 @@ abstract class Buffer<Element, Array> internal constructor(
} }
fun resetMark() { fun resetMark() {
mark = noMark mark = NO_MARK
} }
/** /**
@@ -431,6 +460,7 @@ abstract class Buffer<Element, Array> internal constructor(
abstract fun slice(length: Int = remaining): ByteBufferBase<Element, Array> abstract fun slice(length: Int = remaining): ByteBufferBase<Element, Array>
// -- Package-private methods for bounds checking, etc. -- // -- Package-private methods for bounds checking, etc. --
/** /**
* Checks the current position against the limit, throwing a [ ] if it is not smaller than the limit, and then * Checks the current position against the limit, throwing a [ ] if it is not smaller than the limit, and then
* increments the position. * increments the position.
@@ -468,8 +498,9 @@ abstract class Buffer<Element, Array> internal constructor(
* @throws IllegalStateException if increased position will exceed limit * @throws IllegalStateException if increased position will exceed limit
*/ */
fun nextPutIndex(length: Int): Int { fun nextPutIndex(length: Int): Int {
if (limit - position < length || position < 0) if (limit - position < length || position < 0) {
throw IllegalStateException("Limit:$limit minus position:$position less than $length") throw IllegalStateException("Limit:$limit minus position:$position less than $length")
}
val p = position val p = position
position += length position += length
return p return p
@@ -480,16 +511,23 @@ abstract class Buffer<Element, Array> internal constructor(
* or is smaller than zero. * or is smaller than zero.
*/ */
fun checkIndex(i: Int): Int { // package-private fun checkIndex(i: Int): Int { // package-private
if (i < 0 || i >= limit) throw IndexOutOfBoundsException( if (i < 0 || i >= limit) {
"index=$i out of bounds (limit=$limit)" throw IndexOutOfBoundsException(
"index=$i out of bounds (limit=$limit)",
) )
}
return i return i
} }
fun checkIndex(i: Int, nb: Int): Int { // package-private fun checkIndex(
if (i < 0 || nb > limit - i) throw IndexOutOfBoundsException( i: Int,
"index=$i out of bounds (limit=$limit, nb=$nb)" nb: Int,
): Int { // package-private
if (i < 0 || nb > limit - i) {
throw IndexOutOfBoundsException(
"index=$i out of bounds (limit=$limit, nb=$nb)",
) )
}
return i return i
} }
@@ -498,7 +536,7 @@ abstract class Buffer<Element, Array> internal constructor(
} }
fun truncate() { // package-private fun truncate() { // package-private
mark = noMark mark = NO_MARK
position = 0 position = 0
limit = 0 limit = 0
capacity = 0 capacity = 0
@@ -508,88 +546,100 @@ abstract class Buffer<Element, Array> internal constructor(
mark = -1 mark = -1
} }
private fun getShortValue(index: Int): Short { private fun getShortValue(index: Int): Short =
return when (order) { when (order) {
ByteOrder.LittleEndian -> ((getElementAsInt(index + 1) shl 8) or getElementAsInt(index)).toShort() ByteOrder.LittleEndian -> ((getElementAsInt(index + 1) shl 8) or getElementAsInt(index)).toShort()
ByteOrder.BigEndian -> ((getElementAsInt(index) shl 8) or getElementAsInt(index + 1)).toShort() ByteOrder.BigEndian -> ((getElementAsInt(index) shl 8) or getElementAsInt(index + 1)).toShort()
} }
fun getUShortValue(index: Int): UShort =
when (order) {
ByteOrder.LittleEndian ->
(
(getElementAsUInt(index + 1) shl 8) or
getElementAsUInt(index)
).toUShort()
ByteOrder.BigEndian ->
(
(getElementAsUInt(index) shl 8) or
getElementAsUInt(index + 1)
).toUShort()
} }
fun getUShortValue(index: Int): UShort { private fun getIntValue(index: Int): Int =
return when (order) { when (order) {
ByteOrder.LittleEndian -> ((getElementAsUInt(index + 1) shl 8) or ByteOrder.LittleEndian ->
getElementAsUInt(index)).toUShort() (getElementAsInt(index + 3) shl 24) or
ByteOrder.BigEndian -> ((getElementAsUInt(index) shl 8) or
getElementAsUInt(index + 1)).toUShort()
}
}
private fun getIntValue(index: Int): Int {
return when (order) {
ByteOrder.LittleEndian -> (getElementAsInt(index + 3) shl 24) or
(getElementAsInt(index + 2) shl 16) or (getElementAsInt(index + 2) shl 16) or
(getElementAsInt(index + 1) shl 8) or (getElementAsInt(index + 1) shl 8) or
getElementAsInt(index) getElementAsInt(index)
ByteOrder.BigEndian -> (getElementAsInt(index) shl 24) or ByteOrder.BigEndian ->
(getElementAsInt(index) shl 24) or
(getElementAsInt(index + 1) shl 16) or (getElementAsInt(index + 1) shl 16) or
(getElementAsInt(index + 2) shl 8) or (getElementAsInt(index + 2) shl 8) or
getElementAsInt(index + 3) getElementAsInt(index + 3)
} }
}
private fun getUIntValue(index: Int): UInt { private fun getUIntValue(index: Int): UInt =
return when (order) { when (order) {
ByteOrder.LittleEndian -> (getElementAsUInt(index + 3) shl 24) or ByteOrder.LittleEndian ->
(getElementAsUInt(index + 3) shl 24) or
(getElementAsUInt(index + 2) shl 16) or (getElementAsUInt(index + 2) shl 16) or
(getElementAsUInt(index + 1) shl 8) or (getElementAsUInt(index + 1) shl 8) or
getElementAsUInt(index) getElementAsUInt(index)
ByteOrder.BigEndian -> (getElementAsUInt(index) shl 24) or ByteOrder.BigEndian ->
(getElementAsUInt(index) shl 24) or
(getElementAsUInt(index + 1) shl 16) or (getElementAsUInt(index + 1) shl 16) or
(getElementAsUInt(index + 2) shl 8) or (getElementAsUInt(index + 2) shl 8) or
getElementAsUInt(index + 3) getElementAsUInt(index + 3)
} }
}
fun getLongValue(index: Int): Long { fun getLongValue(index: Int): Long =
return when (order) { when (order) {
ByteOrder.LittleEndian -> ((getElementAsLong(index + 7) shl 56) ByteOrder.LittleEndian -> (
(getElementAsLong(index + 7) shl 56)
or (getElementAsLong(index + 6) shl 48) or (getElementAsLong(index + 6) shl 48)
or (getElementAsLong(index + 5) shl 40) or (getElementAsLong(index + 5) shl 40)
or (getElementAsLong(index + 4) shl 32) or (getElementAsLong(index + 4) shl 32)
or (getElementAsLong(index + 3) shl 24) or (getElementAsLong(index + 3) shl 24)
or (getElementAsLong(index + 2) shl 16) or (getElementAsLong(index + 2) shl 16)
or (getElementAsLong(index + 1) shl 8) or (getElementAsLong(index + 1) shl 8)
or getElementAsLong(index)) or getElementAsLong(index)
ByteOrder.BigEndian -> ((getElementAsLong(index) shl 56) )
ByteOrder.BigEndian -> (
(getElementAsLong(index) shl 56)
or (getElementAsLong(index + 1) shl 48) or (getElementAsLong(index + 1) shl 48)
or (getElementAsLong(index + 2) shl 40) or (getElementAsLong(index + 2) shl 40)
or (getElementAsLong(index + 3) shl 32) or (getElementAsLong(index + 3) shl 32)
or (getElementAsLong(index + 4) shl 24) or (getElementAsLong(index + 4) shl 24)
or (getElementAsLong(index + 5) shl 16) or (getElementAsLong(index + 5) shl 16)
or (getElementAsLong(index + 6) shl 8) or (getElementAsLong(index + 6) shl 8)
or getElementAsLong(index + 7)) or getElementAsLong(index + 7)
} )
} }
private fun getULongValue(index: Int): ULong { private fun getULongValue(index: Int): ULong =
return when (order) { when (order) {
ByteOrder.LittleEndian -> ((getElementAsULong(index + 7) shl 56) ByteOrder.LittleEndian -> (
(getElementAsULong(index + 7) shl 56)
or (getElementAsULong(index + 6) shl 48) or (getElementAsULong(index + 6) shl 48)
or (getElementAsULong(index + 5) shl 40) or (getElementAsULong(index + 5) shl 40)
or (getElementAsULong(index + 4) shl 32) or (getElementAsULong(index + 4) shl 32)
or (getElementAsULong(index + 3) shl 24) or (getElementAsULong(index + 3) shl 24)
or (getElementAsULong(index + 2) shl 16) or (getElementAsULong(index + 2) shl 16)
or (getElementAsULong(index + 1) shl 8) or (getElementAsULong(index + 1) shl 8)
or getElementAsULong(index)) or getElementAsULong(index)
ByteOrder.BigEndian -> ((getElementAsULong(index) shl 56) )
ByteOrder.BigEndian -> (
(getElementAsULong(index) shl 56)
or (getElementAsULong(index + 1) shl 48) or (getElementAsULong(index + 1) shl 48)
or (getElementAsULong(index + 2) shl 40) or (getElementAsULong(index + 2) shl 40)
or (getElementAsULong(index + 3) shl 32) or (getElementAsULong(index + 3) shl 32)
or (getElementAsULong(index + 4) shl 24) or (getElementAsULong(index + 4) shl 24)
or (getElementAsULong(index + 5) shl 16) or (getElementAsULong(index + 5) shl 16)
or (getElementAsULong(index + 6) shl 8) or (getElementAsULong(index + 6) shl 8)
or getElementAsULong(index + 7)) or getElementAsULong(index + 7)
} )
} }
/** /**
@@ -600,23 +650,35 @@ abstract class Buffer<Element, Array> internal constructor(
* *
*/ */
abstract fun putEndian(bytes: Array) abstract fun putEndian(bytes: Array)
abstract fun shortToArray(short: Short): Array abstract fun shortToArray(short: Short): Array
abstract fun ushortToArray(ushort: UShort): Array abstract fun ushortToArray(ushort: UShort): Array
abstract fun intToArray(int: Int): Array abstract fun intToArray(int: Int): Array
abstract fun uintToArray(int: UInt): Array abstract fun uintToArray(int: UInt): Array
abstract fun longToArray(long: Long): Array abstract fun longToArray(long: Long): Array
abstract fun ulongToArray(uLong: ULong): Array abstract fun ulongToArray(uLong: ULong): Array
companion object { companion object {
protected const val noMark = -1 protected const val NO_MARK = -1
protected const val shortLength = 2 protected const val SHORT_LENGTH = 2
protected const val intLength = 4 protected const val INT_LENGTH = 4
protected const val longLength = 8 protected const val LONG_LENGTH = 8
fun checkBounds(off: Int, len: Int, size: Int) { // package-private fun checkBounds(
if (off or len or off + len or size - (off + len) < 0) throw IndexOutOfBoundsException( off: Int,
"off=$off, len=$len out of bounds (size=$size)" len: Int,
size: Int,
) { // package-private
if (off or len or off + len or size - (off + len) < 0) {
throw IndexOutOfBoundsException(
"off=$off, len=$len out of bounds (size=$size)",
) )
} }
} }
} }
}
@@ -31,20 +31,17 @@ import kotlin.math.min
abstract class ByteBufferBase<Element, Array> constructor( abstract class ByteBufferBase<Element, Array> constructor(
capacity: Int, capacity: Int,
order: ByteOrder = ByteOrder.LittleEndian, order: ByteOrder = ByteOrder.LittleEndian,
override val isReadOnly: Boolean = false override val isReadOnly: Boolean = false,
) : Buffer<Element, Array>(-1, 0, capacity, capacity, order), ) : Buffer<Element, Array>(-1, 0, capacity, capacity, order),
Comparable<ByteBufferBase<Element, Array>> { Comparable<ByteBufferBase<Element, Array>> {
abstract var buf: Array abstract var buf: Array
protected set protected set
private var offset = 0 private var offset = 0
val contentBytes get() = buf val contentBytes get() = buf
/** // The following properties offer simple encode/decode operations as indicated by the ByteOrder
* The following properties offer simple encode/decode operations as indicated by the ByteOrder // currently in effect. Properties are defined for many basic types
* currently in effect. Properties are defined for many basic types
*/
/** /**
* This property offers byte-level read/write. get returns the byte at the current position, * This property offers byte-level read/write. get returns the byte at the current position,
@@ -131,7 +128,10 @@ abstract class ByteBufferBase<Element, Array> constructor(
return 0 return 0
} }
abstract fun compareElement(element: Element, other: Element): Int abstract fun compareElement(
element: Element,
other: Element,
): Int
/** /**
* The contents of the current buffer are replaced with the contents of the source. Position, * The contents of the current buffer are replaced with the contents of the source. Position,
@@ -157,7 +157,7 @@ abstract class ByteBufferBase<Element, Array> constructor(
destination: Array, destination: Array,
destinationOffset: Int = 0, destinationOffset: Int = 0,
startIndex: Int = 0, startIndex: Int = 0,
endIndex: Int endIndex: Int,
) )
/** /**
@@ -175,11 +175,12 @@ abstract class ByteBufferBase<Element, Array> constructor(
fun fillArray( fun fillArray(
destination: Array, destination: Array,
destinationOffset: Int = 0, destinationOffset: Int = 0,
length: Int length: Int,
) { ) {
checkBounds(destinationOffset, length, length) checkBounds(destinationOffset, length, length)
if (length > remaining) if (length > remaining) {
throw IllegalStateException("Copying length:$length is more than remaining:$remaining") throw IllegalStateException("Copying length:$length is more than remaining:$remaining")
}
copyInto(destination, destinationOffset, position, position + length) copyInto(destination, destinationOffset, position, position + length)
position += length position += length
} }
@@ -198,11 +199,13 @@ abstract class ByteBufferBase<Element, Array> constructor(
* The positions of both buffers are then incremented by <i>n</i>. * The positions of both buffers are then incremented by <i>n</i>.
*/ */
open fun put(source: ByteBufferBase<Element, Array>) { open fun put(source: ByteBufferBase<Element, Array>) {
if (source == this) if (source == this) {
throw IllegalArgumentException("Cannot copy ByteBuffer to itself") throw IllegalArgumentException("Cannot copy ByteBuffer to itself")
}
val sourceBytes = source.remaining val sourceBytes = source.remaining
if (sourceBytes > remaining) if (sourceBytes > remaining) {
throw IllegalArgumentException("Remaining source bytes:$sourceBytes exceeds destination remaining:$remaining") throw IllegalArgumentException("Remaining source bytes:$sourceBytes exceeds destination remaining:$remaining")
}
source.fillArray(buf, position, sourceBytes) source.fillArray(buf, position, sourceBytes)
position += sourceBytes position += sourceBytes
@@ -212,10 +215,11 @@ abstract class ByteBufferBase<Element, Array> constructor(
* The following are all private functions * The following are all private functions
*/ */
private fun checkPosition(forLength: Int = 1) { private fun checkPosition(forLength: Int = 1) {
if (position + forLength > limit) if (position + forLength > limit) {
throw IllegalStateException() throw IllegalStateException()
} }
} }
}
/** /**
* Enhance byte array implementing the Buffer interface which provides position/limit/remaining/capacity tracking, and * Enhance byte array implementing the Buffer interface which provides position/limit/remaining/capacity tracking, and
@@ -230,10 +234,8 @@ class ByteBuffer(
capacity: Int, capacity: Int,
order: ByteOrder = ByteOrder.LittleEndian, order: ByteOrder = ByteOrder.LittleEndian,
isReadOnly: Boolean = false, isReadOnly: Boolean = false,
override var buf: ByteArray = ByteArray(capacity) override var buf: ByteArray = ByteArray(capacity),
): ByteBufferBase<Byte, ByteArray>(capacity, order, isReadOnly) ) : ByteBufferBase<Byte, ByteArray>(capacity, order, isReadOnly) {
{
/** /**
* Construct a ByteBuffer from an existing ByteArray * Construct a ByteBuffer from an existing ByteArray
* @param bytes becomes the buffer content (not a copy). capacity is set to the ByteArray size, position is set to * @param bytes becomes the buffer content (not a copy). capacity is set to the ByteArray size, position is set to
@@ -248,11 +250,12 @@ class ByteBuffer(
return this return this
} }
override fun getElementAt(index: Int): Byte { override fun getElementAt(index: Int): Byte = buf[index]
return buf[index]
}
override fun setElementAt(index: Int, element: Byte) { override fun setElementAt(
index: Int,
element: Byte,
) {
buf[index] = element buf[index] = element
} }
@@ -262,9 +265,7 @@ class ByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return INt will not have it's high order bits set. * @return INt will not have it's high order bits set.
*/ */
override fun getElementAsInt(index: Int): Int { override fun getElementAsInt(index: Int): Int = buf toPosInt index
return buf toPosInt index
}
/** /**
* gets one byte at the current position without changing the position, and return a UInt. * gets one byte at the current position without changing the position, and return a UInt.
@@ -272,9 +273,7 @@ class ByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return UINt will not have it's high order bits set. * @return UINt will not have it's high order bits set.
*/ */
override fun getElementAsUInt(index: Int): UInt { override fun getElementAsUInt(index: Int): UInt = buf toPosUInt index
return buf toPosUInt index
}
/** /**
* gets one byte at the current position without changing the position. The byte is treated as * gets one byte at the current position without changing the position. The byte is treated as
@@ -282,9 +281,7 @@ class ByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return Long will not have it's high order bits set. * @return Long will not have it's high order bits set.
*/ */
override fun getElementAsLong(index: Int): Long { override fun getElementAsLong(index: Int): Long = buf toPosLong index
return buf toPosLong index
}
/** /**
* gets one byte at the current position without changing the position. The byte is treated as * gets one byte at the current position without changing the position. The byte is treated as
@@ -292,9 +289,7 @@ class ByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return ULong will not have it's high order bits set. * @return ULong will not have it's high order bits set.
*/ */
override fun getElementAsULong(index: Int): ULong { override fun getElementAsULong(index: Int): ULong = buf toPosULong index
return buf toPosULong index
}
override fun getBytes(length: Int): ByteArray { override fun getBytes(length: Int): ByteArray {
val l = min(remaining, length) val l = min(remaining, length)
@@ -323,40 +318,36 @@ class ByteBuffer(
put(bytes) put(bytes)
} }
override fun shortToArray(short: Short): ByteArray { override fun shortToArray(short: Short): ByteArray =
return byteArrayOf( byteArrayOf(
(short.toInt() shr 8).toByte(), (short.toInt() shr 8).toByte(),
short.toByte() short.toByte(),
) )
}
override fun ushortToArray(ushort: UShort): ByteArray { override fun ushortToArray(ushort: UShort): ByteArray =
return byteArrayOf( byteArrayOf(
(ushort.toUInt() shr 8).toByte(), (ushort.toUInt() shr 8).toByte(),
ushort.toByte() ushort.toByte(),
) )
}
override fun intToArray(int: Int): ByteArray { override fun intToArray(int: Int): ByteArray =
return byteArrayOf( byteArrayOf(
(int shr 24 and 0xff).toByte(), (int shr 24 and 0xff).toByte(),
(int shr 16 and 0xff).toByte(), (int shr 16 and 0xff).toByte(),
(int shr 8 and 0xff).toByte(), (int shr 8 and 0xff).toByte(),
(int and 0xff).toByte() (int and 0xff).toByte(),
) )
}
override fun uintToArray(int: UInt): ByteArray { override fun uintToArray(int: UInt): ByteArray =
return byteArrayOf( byteArrayOf(
(int shr 24 and 0xffu).toByte(), (int shr 24 and 0xffu).toByte(),
(int shr 16 and 0xffu).toByte(), (int shr 16 and 0xffu).toByte(),
(int shr 8 and 0xffu).toByte(), (int shr 8 and 0xffu).toByte(),
(int and 0xffu).toByte() (int and 0xffu).toByte(),
) )
}
override fun longToArray(long: Long): ByteArray { override fun longToArray(long: Long): ByteArray =
return byteArrayOf( byteArrayOf(
(long shr 56 and 0xff).toByte(), (long shr 56 and 0xff).toByte(),
(long shr 48 and 0xff).toByte(), (long shr 48 and 0xff).toByte(),
(long shr 40 and 0xff).toByte(), (long shr 40 and 0xff).toByte(),
@@ -364,12 +355,11 @@ class ByteBuffer(
(long shr 24 and 0xff).toByte(), (long shr 24 and 0xff).toByte(),
(long shr 16 and 0xff).toByte(), (long shr 16 and 0xff).toByte(),
(long shr 8 and 0xff).toByte(), (long shr 8 and 0xff).toByte(),
(long and 0xff).toByte() (long and 0xff).toByte(),
) )
}
override fun ulongToArray(uLong: ULong): ByteArray { override fun ulongToArray(uLong: ULong): ByteArray =
return byteArrayOf( byteArrayOf(
(uLong shr 56 and 0xffu).toByte(), (uLong shr 56 and 0xffu).toByte(),
(uLong shr 48 and 0xffu).toByte(), (uLong shr 48 and 0xffu).toByte(),
(uLong shr 40 and 0xffu).toByte(), (uLong shr 40 and 0xffu).toByte(),
@@ -377,9 +367,8 @@ class ByteBuffer(
(uLong shr 24 and 0xffu).toByte(), (uLong shr 24 and 0xffu).toByte(),
(uLong shr 16 and 0xffu).toByte(), (uLong shr 16 and 0xffu).toByte(),
(uLong shr 8 and 0xffu).toByte(), (uLong shr 8 and 0xffu).toByte(),
(uLong and 0xffu).toByte() (uLong and 0xffu).toByte(),
) )
}
/** /**
* Similar to [ByteArray] copyInto * Similar to [ByteArray] copyInto
@@ -393,14 +382,15 @@ class ByteBuffer(
destination: ByteArray, destination: ByteArray,
destinationOffset: Int, destinationOffset: Int,
startIndex: Int, startIndex: Int,
endIndex: Int endIndex: Int,
) { ) {
buf.copyInto(destination, destinationOffset, startIndex, endIndex) buf.copyInto(destination, destinationOffset, startIndex, endIndex)
} }
override fun compareElement(element: Byte, other: Byte): Int { override fun compareElement(
return element.compareTo(other) element: Byte,
} other: Byte,
): Int = element.compareTo(other)
/** /**
* Increase size of buffer. Capacity and content are increased. Position is unchanged. if limit * Increase size of buffer. Capacity and content are increased. Position is unchanged. if limit
@@ -436,7 +426,7 @@ class ByteBuffer(
buf, buf,
position, position,
appendBuffer.position, appendBuffer.position,
appendBuffer.remaining appendBuffer.remaining,
) )
capacity = newLimit capacity = newLimit
limit = newLimit limit = newLimit
@@ -446,7 +436,7 @@ class ByteBuffer(
fun get( fun get(
destination: ByteArray, destination: ByteArray,
destinationOffset: Int = 0, destinationOffset: Int = 0,
size: Int = destination.size size: Int = destination.size,
) { ) {
super.fillArray(destination, destinationOffset, size) super.fillArray(destination, destinationOffset, size)
} }
@@ -462,10 +452,15 @@ class ByteBuffer(
* @return this * @return this
* @throws IllegalArgumentException on bounds violation * @throws IllegalArgumentException on bounds violation
*/ */
fun putBytes(source: ByteArray, sourceOffset: Int = 0, length: Int = source.size) { fun putBytes(
source: ByteArray,
sourceOffset: Int = 0,
length: Int = source.size,
) {
checkBounds(sourceOffset, length, length) checkBounds(sourceOffset, length, length)
if (length > remaining) if (length > remaining) {
throw IllegalArgumentException("Length:$length exceeds remaining:$remaining") throw IllegalArgumentException("Length:$length exceeds remaining:$remaining")
}
source.copyInto(buf, position, sourceOffset, length) source.copyInto(buf, position, sourceOffset, length)
position += length position += length
} }
@@ -495,14 +490,14 @@ class ByteBuffer(
return uBuf return uBuf
} }
override fun toString(): String { override fun toString(): String =
return buildString { buildString {
append("Position: $position, limit: $limit, remaining: $remaining. Content: 0x") append("Position: $position, limit: $limit, remaining: $remaining. Content: 0x")
for (i in position until limit) { for (i in position until limit) {
append("${contentBytes[i].toString(16).padStart(2, '0')} ") append("${contentBytes[i].toString(16).padStart(2, '0')} ")
} }
} }
}
/** /**
* Tells whether or not this buffer is equal to another object. * Tells whether or not this buffer is equal to another object.
* *
@@ -567,9 +562,8 @@ class UByteBuffer(
capacity: Int, capacity: Int,
order: ByteOrder = ByteOrder.LittleEndian, order: ByteOrder = ByteOrder.LittleEndian,
isReadOnly: Boolean = false, isReadOnly: Boolean = false,
override var buf: UByteArray = UByteArray(capacity) override var buf: UByteArray = UByteArray(capacity),
) : ByteBufferBase<UByte, UByteArray>(capacity, order, isReadOnly) { ) : ByteBufferBase<UByte, UByteArray>(capacity, order, isReadOnly) {
constructor(bytes: UByteArray, order: ByteOrder = ByteOrder.LittleEndian) : constructor(bytes: UByteArray, order: ByteOrder = ByteOrder.LittleEndian) :
this(bytes.size, order, false, bytes) this(bytes.size, order, false, bytes)
@@ -585,14 +579,15 @@ class UByteBuffer(
destination: UByteArray, destination: UByteArray,
destinationOffset: Int, destinationOffset: Int,
startIndex: Int, startIndex: Int,
endIndex: Int endIndex: Int,
) { ) {
buf.copyInto(destination, destinationOffset, startIndex, endIndex) buf.copyInto(destination, destinationOffset, startIndex, endIndex)
} }
override fun compareElement(element: UByte, other: UByte): Int { override fun compareElement(
return element.compareTo(other) element: UByte,
} other: UByte,
): Int = element.compareTo(other)
/** /**
* Increase size of buffer. Capacity and content are increased. Position is unchanged. if limit * Increase size of buffer. Capacity and content are increased. Position is unchanged. if limit
@@ -628,7 +623,7 @@ class UByteBuffer(
buf, buf,
position, position,
appendBuffer.position, appendBuffer.position,
appendBuffer.remaining appendBuffer.remaining,
) )
capacity = newLimit capacity = newLimit
limit = newLimit limit = newLimit
@@ -640,9 +635,7 @@ class UByteBuffer(
return this return this
} }
override fun getElementAt(index: Int): UByte { override fun getElementAt(index: Int): UByte = buf[index]
return buf[index]
}
/** /**
* gets one byte at the current position without changing the position. The byte is treated as * gets one byte at the current position without changing the position. The byte is treated as
@@ -650,9 +643,7 @@ class UByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return Int will not have it's high order bits set. * @return Int will not have it's high order bits set.
*/ */
override fun getElementAsInt(index: Int): Int { override fun getElementAsInt(index: Int): Int = buf toPosInt index
return buf toPosInt index
}
/** /**
* gets one byte at the current position without changing the position. The byte is treated as * gets one byte at the current position without changing the position. The byte is treated as
@@ -660,9 +651,7 @@ class UByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return UInt will not have it's high order bits set. * @return UInt will not have it's high order bits set.
*/ */
override fun getElementAsUInt(index: Int): UInt { override fun getElementAsUInt(index: Int): UInt = buf toPosUInt index
return buf toPosUInt index
}
/** /**
* gets one byte at the current position without changing the position. The byte is treated as * gets one byte at the current position without changing the position. The byte is treated as
@@ -670,9 +659,7 @@ class UByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return Long will not have it's high order bits set. * @return Long will not have it's high order bits set.
*/ */
override fun getElementAsLong(index: Int): Long { override fun getElementAsLong(index: Int): Long = buf toPosLong index
return buf toPosLong index
}
/** /**
* gets one byte at the current position without changing the position. The byte is treated as * gets one byte at the current position without changing the position. The byte is treated as
@@ -680,14 +667,12 @@ class UByteBuffer(
* @param index indicates which element in the current array to retrieve * @param index indicates which element in the current array to retrieve
* @return ULong will not have it's high order bits set. * @return ULong will not have it's high order bits set.
*/ */
override fun getElementAsULong(index: Int): ULong { override fun getElementAsULong(index: Int): ULong = buf toPosULong index
return buf toPosULong index
}
fun get( fun get(
destination: UByteArray, destination: UByteArray,
destinationOffset: Int = 0, destinationOffset: Int = 0,
size: Int = destination.size size: Int = destination.size,
) { ) {
super.fillArray(destination, destinationOffset, size) super.fillArray(destination, destinationOffset, size)
} }
@@ -723,10 +708,15 @@ class UByteBuffer(
* @return this * @return this
* @throws IllegalArgumentException on bounds violation * @throws IllegalArgumentException on bounds violation
*/ */
fun putBytes(source: UByteArray, sourceOffset: Int = 0, length: Int = source.size) { fun putBytes(
source: UByteArray,
sourceOffset: Int = 0,
length: Int = source.size,
) {
checkBounds(sourceOffset, length, length) checkBounds(sourceOffset, length, length)
if (length > remaining) if (length > remaining) {
throw IllegalArgumentException("Length:$length exceeds remaining:$remaining") throw IllegalArgumentException("Length:$length exceeds remaining:$remaining")
}
for (i in sourceOffset until sourceOffset + length) { for (i in sourceOffset until sourceOffset + length) {
byte = source[i] byte = source[i]
} }
@@ -739,7 +729,10 @@ class UByteBuffer(
put(bytes) put(bytes)
} }
override fun setElementAt(index: Int, element: UByte) { override fun setElementAt(
index: Int,
element: UByte,
) {
buf[index] = element buf[index] = element
} }
@@ -754,40 +747,36 @@ class UByteBuffer(
return UByteBuffer(bytes, this.order) return UByteBuffer(bytes, this.order)
} }
override fun shortToArray(short: Short): UByteArray { override fun shortToArray(short: Short): UByteArray =
return ubyteArrayOf( ubyteArrayOf(
(short.toInt() shr 8).toUByte(), (short.toInt() shr 8).toUByte(),
short.toUByte() short.toUByte(),
) )
}
override fun ushortToArray(ushort: UShort): UByteArray { override fun ushortToArray(ushort: UShort): UByteArray =
return ubyteArrayOf( ubyteArrayOf(
(ushort.toUInt() shr 8).toUByte(), (ushort.toUInt() shr 8).toUByte(),
ushort.toUByte() ushort.toUByte(),
) )
}
override fun intToArray(int: Int): UByteArray { override fun intToArray(int: Int): UByteArray =
return ubyteArrayOf( ubyteArrayOf(
(int shr 24 and 0xff).toUByte(), (int shr 24 and 0xff).toUByte(),
(int shr 16 and 0xff).toUByte(), (int shr 16 and 0xff).toUByte(),
(int shr 8 and 0xff).toUByte(), (int shr 8 and 0xff).toUByte(),
(int and 0xff).toUByte() (int and 0xff).toUByte(),
) )
}
override fun uintToArray(int: UInt): UByteArray { override fun uintToArray(int: UInt): UByteArray =
return ubyteArrayOf( ubyteArrayOf(
(int shr 24 and 0xffu).toUByte(), (int shr 24 and 0xffu).toUByte(),
(int shr 16 and 0xffu).toUByte(), (int shr 16 and 0xffu).toUByte(),
(int shr 8 and 0xffu).toUByte(), (int shr 8 and 0xffu).toUByte(),
(int and 0xffu).toUByte() (int and 0xffu).toUByte(),
) )
}
override fun longToArray(long: Long): UByteArray { override fun longToArray(long: Long): UByteArray =
return ubyteArrayOf( ubyteArrayOf(
(long shr 56 and 0xff).toUByte(), (long shr 56 and 0xff).toUByte(),
(long shr 48 and 0xff).toUByte(), (long shr 48 and 0xff).toUByte(),
(long shr 40 and 0xff).toUByte(), (long shr 40 and 0xff).toUByte(),
@@ -795,12 +784,11 @@ class UByteBuffer(
(long shr 24 and 0xff).toUByte(), (long shr 24 and 0xff).toUByte(),
(long shr 16 and 0xff).toUByte(), (long shr 16 and 0xff).toUByte(),
(long shr 8 and 0xff).toUByte(), (long shr 8 and 0xff).toUByte(),
(long and 0xff).toUByte() (long and 0xff).toUByte(),
) )
}
override fun ulongToArray(uLong: ULong): UByteArray { override fun ulongToArray(uLong: ULong): UByteArray =
return ubyteArrayOf( ubyteArrayOf(
(uLong shr 56 and 0xffu).toUByte(), (uLong shr 56 and 0xffu).toUByte(),
(uLong shr 48 and 0xffu).toUByte(), (uLong shr 48 and 0xffu).toUByte(),
(uLong shr 40 and 0xffu).toUByte(), (uLong shr 40 and 0xffu).toUByte(),
@@ -808,9 +796,8 @@ class UByteBuffer(
(uLong shr 24 and 0xffu).toUByte(), (uLong shr 24 and 0xffu).toUByte(),
(uLong shr 16 and 0xffu).toUByte(), (uLong shr 16 and 0xffu).toUByte(),
(uLong shr 8 and 0xffu).toUByte(), (uLong shr 8 and 0xffu).toUByte(),
(uLong and 0xffu).toUByte() (uLong and 0xffu).toUByte(),
) )
}
/** /**
* Convert from a [UByteBuffer] to a [ByteBuffer], retaining the same capacity, position, limit * Convert from a [UByteBuffer] to a [ByteBuffer], retaining the same capacity, position, limit
@@ -822,14 +809,13 @@ class UByteBuffer(
return uBuf return uBuf
} }
override fun toString(): String { override fun toString(): String =
return buildString { buildString {
append("Position: $position, limit: $limit, remaining: $remaining. Content: 0x") append("Position: $position, limit: $limit, remaining: $remaining. Content: 0x")
for (i in position until limit) { for (i in position until limit) {
append("${contentBytes[i].toString(16).padStart(2, '0')} ") append("${contentBytes[i].toString(16).padStart(2, '0')} ")
} }
} }
}
/** /**
* Tells whether or not this buffer is equal to another object. * Tells whether or not this buffer is equal to another object.
@@ -28,7 +28,10 @@ package com.vitorpamplona.quartz.utils.io
* @return String of size [2 * length], all lower case * @return String of size [2 * length], all lower case
* @throws IndexOutOfBoundsException if argument(s) specified are wrong * @throws IndexOutOfBoundsException if argument(s) specified are wrong
*/ */
fun ByteArray.toHex(startIndex: Int = 0, length: Int = size): String { fun ByteArray.toHex(
startIndex: Int = 0,
length: Int = size,
): String {
val hexChars = "0123456789abcdef" val hexChars = "0123456789abcdef"
val result = StringBuilder(length * 2) val result = StringBuilder(length * 2)
for (i in startIndex until startIndex + length) { for (i in startIndex until startIndex + length) {
@@ -42,74 +45,56 @@ fun ByteArray.toHex(startIndex: Int = 0, length: Int = size): String {
* Convenience method, forces a Byte to an Int while stripping all sign bits. the Byte becomes * Convenience method, forces a Byte to an Int while stripping all sign bits. the Byte becomes
* the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int. * the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int.
*/ */
infix fun ByteArray.toPosInt(index: Int): Int { infix fun ByteArray.toPosInt(index: Int): Int = this[index].toInt() and 0xFF
return this[index].toInt() and 0xFF
}
/** /**
* Convenience method, forces a Byte to an UInt while stripping all sign bits. the Byte becomes * Convenience method, forces a Byte to an UInt while stripping all sign bits. the Byte becomes
* the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int. * the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int.
*/ */
infix fun ByteArray.toPosUInt(index: Int): UInt { infix fun ByteArray.toPosUInt(index: Int): UInt = this[index].toUInt() and 0xFFu
return this[index].toUInt() and 0xFFu
}
/** /**
* Convenience method, forces a UByte to an Int while stripping all sign bits. the Byte becomes * Convenience method, forces a UByte to an Int while stripping all sign bits. the Byte becomes
* the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int. * the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int.
*/ */
infix fun UByteArray.toPosInt(index: Int): Int { infix fun UByteArray.toPosInt(index: Int): Int = this[index].toInt() and 0xFF
return this[index].toInt() and 0xFF
}
/** /**
* Convenience method, forces a Byte to an UInt while stripping all sign bits. the Byte becomes * Convenience method, forces a Byte to an UInt while stripping all sign bits. the Byte becomes
* the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int. * the LSB of the Int produced. For example, byte of 0xFF becomes 0x000000FF or 255 as the result Int.
*/ */
infix fun UByteArray.toPosUInt(index: Int): UInt { infix fun UByteArray.toPosUInt(index: Int): UInt = this[index].toUInt() and 0xFFu
return this[index].toUInt() and 0xFFu
}
/** /**
* Convenience method, forces a Byte to a Long while stripping all sign bits. the Byte becomes * Convenience method, forces a Byte to a Long while stripping all sign bits. the Byte becomes
* the LSB of the Long produced. For example, byte of 0xFF becomes 0x00000000000000FF or 255 as * the LSB of the Long produced. For example, byte of 0xFF becomes 0x00000000000000FF or 255 as
* the result Long. * the result Long.
*/ */
infix fun ByteArray.toPosLong(index: Int): Long { infix fun ByteArray.toPosLong(index: Int): Long = this[index].toLong() and 0xFF
return this[index].toLong() and 0xFF
}
/** /**
* Convenience method, forces a Byte to a ULong while stripping all sign bits. the Byte becomes * Convenience method, forces a Byte to a ULong while stripping all sign bits. the Byte becomes
* the LSB of the Long produced. For example, byte of 0xFF becomes 0x00000000000000FF or 255 as * the LSB of the Long produced. For example, byte of 0xFF becomes 0x00000000000000FF or 255 as
* the result Long. * the result Long.
*/ */
infix fun ByteArray.toPosULong(index: Int): ULong { infix fun ByteArray.toPosULong(index: Int): ULong = this[index].toULong() and 0xFFu
return this[index].toULong() and 0xFFu
}
/** /**
* Convenience method, forces a UByte to a Long while stripping all sign bits. the Byte becomes * Convenience method, forces a UByte to a Long while stripping all sign bits. the Byte becomes
* the LSB of the Long produced. For example, byte of 0xFF becomes 0x00000000000000FF or 255 as * the LSB of the Long produced. For example, byte of 0xFF becomes 0x00000000000000FF or 255 as
* the result Int. * the result Int.
*/ */
infix fun UByteArray.toPosLong(index: Int): Long { infix fun UByteArray.toPosLong(index: Int): Long = this[index].toLong() and 0xFF
return this[index].toLong() and 0xFF
}
/** /**
* Convenience method, forces a UByte to a ULong while using only the LSB. * Convenience method, forces a UByte to a ULong while using only the LSB.
* For example, byte of 0xFF becomes 0x00000000000000FF or 255 as the result ULong. * For example, byte of 0xFF becomes 0x00000000000000FF or 255 as the result ULong.
*/ */
infix fun UByteArray.toPosULong(index: Int): ULong { infix fun UByteArray.toPosULong(index: Int): ULong = this[index].toULong() and 0xFFu
return this[index].toULong() and 0xFFu
}
/** // These endian-aware extensions functions assist with retrieving Short, UShort, Int, UInt, Long, Ulong, Float,
* These endian-aware extensions functions assist with retrieving Short, UShort, Int, UInt, Long, Ulong, Float, // and Double values from ByteArray and UByteArray. For some reason Kotlin only offers these for Little
* and Double values from ByteArray and UByteArray. For some reason Kotlin only offers these for Little // Endian (you have to do your own reverse() for BigEndian) and only in Kotlin Native.
* Endian (you have to do your own reverse() for BigEndian) and only in Kotlin Native.
*/
/** /**
* Change one byte into an Int with toPosInt, then Binary Shift left the specified number of times. * Change one byte into an Int with toPosInt, then Binary Shift left the specified number of times.
@@ -117,9 +102,10 @@ infix fun UByteArray.toPosULong(index: Int): ULong {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting Int * @return resulting Int
*/ */
fun ByteArray.toIntShl(index: Int, shift: Int = 0): Int { fun ByteArray.toIntShl(
return this toPosInt index shl shift index: Int,
} shift: Int = 0,
): Int = this toPosInt index shl shift
/** /**
* Change one byte into an Int with toPosInt, then Binary Shift left the specified number of times. * Change one byte into an Int with toPosInt, then Binary Shift left the specified number of times.
@@ -127,9 +113,10 @@ fun ByteArray.toIntShl(index: Int, shift: Int = 0): Int {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return result as UInt * @return result as UInt
*/ */
fun ByteArray.toUIntShl(index: Int, shift: Int = 0): UInt { fun ByteArray.toUIntShl(
return this toPosUInt index shl shift index: Int,
} shift: Int = 0,
): UInt = this toPosUInt index shl shift
/** /**
* Change one byte into a Long, after the byte value is Binary Shifted left the specified number of times. * Change one byte into a Long, after the byte value is Binary Shifted left the specified number of times.
@@ -137,9 +124,10 @@ fun ByteArray.toUIntShl(index: Int, shift: Int = 0): UInt {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting Long * @return resulting Long
*/ */
fun ByteArray.toLongShl(index: Int, shift: Int = 0): Long { fun ByteArray.toLongShl(
return this toPosLong index shl shift index: Int,
} shift: Int = 0,
): Long = this toPosLong index shl shift
/** /**
* Change one byte into a ULong, after the byte value is Binary Shifted left the specified number of times. * Change one byte into a ULong, after the byte value is Binary Shifted left the specified number of times.
@@ -147,9 +135,10 @@ fun ByteArray.toLongShl(index: Int, shift: Int = 0): Long {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting ULong * @return resulting ULong
*/ */
fun ByteArray.toULongShl(index: Int, shift: Int = 0): ULong { fun ByteArray.toULongShl(
return this toPosULong index shl shift index: Int,
} shift: Int = 0,
): ULong = this toPosULong index shl shift
/** /**
* starting at the specified index, change bytes at index and index+1 to a Short. Both LittleEndian * starting at the specified index, change bytes at index and index+1 to a Short. Both LittleEndian
@@ -160,10 +149,12 @@ fun ByteArray.toULongShl(index: Int, shift: Int = 0): ULong {
*/ */
fun ByteArray.getShortAt( fun ByteArray.getShortAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): Short { ): Short =
return if (littleEndian) (toIntShl(index + 1, 8) or toIntShl(index)).toShort() if (littleEndian) {
else (toIntShl(index, 8) or toIntShl(index + 1)).toShort() (toIntShl(index + 1, 8) or toIntShl(index)).toShort()
} else {
(toIntShl(index, 8) or toIntShl(index + 1)).toShort()
} }
/** /**
@@ -175,11 +166,12 @@ fun ByteArray.getShortAt(
*/ */
fun ByteArray.getUShortAt( fun ByteArray.getUShortAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): UShort { ): UShort =
return if (littleEndian) if (littleEndian) {
(toUIntShl(index + 1, 8) or toUIntShl(index)).toUShort() (toUIntShl(index + 1, 8) or toUIntShl(index)).toUShort()
else (toUIntShl(index, 8) or toUIntShl(index + 1)).toUShort() } else {
(toUIntShl(index, 8) or toUIntShl(index + 1)).toUShort()
} }
/** /**
@@ -191,14 +183,15 @@ fun ByteArray.getUShortAt(
*/ */
fun ByteArray.getIntAt( fun ByteArray.getIntAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): Int { ): Int =
return if (littleEndian) if (littleEndian) {
toIntShl(index + 3, 24) or toIntShl(index + 3, 24) or
toIntShl(index + 2, 16) or toIntShl(index + 2, 16) or
toIntShl(index + 1, 8) or toIntShl(index + 1, 8) or
toIntShl(index) toIntShl(index)
else toIntShl(index, 24) or } else {
toIntShl(index, 24) or
toIntShl(index + 1, 16) or toIntShl(index + 1, 16) or
toIntShl(index + 2, 8) or toIntShl(index + 2, 8) or
toIntShl(index + 3) toIntShl(index + 3)
@@ -213,14 +206,15 @@ fun ByteArray.getIntAt(
*/ */
fun ByteArray.getUIntAt( fun ByteArray.getUIntAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): UInt { ): UInt =
return if (littleEndian) if (littleEndian) {
toUIntShl(index + 3, 24) or toUIntShl(index + 3, 24) or
toUIntShl(index + 2, 16) or toUIntShl(index + 2, 16) or
toUIntShl(index + 1, 8) or toUIntShl(index + 1, 8) or
toUIntShl(index) toUIntShl(index)
else toUIntShl(index, 24) or } else {
toUIntShl(index, 24) or
toUIntShl(index + 1, 16) or toUIntShl(index + 1, 16) or
toUIntShl(index + 2, 8) or toUIntShl(index + 2, 8) or
toUIntShl(index + 3) toUIntShl(index + 3)
@@ -235,9 +229,9 @@ fun ByteArray.getUIntAt(
*/ */
fun ByteArray.getLongAt( fun ByteArray.getLongAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): Long { ): Long =
return if (littleEndian) if (littleEndian) {
toLongShl(index + 7, 56) or toLongShl(index + 7, 56) or
toLongShl(index + 6, 48) or toLongShl(index + 6, 48) or
toLongShl(index + 5, 40) or toLongShl(index + 5, 40) or
@@ -246,7 +240,8 @@ fun ByteArray.getLongAt(
toLongShl(index + 2, 16) or toLongShl(index + 2, 16) or
toLongShl(index + 1, 8) or toLongShl(index + 1, 8) or
toLongShl(index) toLongShl(index)
else toLongShl(index, 56) or } else {
toLongShl(index, 56) or
toLongShl(index + 1, 48) or toLongShl(index + 1, 48) or
toLongShl(index + 2, 40) or toLongShl(index + 2, 40) or
toLongShl(index + 3, 32) or toLongShl(index + 3, 32) or
@@ -265,9 +260,9 @@ fun ByteArray.getLongAt(
*/ */
fun ByteArray.getULongAt( fun ByteArray.getULongAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): ULong { ): ULong =
return if (littleEndian) if (littleEndian) {
toULongShl(index + 7, 56) or toULongShl(index + 7, 56) or
toULongShl(index + 6, 48) or toULongShl(index + 6, 48) or
toULongShl(index + 5, 40) or toULongShl(index + 5, 40) or
@@ -276,7 +271,8 @@ fun ByteArray.getULongAt(
toULongShl(index + 2, 16) or toULongShl(index + 2, 16) or
toULongShl(index + 1, 8) or toULongShl(index + 1, 8) or
toULongShl(index) toULongShl(index)
else toULongShl(index, 56) or } else {
toULongShl(index, 56) or
toULongShl(index + 1, 48) or toULongShl(index + 1, 48) or
toULongShl(index + 2, 40) or toULongShl(index + 2, 40) or
toULongShl(index + 3, 32) or toULongShl(index + 3, 32) or
@@ -293,7 +289,10 @@ fun ByteArray.getULongAt(
* @return String of size [2 * length], all lower case * @return String of size [2 * length], all lower case
* @throws IndexOutOfBoundsException if argument(s) specified are wrong * @throws IndexOutOfBoundsException if argument(s) specified are wrong
*/ */
fun UByteArray.toHex(startIndex: Int = 0, length: Int = size): String { fun UByteArray.toHex(
startIndex: Int = 0,
length: Int = size,
): String {
val hexChars = "0123456789abcdef" val hexChars = "0123456789abcdef"
val result = StringBuilder(length * 2) val result = StringBuilder(length * 2)
for (i in startIndex until startIndex + length) { for (i in startIndex until startIndex + length) {
@@ -309,9 +308,10 @@ fun UByteArray.toHex(startIndex: Int = 0, length: Int = size): String {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting Int * @return resulting Int
*/ */
fun UByteArray.toIntShl(index: Int, shift: Int = 0): Int { fun UByteArray.toIntShl(
return this toPosInt index shl shift index: Int,
} shift: Int = 0,
): Int = this toPosInt index shl shift
/** /**
* Change one byte into an UInt, after the byte value is Binary Shifted left the specified number of times. * Change one byte into an UInt, after the byte value is Binary Shifted left the specified number of times.
@@ -319,9 +319,10 @@ fun UByteArray.toIntShl(index: Int, shift: Int = 0): Int {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting UInt * @return resulting UInt
*/ */
fun UByteArray.toUIntShl(index: Int, shift: Int = 0): UInt { fun UByteArray.toUIntShl(
return this toPosUInt index shl shift index: Int,
} shift: Int = 0,
): UInt = this toPosUInt index shl shift
/** /**
* Change one byte into a Long, after the byte value is Binary Shifted left the specified number of times. * Change one byte into a Long, after the byte value is Binary Shifted left the specified number of times.
@@ -329,9 +330,10 @@ fun UByteArray.toUIntShl(index: Int, shift: Int = 0): UInt {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting Long * @return resulting Long
*/ */
fun UByteArray.toLongShl(index: Int, shift: Int = 0): Long { fun UByteArray.toLongShl(
return this toPosLong index shl shift index: Int,
} shift: Int = 0,
): Long = this toPosLong index shl shift
/** /**
* Change one byte into a ULong, after the byte value is Binary Shifted left the specified number of times. * Change one byte into a ULong, after the byte value is Binary Shifted left the specified number of times.
@@ -339,9 +341,10 @@ fun UByteArray.toLongShl(index: Int, shift: Int = 0): Long {
* @param shift number of times value is binary shifted left. * @param shift number of times value is binary shifted left.
* @return resulting ULong * @return resulting ULong
*/ */
fun UByteArray.toULongShl(index: Int, shift: Int = 0): ULong { fun UByteArray.toULongShl(
return this toPosULong index shl shift index: Int,
} shift: Int = 0,
): ULong = this toPosULong index shl shift
/** /**
* starting at the specified index, change bytes at index and index+1 to a Short. Both LittleEndian * starting at the specified index, change bytes at index and index+1 to a Short. Both LittleEndian
@@ -352,11 +355,12 @@ fun UByteArray.toULongShl(index: Int, shift: Int = 0): ULong {
*/ */
fun UByteArray.getShortAt( fun UByteArray.getShortAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): Short { ): Short =
return if (littleEndian) if (littleEndian) {
(toIntShl(index + 1, 8) or toIntShl(index)).toShort() (toIntShl(index + 1, 8) or toIntShl(index)).toShort()
else (toIntShl(index, 8) or toIntShl(index + 1)).toShort() } else {
(toIntShl(index, 8) or toIntShl(index + 1)).toShort()
} }
/** /**
@@ -368,11 +372,12 @@ fun UByteArray.getShortAt(
*/ */
fun UByteArray.getUShortAt( fun UByteArray.getUShortAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): UShort { ): UShort =
return if (littleEndian) if (littleEndian) {
(toUIntShl(index + 1, 8) or toUIntShl(index)).toUShort() (toUIntShl(index + 1, 8) or toUIntShl(index)).toUShort()
else (toUIntShl(index, 8) or toUIntShl(index + 1)).toUShort() } else {
(toUIntShl(index, 8) or toUIntShl(index + 1)).toUShort()
} }
/** /**
@@ -384,14 +389,15 @@ fun UByteArray.getUShortAt(
*/ */
fun UByteArray.getIntAt( fun UByteArray.getIntAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): Int { ): Int =
return if (littleEndian) if (littleEndian) {
toIntShl(index + 3, 24) or toIntShl(index + 3, 24) or
toIntShl(index + 2, 16) or toIntShl(index + 2, 16) or
toIntShl(index + 1, 8) or toIntShl(index + 1, 8) or
toIntShl(index) toIntShl(index)
else toIntShl(index, 24) or } else {
toIntShl(index, 24) or
toIntShl(index + 1, 16) or toIntShl(index + 1, 16) or
toIntShl(index + 2, 8) or toIntShl(index + 2, 8) or
toIntShl(index + 3) toIntShl(index + 3)
@@ -406,14 +412,15 @@ fun UByteArray.getIntAt(
*/ */
fun UByteArray.getUIntAt( fun UByteArray.getUIntAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): UInt { ): UInt =
return if (littleEndian) if (littleEndian) {
toUIntShl(index + 3, 24) or toUIntShl(index + 3, 24) or
toUIntShl(index + 2, 16) or toUIntShl(index + 2, 16) or
toUIntShl(index + 1, 8) or toUIntShl(index + 1, 8) or
toUIntShl(index) toUIntShl(index)
else toUIntShl(index, 24) or } else {
toUIntShl(index, 24) or
toUIntShl(index + 1, 16) or toUIntShl(index + 1, 16) or
toUIntShl(index + 2, 8) or toUIntShl(index + 2, 8) or
toUIntShl(index + 3) toUIntShl(index + 3)
@@ -428,9 +435,9 @@ fun UByteArray.getUIntAt(
*/ */
fun UByteArray.getLongAt( fun UByteArray.getLongAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): Long { ): Long =
return if (littleEndian) if (littleEndian) {
toLongShl(index + 7, 56) or toLongShl(index + 7, 56) or
toLongShl(index + 6, 48) or toLongShl(index + 6, 48) or
toLongShl(index + 5, 40) or toLongShl(index + 5, 40) or
@@ -439,7 +446,8 @@ fun UByteArray.getLongAt(
toLongShl(index + 2, 16) or toLongShl(index + 2, 16) or
toLongShl(index + 1, 8) or toLongShl(index + 1, 8) or
toLongShl(index) toLongShl(index)
else toLongShl(index, 56) or } else {
toLongShl(index, 56) or
toLongShl(index + 1, 48) or toLongShl(index + 1, 48) or
toLongShl(index + 2, 40) or toLongShl(index + 2, 40) or
toLongShl(index + 3, 32) or toLongShl(index + 3, 32) or
@@ -458,9 +466,9 @@ fun UByteArray.getLongAt(
*/ */
fun UByteArray.getULongAt( fun UByteArray.getULongAt(
index: Int, index: Int,
littleEndian: Boolean = true littleEndian: Boolean = true,
): ULong { ): ULong =
return if (littleEndian) if (littleEndian) {
toULongShl(index + 7, 56) or toULongShl(index + 7, 56) or
toULongShl(index + 6, 48) or toULongShl(index + 6, 48) or
toULongShl(index + 5, 40) or toULongShl(index + 5, 40) or
@@ -469,7 +477,8 @@ fun UByteArray.getULongAt(
toULongShl(index + 2, 16) or toULongShl(index + 2, 16) or
toULongShl(index + 1, 8) or toULongShl(index + 1, 8) or
toULongShl(index) toULongShl(index)
else toULongShl(index, 56) or } else {
toULongShl(index, 56) or
toULongShl(index + 1, 48) or toULongShl(index + 1, 48) or
toULongShl(index + 2, 40) or toULongShl(index + 2, 40) or
toULongShl(index + 3, 32) or toULongShl(index + 3, 32) or