Can I use the UInt class to make this easier to re...
# getting-started
s
Can I use the UInt class to make this easier to read?
Copy code
private fun getUInt16(firstByte: Byte, secondByte: Byte): Int =
    firstByte.toInt() shl 8 and 0xFF00 or (secondByte.toInt() and 0xFF)
1
r
Should make a infix + extension function
Copy code
private infix fun Byte.getUInt16(byte: Byte): Int =
    toInt() shl 8 and 0xFF00 or (byte.toInt() and 0xFF)
🙏 1
k
It's not much better than the original, but you can do:
Copy code
private fun getUInt16(firstByte: Byte, secondByte: Byte): Int =
    firstByte.toUByte().toInt() shl 8 or secondByte.toUByte().toInt()
... though if your function is called getUInt16, maybe it should return a UInt instead of an Int; then the expression becomes slightly simpler:
Copy code
private fun getUInt16(firstByte: Byte, secondByte: Byte): UInt =
        firstByte.toUByte() * 256u + secondByte.toUByte()
(though I've had to use arithmetic operations because Kotlin doesn't allow bitwise operations on UByte for some strange reason)
🙏 1
e
as far as the JVM goes, there are no bitwise operators on bytes, only ints and longs. most native platforms are similar, and JS is worse (only int)
🙏 1
s
@Raphael TEYSSANDIER @Klitos Kyriacou @ephemient Thank you all for your advice. I changed it to infix and do this now:
Copy code
const val INT16_BYTE_SIZE: Int = 2
const val INT24_BYTE_SIZE: Int = 3
const val INT32_BYTE_SIZE: Int = 4

fun Byte.toInt8(): Byte = this

fun Byte.toUInt8(): Short = (toInt() and 0xFF).toShort()

fun ByteArray.toInt16(): Short {

    require(size == INT16_BYTE_SIZE) { "Required $INT16_BYTE_SIZE bytes, but was $size" }

    return (this[0].toShort().toInt() shl 8 and 0xFF00.toShort().toInt() or
        (this[1].toShort().toInt() and 0xFF.toShort().toInt())).toShort()
}

fun ByteArray.toUInt16(): Int {

    require(size == INT16_BYTE_SIZE) { "Required $INT16_BYTE_SIZE bytes, but was $size" }

    return this[0].toInt() shl 8 and 0xFF00 or (this[1].toInt() and 0xFF)
}

fun ByteArray.toInt24(): Int {

    require(size == INT24_BYTE_SIZE) { "Required $INT24_BYTE_SIZE bytes, but was $size" }

    return this[0].toInt() shl 16 and 0xFF0000 or
        (this[1].toInt() shl 8 and 0xFF00) or
        (this[2].toInt() and 0xFF)
}

fun ByteArray.toInt32(): Int {

    require(size == INT32_BYTE_SIZE) { "Required $INT32_BYTE_SIZE bytes, but was $size" }

    return this[0].toInt() shl 24 and -0x1000000 or
        (this[1].toInt() shl 16 and 0xFF0000) or
        (this[2].toInt() shl 8 and 0xFF00) or
        (this[3].toInt() and 0xFF)
}

fun ByteArray.toUInt32(): Long {

    require(size == INT32_BYTE_SIZE) { "Required $INT32_BYTE_SIZE bytes, but was $size" }

    return this[0].toLong() shl 24 and 0xFF000000L or
        (this[1].toLong() shl 16 and 0xFF0000L) or
        (this[2].toLong() shl 8 and 0xFF00L) or
        (this[3].toLong() and 0xFFL)
}
k
Just wondering why you're doing
this[0].toShort().toInt()
- isn't that the same as
this[0].toInt()
?
Some of these functions can be implemented using
ByteBuffer.getInt()
etc.
s
How?
Oh, yes, after converting the original Java code to Kotlin I did not test it further. But indeed...
toInt16
can also be written like
(this[0].toInt() shl 8 and 0xFF00 or (this[1].toInt() and 0xFF)).toShort()
with the same output.
k
Copy code
fun ByteArray.toInt32() = ByteBuffer.wrap(this).getInt()
s
ByteBuffer
is a JVM class, right? I should have mentioned that I'm on Kotlin/Native for Multiplatform. 🙂
k
No worries. Yes it is a JVM class, so it won't work on Kotlin Native.
e
okio.Buffer has similar functions on multiplatform
s
Thanks for the hint.