package com.infendro.bytearray import com.infendro.bytearray.ByteOrder.BIG_ENDIAN infix fun UByteArray.and( that: UByteArray, ): UByteArray { if (this.size != that.size) throw Exception() return UByteArray(size) { i -> this[i] and that[i] } } infix fun UByteArray.or( that: UByteArray, ): UByteArray { if (this.size != that.size) throw Exception() return UByteArray(size) { i -> this[i] or that[i] } } infix fun UByteArray.xor( that: UByteArray, ): UByteArray { if (this.size != that.size) throw Exception() return UByteArray(size) { i -> this[i] xor that[i] } } fun UByteArray.padStart( length: Int, padByte: UByte, ): UByteArray { return buildList { repeat(length - size) { add(padByte) } addAll(this) }.toUByteArray() } fun UByteArray.padEnd( length: Int, padByte: UByte, ): UByteArray { return buildList { addAll(this) repeat(length - size) { add(padByte) } }.toUByteArray() } fun UByteArray.toInt( order: ByteOrder = BIG_ENDIAN, ): Int { if (size != 4) throw Exception() val bytes = order.normalize(this) return bytes.fold(0) { acc, byte -> (acc shl 8) or (byte.toInt() and 0xFF) } } fun UByteArray.toIntArray( order: ByteOrder = BIG_ENDIAN, ): IntArray { if (size % 4 != 0) throw Exception() return toList() .chunked(4) .map { it.toUByteArray().toInt(order) } .toIntArray() } fun UByteArray.toLong( order: ByteOrder = BIG_ENDIAN, ): Long { if (size != 8) throw Exception() val bytes = order.normalize(this) return bytes.fold(0L) { acc, byte -> (acc shl 8) or (byte.toLong() and 0xFFL) } } fun UByteArray.toLongArray( order: ByteOrder = BIG_ENDIAN, ): LongArray { if (size % 8 != 0) throw Exception() return toList() .chunked(8) .map { it.toUByteArray().toLong(order) } .toLongArray() } fun UByteArray.toUInt( order: ByteOrder = BIG_ENDIAN, ): UInt { if (size != 4) throw Exception() val bytes = order.normalize(this) return bytes.fold(0U) { acc, byte -> (acc shl 8) or (byte.toUInt() and 0xFFU) } } fun UByteArray.toUIntArray( order: ByteOrder = BIG_ENDIAN, ): UIntArray { if (size % 4 != 0) throw Exception() return toList() .chunked(4) .map { it.toUByteArray().toUInt(order) } .toUIntArray() } fun UByteArray.toULong( order: ByteOrder = BIG_ENDIAN, ): ULong { if (size != 8) throw Exception() val bytes = order.normalize(this) return bytes.fold(0UL) { acc, byte -> (acc shl 8) or (byte.toULong() and 0xFFUL) } } fun UByteArray.toULongArray( order: ByteOrder = BIG_ENDIAN, ): ULongArray { if (size % 8 != 0) throw Exception() return toList() .chunked(8) .map { it.toUByteArray().toULong(order) } .toULongArray() }