Search code examples
javanionettyunsigned

How to store unsigned short in java?


So generally I'm using Netty and it's BigEndianHeapChannelBuffer to receive unsinged short (from c++ software) in Java. When I do it like this:

buf.readUnsignedByte(); buf.readUnsignedByte();

it returns: 149 and 00. Till now everything is fine. Because server sent 149 as unsigned short [2 bytes].

Instead of this I would like to receive unsigned short (ofc after restarting my application):

buf.readUnsignedShort();

and magic happens. It returns: 38144.

Next step is to retrieve unsigned byte: short type = buf.readUnsignedByte(); System.out.println(type);

and it returns: 1 which is correct output.

Could anyone help me with this? I looked deeper and this is what netty does with it:

public short readShort() {
    checkReadableBytes(2);
    short v = getShort(readerIndex);
    readerIndex += 2;
    return v;
}

public int readUnsignedShort() {
    return readShort() & 0xFFFF;
}

But still I can't figure what is wrong. I would like just be able to read that 149.


Solution

  • The answer is to change endianness. Thanks to Roger who in comments wrote:

    Not much magic, 149*256+0=38144. You have specified BigEndian so this seems correct, the most significant byte is sent first

    and:

    @mickula The short is two bytes, where one of the bytes is "worth" 256 times as much as the other, Since you use BigEndian the first byte is the one "worth" more. Similar to the decimal number 123 of the digits 1, 2, and 3. The first position is with 10 times the next position which is worth 10 times the next, and so on. So 1 * 100 + 2 * 10 + 3 = 123 when the digits are transferred one at a time. If you see 1, 2, and 3 as little endian you would use 1 + 2 * 10 + 3 * 100 = 321. The 256 is because the size of a byte is 256. –

    Thanks to his comments I just switched endianess in server bootstrap by adding:
    bootstrap.setOption("child.bufferFactory", new HeapChannelBufferFactory(ByteOrder.LITTLE_ENDIAN));