Files
bytes.kt/src/commonMain/kotlin/com/infendro/bytes/bytearray/Operator.kt
2026-02-05 14:19:51 +01:00

179 lines
5.1 KiB
Kotlin

package com.infendro.bytes.bytearray
import com.infendro.bytes.byte.not
import kotlin.experimental.and
import kotlin.experimental.or
import kotlin.experimental.xor
private inline fun ByteArray.combineInto(
that: ByteArray,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
thatStartIndex: Int = 0,
combine: (Byte, Byte) -> Byte,
) {
val length = endIndex - startIndex
require(length >= 0)
require(startIndex in 0..(size - length))
require(thatStartIndex in 0..(that.size - length))
require(destinationOffset in 0..(destination.size - length))
for (i in 0..<length) {
destination[destinationOffset + i] = combine(this[startIndex + i], that[thatStartIndex + i])
}
}
private inline fun ByteArray.combineInto(
that: Byte,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
combine: (Byte, Byte) -> Byte,
) {
val length = endIndex - startIndex
require(length >= 0)
require(startIndex in 0..(size - length))
require(destinationOffset in 0..(destination.size - length))
for (i in 0..<length) {
destination[destinationOffset + i] = combine(this[startIndex + i], that)
}
}
private inline fun ByteArray.combine(that: ByteArray, combine: (Byte, Byte) -> Byte): ByteArray {
require(this.size == that.size)
val result = ByteArray(size)
combineInto(that, result, combine = combine)
return result
}
private inline fun ByteArray.combine(that: Byte, combine: (Byte, Byte) -> Byte): ByteArray {
val result = ByteArray(size)
combineInto(that, result, combine = combine)
return result
}
fun ByteArray.andInto(
that: ByteArray,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
thatStartIndex: Int = 0,
) {
combineInto(that, destination, destinationOffset, startIndex, endIndex, thatStartIndex) { a, b -> a and b }
}
fun ByteArray.andInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size) {
andInto(destination, destination, destinationOffset, startIndex, endIndex, destinationOffset)
}
fun ByteArray.andInto(
that: Byte,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
) {
combineInto(that, destination, destinationOffset, startIndex, endIndex) { a, b -> a and b }
}
infix fun ByteArray.and(that: ByteArray): ByteArray {
return combine(that) { a, b -> a and b }
}
infix fun ByteArray.and(that: Byte): ByteArray {
return combine(that) { a, b -> a and b }
}
fun ByteArray.orInto(
that: ByteArray,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
thatStartIndex: Int = 0,
) {
combineInto(that, destination, destinationOffset, startIndex, endIndex, thatStartIndex) { a, b -> a or b }
}
fun ByteArray.orInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size) {
orInto(destination, destination, destinationOffset, startIndex, endIndex, destinationOffset)
}
fun ByteArray.orInto(
that: Byte,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
) {
combineInto(that, destination, destinationOffset, startIndex, endIndex) { a, b -> a or b }
}
infix fun ByteArray.or(that: ByteArray): ByteArray {
return combine(that) { a, b -> a or b }
}
infix fun ByteArray.or(that: Byte): ByteArray {
return combine(that) { a, b -> a or b }
}
fun ByteArray.xorInto(
that: ByteArray,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
thatStartIndex: Int = 0,
) {
combineInto(that, destination, destinationOffset, startIndex, endIndex, thatStartIndex) { a, b -> a xor b }
}
fun ByteArray.xorInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size) {
xorInto(destination, destination, destinationOffset, startIndex, endIndex, destinationOffset)
}
fun ByteArray.xorInto(
that: Byte,
destination: ByteArray,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size,
) {
combineInto(that, destination, destinationOffset, startIndex, endIndex) { a, b -> a xor b }
}
infix fun ByteArray.xor(that: ByteArray): ByteArray {
return combine(that) { a, b -> a xor b }
}
infix fun ByteArray.xor(that: Byte): ByteArray {
return combine(that) { a, b -> a xor b }
}
fun ByteArray.invInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size) {
val length = endIndex - startIndex
require(length >= 0)
require(startIndex in 0..(size - length))
require(destinationOffset in 0..(destination.size - length))
for (i in 0..<length) {
destination[destinationOffset + i] = !this[startIndex + i]
}
}
fun ByteArray.inv(startIndex: Int = 0, endIndex: Int = size) {
invInto(this, startIndex, startIndex, endIndex)
}
operator fun ByteArray.not(): ByteArray {
val result = ByteArray(size)
invInto(result)
return result
}