179 lines
5.1 KiB
Kotlin
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
|
|
}
|