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?
By default, the order of a ByteBuffer object is BIG_ENDIAN. If a byte order is passed as a parameter to the order method, it modifies the byte order of the buffer and returns the buffer itself. The new byte order may be either LITTLE_ENDIAN or BIG_ENDIAN.
ByteBuffer holds a sequence of integer values to be used in an I/O operation. The ByteBuffer class provides the following four categories of operations upon long buffers: Absolute and relative get method that read single bytes. Absolute and relative put methods that write single bytes.
After you've written to the ByteBuffer, the number of bytes you've written can be found with the position() method. If you then flip() the buffer, the number of bytes in the buffer can be found with the limit() or remaining() methods.
A byte order is called little endian if the bytes of a multi-byte value are stored from the least significant byte to the most significant byte. Little endian means least significant first. In the little endian byte order, you would store 300 as 0010110000000001, which seems backwards for representing a 16-bit value.
By default, the byte order of the ByteBuffer class is always ByteOrder.BIG_ENDIAN. And, we can use the order () and order (ByteOrder) methods to respectively get and set the current byte order. The byte order influences how to interpret the underlying data. For example, suppose we have a buffer instance:
The ByteBuffer is an abstract class, so we can't construct a new instance directly. However, it provides static factory methods to facilitate instance creation. Briefly, there are two ways to create a ByteBuffer instance, either by allocation or wrapping: 2.1. Allocation
To be precise, the hasArray () method can tell us if a buffer has an accessible backing array or not. If the hasArray () method returns true, then we can use the array () and arrayOffset () methods to get more relevant information. 7.3. Byte Order By default, the byte order of the ByteBuffer class is always ByteOrder.BIG_ENDIAN.
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]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With