https://kotlinlang.org logo
Title
m

martmists

05/23/2023, 9:09 PM
How do I read binary data in multiplatform code? On java I have ByteBuffer, but on multiplatform I have to roll my own solution. However, the following code doesn't work but I can't quite figure out why:
fun ByteArray.readInt(offset: Int, endianness: Endianness = Endianness.LITTLE): Int {
    return when (endianness) {
        Endianness.BIG -> {
            ((this[offset].toInt() shl 24) or
                    (this[offset + 1].toInt() shl 16) or
                    (this[offset + 2].toInt() shl 8) or
                    (this[offset + 3].toInt() shl 0))
        }
        Endianness.LITTLE -> {
            ((this[offset].toInt() shl 0) or
                    (this[offset + 1].toInt() shl 8) or
                    (this[offset + 2].toInt() shl 16) or
                    (this[offset + 3].toInt() shl 24))
        }
    }.also {
        println("Read int $it from bytes ${this[offset]}, ${this[offset + 1]}, ${this[offset + 2]} and ${this[offset + 3]}")
    }
}
as it outputs
Read int -38 from bytes -38, 12, 0 and 0
but it should output
Read int 3290 from bytes -38, 12, 0 and 0
where the input data is
[0xDA, 0x0C, 0x00, 0x00]
read from a file using JVM
File().readBytes()
j

Joel Denke

05/24/2023, 5:23 AM
Not sure if helps in all cases but Okio is multiplatform, https://square.github.io/okio/multiplatform/
j

Jiri Bruchanov

05/24/2023, 6:33 AM
have a look this lib, it might help https://github.com/DitchOoM/buffer
m

Michael Paus

05/24/2023, 8:16 AM
You have forgotten to mask your data in the byte to int conversion. This is a fragment of my own code for something similar which works:
tgtImage[refIndex] = (
        ((0xFF and tgtA) shl 24) or
        ((0xFF and tgtR) shl 16) or
        ((0xFF and tgtG) shl  8) or
        ((0xFF and tgtB) shl  0)
    )