ByteBuffer Little Endian insert not working
Asked Answered
F

2

28

I have to make a two way communication between a legacy system and an android device. The legacy system uses little endian byte ordering. I have successfully implemented the receiving part, however sending not works.

Strange because for me it seems that the ByteBuffer class malfunctions (I can hardly believe that)

    ByteBuffer byteBuffer = ByteBuffer.allocate(4);
    byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
    byteBuffer = ByteBuffer.allocate(4);
    byteBuffer.putInt(88);
    byte[] result = byteBuffer.array();

Results: [0, 0, 0, 88]

    ByteBuffer byteBuffer = ByteBuffer.allocate(4);
    byteBuffer.order(ByteOrder.BIG_ENDIAN);
    byteBuffer = ByteBuffer.allocate(4);
    byteBuffer.putInt(88);
    byte[] result = byteBuffer.array();

Also results the same: [0, 0, 0, 88]

However if I'm not mistaken little endian ordering should return: [88, 0, 0, 0]

So what's the point I'm missing?

Forrestforrester answered 25/11, 2012 at 17:12 Comment(0)
B
40

You are, for some strange reason, reinitializing your byte buffers and throwing away the previous copies where you had changed the endian order. The following code works just fine for me:

ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.BIG_ENDIAN);
byteBuffer.putInt(88);
byte[] result = byteBuffer.array();
System.out.println(Arrays.toString(result));

Prints [0, 0, 0, 88]

ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
byteBuffer.putInt(88);
byte[] result = byteBuffer.array();
System.out.println(Arrays.toString(result));

Prints [88, 0, 0, 0]

Boatswain answered 25/11, 2012 at 17:28 Comment(2)
Maybe the OP has the misconception that ByteBuffer.order makes the change globally, affecting all ByteBuffers?Pironi
I can't believe it, but I did not see it. The second initialization was not intentional. I need to get some sleep. Thanks anyway,Forrestforrester
I
1

On a related note:

This code:

 int unicodePointsLen = textContent.length() * 2;
 ByteBuffer unicodePointsBuffer = ByteBuffer.allocateDirect(unicodePointsLen);
 short unicodePointValue;
 for (int i = 0; i < textContent.length(); i++) 
 {  
     unicodePointValue = (short)textContent.charAt(i);
     unicodePointsBuffer.put((byte)(unicodePointValue & 0x00FF)).put((byte)(unicodePointValue >> 8));
 }

Is about 25% faster than this:

 int unicodePointsLen = textContent.length() * 2;
 ByteBuffer unicodePointsBuffer = ByteBuffer.allocateDirect(unicodePointsLen);
 unicodePointsBuffer.order(ByteOrder.LITTLE_ENDIAN);
 for (int i = 0; i < textContent.length(); i++) 
 {  
     unicodePointsBuffer.putShort((short)textContent.charAt(i));  
 }

Using JDK 1.8.

I am trying to pass unicode points from JAVA to C++ through JNI and the first method is the fastest I found. Curious that it is faster than the second snippet.

Infallible answered 30/12, 2014 at 22:12 Comment(1)
The speedup is not that strange. Internally putShort() might also handle endianness and in the end still push two separate bytes using put(byte).Magdalenmagdalena

© 2022 - 2024 — McMap. All rights reserved.