Make linter happy, I guess.
This commit is contained in:
+62
-128
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user