joesan
joesan

Reputation: 15345

Representing Int32 as 4 Bytes in Scala

I'm in the process of doing a binary protocol parsing where I'm trying to read a String from the Array of bytes. In this array of bytes, the first 4 bytes represent the length of the String. The length of String is represented as Int32. For example., here is the Byte array:

val arr = "45 0 0 0 65 59 78 76 89 89 78 67 56 67 78 89 98 56 67 78 89 90 98 56 67 78 89 90 56 67 78 89 90 56 67 78 89 90 56 67 78 89 90 56 67 78 89 56 67"

It can be seen from the array above that the first 4 bytes 45 0 0 0 represent the size of the following String which in this case is 45 bytes long.

I understand that Int32 needs 4 bytes to be represented on the JVM. But I don't understand how I can parse the first 4 bytes and infer that the size of the following String is going to be 45 in the example above!

So what I need basically is something that can convert the Array 45 0 0 0 to just 45! Am I talking sense? Any suggestions please?

res60: Array[Byte] = Array(45, 0, 0, 0)

scala> ByteBuffer.wrap(res60).getInt()
res61: Int = 754974720

res61 is not something that I'm expecting!

Upvotes: 1

Views: 1100

Answers (2)

Jorn Vernee
Jorn Vernee

Reputation: 33845

ByteBuffer has big endian byte order by default, but your int uses little endian byte order. You have to explicitly convert the ByteBuffer to be little endian e.g.:

byte[] input = { 45, 0,  0,  0 };
ByteBuffer bb = ByteBuffer.wrap(input).order(ByteOrder.LITTLE_ENDIAN); // <---    
int length = bb.getInt();
System.out.println(length); // 45

Upvotes: 7

Andreas
Andreas

Reputation: 159086

You can do it like this (Java):

String input = "45 0 0 0 65 59 78 76 89 89 78 67 56 67 78 89 98 56 67 78 89 90 98 56 67 78 89 90 56 67 78 89 90 56 67 78 89 90 56 67 78 89 90 56 67 78 89 56 67";

String[] arr = input.split(" ");
int i = 0;
int len = Integer.parseInt(arr[i++]) +
          256 * (Integer.parseInt(arr[i++]) +
                 256 * (Integer.parseInt(arr[i++]) +
                        256 * Integer.parseInt(arr[i++])));
char[] buf = new char[len];
for (int j = 0; j < len; j++)
    buf[j] = (char) Integer.parseInt(arr[i++]);
String result = new String(buf);

System.out.println(result);

Output

A;NLYYNC8CNYb8CNYZb8CNYZ8CNYZ8CNYZ8CNYZ8CNY8C

Upvotes: 1

Related Questions