byte vec & bit vec (bit set)
This commit is contained in:
10
src/main/kotlin/blitz/Bits.kt
Normal file
10
src/main/kotlin/blitz/Bits.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package blitz
|
||||||
|
|
||||||
|
fun Byte.toBool(): Boolean =
|
||||||
|
(this.toInt() != 0)
|
||||||
|
|
||||||
|
fun Boolean.toByte(): Byte =
|
||||||
|
if (this) 1 else 0
|
||||||
|
|
||||||
|
fun Boolean.toBit2(): Char =
|
||||||
|
if (this) '1' else '0'
|
39
src/main/kotlin/blitz/Endian.kt
Normal file
39
src/main/kotlin/blitz/Endian.kt
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package blitz
|
||||||
|
|
||||||
|
enum class Endian {
|
||||||
|
LITTLE,
|
||||||
|
BIG
|
||||||
|
;
|
||||||
|
|
||||||
|
infix fun encodeLittle(little: ByteArray) =
|
||||||
|
if (this == BIG) little.reversedArray()
|
||||||
|
else little
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Long.toBytes(endian: Endian) =
|
||||||
|
endian encodeLittle
|
||||||
|
toInt().toBytes(Endian.LITTLE) +
|
||||||
|
toInt().shr(32).toBytes(Endian.LITTLE)
|
||||||
|
|
||||||
|
fun Int.toBytes(endian: Endian) =
|
||||||
|
endian encodeLittle byteArrayOf(
|
||||||
|
this.and(0xFF).toByte(),
|
||||||
|
this.shr(8).and(0xFF).toByte(),
|
||||||
|
this.shr(16).and(0xFF).toByte(),
|
||||||
|
this.shr(24).and(0xFF).toByte()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun UInt.toBytes(endian: Endian) =
|
||||||
|
toInt().toBytes(endian)
|
||||||
|
|
||||||
|
fun Short.toBytes(endian: Endian) =
|
||||||
|
endian encodeLittle toInt().toBytes(Endian.LITTLE).copyOf(2)
|
||||||
|
|
||||||
|
fun UShort.toBytes(endian: Endian) =
|
||||||
|
toShort().toBytes(endian)
|
||||||
|
|
||||||
|
fun Byte.toBytes() =
|
||||||
|
byteArrayOf(this)
|
||||||
|
|
||||||
|
fun UByte.toBytes() =
|
||||||
|
toByte().toBytes()
|
@@ -15,6 +15,39 @@ interface ByteBatchIterator: BatchIterator<Byte> {
|
|||||||
fun nextBytes(dest: ByteArray): Int
|
fun nextBytes(dest: ByteArray): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun BatchIterator<Byte>.asByteBatchIterator(): ByteBatchIterator =
|
||||||
|
object : ByteBatchIterator {
|
||||||
|
override fun nextBytes(dest: ByteArray): Int {
|
||||||
|
val temp = Array<Byte>(dest.size) { 0 }
|
||||||
|
val am = this@asByteBatchIterator.next(temp)
|
||||||
|
temp.copyInto(dest)
|
||||||
|
return am
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(dest: Array<Byte>): Int =
|
||||||
|
this@asByteBatchIterator.next(dest)
|
||||||
|
|
||||||
|
override fun next(limit: Int): List<Byte> =
|
||||||
|
this@asByteBatchIterator.next(limit)
|
||||||
|
|
||||||
|
override fun next(dest: MutableList<Byte>, limit: Int) =
|
||||||
|
this@asByteBatchIterator.next(dest, limit)
|
||||||
|
|
||||||
|
override fun nextBytes(limit: Int): ByteArray {
|
||||||
|
val temp = Array<Byte>(limit) { 0 }
|
||||||
|
val am = this@asByteBatchIterator.next(temp)
|
||||||
|
val o = ByteArray(am)
|
||||||
|
temp.copyInto(o)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): Byte =
|
||||||
|
this@asByteBatchIterator.next()
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean =
|
||||||
|
this@asByteBatchIterator.hasNext()
|
||||||
|
}
|
||||||
|
|
||||||
interface BatchSequence<T>: Sequence<T> {
|
interface BatchSequence<T>: Sequence<T> {
|
||||||
override fun iterator(): BatchIterator<T>
|
override fun iterator(): BatchIterator<T>
|
||||||
}
|
}
|
||||||
|
66
src/main/kotlin/blitz/collections/BitVec.kt
Normal file
66
src/main/kotlin/blitz/collections/BitVec.kt
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package blitz.collections
|
||||||
|
|
||||||
|
import blitz.toBit2
|
||||||
|
import blitz.toBool
|
||||||
|
import blitz.toByte
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
// TODO: make it hybrid to a real bitset if a lot of elements
|
||||||
|
|
||||||
|
class BitVec private constructor(
|
||||||
|
private val byteVec: ByteVec
|
||||||
|
): Vec<Boolean> {
|
||||||
|
constructor(initCap: Int = 0): this(ByteVec(initCap))
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = byteVec.size
|
||||||
|
|
||||||
|
// TODO: implement better
|
||||||
|
fun toBytes(): ByteArray =
|
||||||
|
toString()
|
||||||
|
.padEnd(ceil(byteVec.size.toFloat() / 8).toInt(), '0')
|
||||||
|
.chunked(8)
|
||||||
|
.map { it.toByte(2) }
|
||||||
|
.toByteArray()
|
||||||
|
|
||||||
|
override fun flip() =
|
||||||
|
byteVec.flip()
|
||||||
|
|
||||||
|
override fun copy(): Vec<Boolean> =
|
||||||
|
BitVec(byteVec)
|
||||||
|
|
||||||
|
override fun reserve(amount: Int) =
|
||||||
|
byteVec.reserve(amount)
|
||||||
|
|
||||||
|
override fun popBack(): Boolean =
|
||||||
|
byteVec.popBack().toBool()
|
||||||
|
|
||||||
|
override fun pushBack(elem: Boolean) =
|
||||||
|
byteVec.pushBack(elem.toByte())
|
||||||
|
|
||||||
|
override fun get(index: Int): Boolean =
|
||||||
|
byteVec[index].toBool()
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<Boolean> =
|
||||||
|
byteVec.iterator().mapModifier { it.toBool() }
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
joinToString(separator = "") { it.toBit2().toString() }
|
||||||
|
|
||||||
|
override fun set(index: Int, value: Boolean) {
|
||||||
|
byteVec[index] = value.toByte()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// TODO: implement better
|
||||||
|
fun from(bytes: ByteArray): BitVec =
|
||||||
|
BitVec(ByteVec.from(
|
||||||
|
bytes.asSequence()
|
||||||
|
.map { it
|
||||||
|
.toString(2)
|
||||||
|
.map { c -> (c == '1').toByte() }
|
||||||
|
}
|
||||||
|
.flatten()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
5
src/main/kotlin/blitz/collections/ByteArrayUtils.kt
Normal file
5
src/main/kotlin/blitz/collections/ByteArrayUtils.kt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package blitz.collections
|
||||||
|
|
||||||
|
fun Array<Byte>.copyInto(dest: ByteArray) {
|
||||||
|
forEachIndexed { i, byte -> dest[i] = byte }
|
||||||
|
}
|
79
src/main/kotlin/blitz/collections/ByteVec.kt
Normal file
79
src/main/kotlin/blitz/collections/ByteVec.kt
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package blitz.collections
|
||||||
|
|
||||||
|
class ByteVec(initCap: Int = 0): Vec<Byte>, ByteBatchSequence {
|
||||||
|
override var size = 0
|
||||||
|
private var cap = initCap
|
||||||
|
private var array = ByteArray(initCap)
|
||||||
|
|
||||||
|
fun copyAsArray(): ByteArray =
|
||||||
|
array.copyOfRange(0, size)
|
||||||
|
|
||||||
|
fun copyIntoArray(arr: ByteArray, destOff: Int = 0, startOff: Int = 0) =
|
||||||
|
array.copyInto(arr, destOff, startOff, size)
|
||||||
|
|
||||||
|
override fun copy(): ByteVec =
|
||||||
|
ByteVec(size).also {
|
||||||
|
copyIntoArray(it.array)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reserve(amount: Int) {
|
||||||
|
if (amount > 0 && cap - size >= amount)
|
||||||
|
return
|
||||||
|
array = array.copyOf(size + amount)
|
||||||
|
cap = size + amount
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun popBack(): Byte =
|
||||||
|
array[size - 1].also {
|
||||||
|
reserve(-1)
|
||||||
|
size --
|
||||||
|
}
|
||||||
|
|
||||||
|
fun popBack(dest: ByteArray, destOff: Int = 0) {
|
||||||
|
copyIntoArray(dest, destOff, size - dest.size)
|
||||||
|
reserve(-dest.size)
|
||||||
|
size -= dest.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(index: Int): Byte =
|
||||||
|
array[index]
|
||||||
|
|
||||||
|
override fun flip() {
|
||||||
|
array = array.reversedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pushBack(arr: ByteArray) {
|
||||||
|
reserve(arr.size)
|
||||||
|
arr.copyInto(array, size)
|
||||||
|
size += arr.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushBack(elem: Byte) {
|
||||||
|
reserve(8)
|
||||||
|
array[size] = elem
|
||||||
|
size ++
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): ByteBatchIterator =
|
||||||
|
array.asSequence().asBatch().iterator().asByteBatchIterator()
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
joinToString(prefix = "[", postfix = "]") { "0x${it.toUByte().toString(16)}" }
|
||||||
|
|
||||||
|
override fun set(index: Int, value: Byte) {
|
||||||
|
array[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(bytes: ByteArray) =
|
||||||
|
ByteVec(bytes.size).also {
|
||||||
|
bytes.copyInto(it.array)
|
||||||
|
it.size += bytes.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun from(bytes: Sequence<Byte>) =
|
||||||
|
ByteVec().also { bv ->
|
||||||
|
bytes.forEach(bv::pushBack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/main/kotlin/blitz/collections/IterUtils.kt
Normal file
10
src/main/kotlin/blitz/collections/IterUtils.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package blitz.collections
|
||||||
|
|
||||||
|
fun <T, R> Iterator<T>.mapModifier(fn: (T) -> R): Iterator<R> =
|
||||||
|
object : Iterator<R> {
|
||||||
|
override fun next(): R =
|
||||||
|
fn(this@mapModifier.next())
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean =
|
||||||
|
this@mapModifier.hasNext()
|
||||||
|
}
|
31
src/main/kotlin/blitz/collections/Vec.kt
Normal file
31
src/main/kotlin/blitz/collections/Vec.kt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package blitz.collections
|
||||||
|
|
||||||
|
interface Vec<T>: IndexableSequence<T> {
|
||||||
|
val size: Int
|
||||||
|
|
||||||
|
fun flip()
|
||||||
|
|
||||||
|
fun copy(): Vec<T>
|
||||||
|
|
||||||
|
fun reserve(amount: Int)
|
||||||
|
|
||||||
|
fun pushBack(elem: T)
|
||||||
|
fun pushBack(elems: Array<T>) {
|
||||||
|
reserve(elems.size)
|
||||||
|
elems.forEach(::pushBack)
|
||||||
|
}
|
||||||
|
fun pushBack(elems: Collection<T>) {
|
||||||
|
reserve(elems.size)
|
||||||
|
elems.forEach(::pushBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun popBack(): T
|
||||||
|
fun popBack(dest: Array<T>) {
|
||||||
|
var writer = 0
|
||||||
|
repeat(dest.size) {
|
||||||
|
dest[writer ++] = popBack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun set(index: Int, value: T)
|
||||||
|
}
|
Reference in New Issue
Block a user