I'm trying to port some C code to Java, however I've been struggling to figure out what these lines of code do.
Note: rawEntry
is of type char*
and appears to be a 12 bytes long allocated as such
char *rawEntry = (char*)malloc(0x000c);
unsigned long *l;
unsigned long offset;
// ...
l = (unsigned long*) rawEntry + 1;
offset = ntohl(*l);
As far as I can tell, it takes the first four items of the array, and puts them together to form a long, however my attempts in java have been less than successful.
offset = (rawEntry[0] << 24) +
(rawEntry[1] << 16) +
(rawEntry[2] << 8) +
(rawEntry[3]) +
1;
When presented with the following array,
1 0 0 0 0 0 0 0 0 0 11 -38
The C code outputs 3034 as the offset
My Java code outputs 16777217, or 1 if I flip the endian
This expression
l = (unsigned long*) rawEntry + 1;
casts rawEntry
to pointer to a type that has size of 8 bytes on your system. After that, adding 1
means adding 8 bytes, so the actual conversion looks like this:
offset = (Byte.toUnsignedInt(rawEntry[ 8]) << 24) +
(Byte.toUnsignedInt(rawEntry[ 9]) << 16) +
(Byte.toUnsignedInt(rawEntry[10]) << 8) +
(Byte.toUnsignedInt(rawEntry[11]) << 0);
The following four bytes are interpreted as 3034
:
0 0 11 -38
You should be able to simplify this further by using ByteBuffer
:
int offset = ByteBuffer.wrap(rawEntry, 8, 4).getInt();
Before going further it is important to note that this code depends on the actual magnitude of a long
on your platform. On 64 bits platforms longs are 64 bits, that is a long
takes up 8 bytes. On the other hand ntohl
converts a “network long” that is 32 bits long (4 bytes).
Assuming rawEntry
is {1,0,0,0,0,0,0,0,0,0,0xB,0xDA,…}
(0xB is the base 16 equivalent of 11, 0xDA is the base 16 (hexadecimal) unsigned
value that corresponds to -38)
l = (unsigned long*) rawEntry + 1;
really means that l
refers to the second unsigned long
. That is skip the first 8 bytes from rawEntry
and l
then points to the {0,0,0xB,0xDA,…}
part. Now *l
is the unsigned long
represented by the {0,0,0xB,0xDA,…}
bytes sequence and it is dependent on your architecture. If you are on a little endian machine that will be 0x…DA0B0000 (ellipsis because the end of the array is unkown, that is undefined behaviour). And now ntohl
will just keep the last 32 bits and invert the bytes order resulting in 0x00000BDA or 3034 in base 10.
The easy way to write this in Java would be
offset = (rawEntry[8] << 24) +
(rawEntry[9] << 16) +
(rawEntry[10] << 8) +
(rawEntry[11]);
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