Reputation: 731
I want to know how to convert big-endian numbers to native numbers in Delphi. I am porting some C++ code in that I came across:
unsigned long blockLength = *blockLengthPtr++ << 24;
blockLength |= *blockLengthPtr++ << 16;
blockLength |= *blockLengthPtr++ << 8;
blockLength |= *blockLengthPtr;
unsigned long dataLength = *dataLengthPtr++ << 24;
dataLength |= *dataLengthPtr++ << 16;
dataLength |= *dataLengthPtr++ << 8;
dataLength |= *dataLengthPtr;
I am not familiar with C++, so I don't understand what those operators do.
Upvotes: 7
Views: 8982
Reputation: 84550
Andreas's answer is a pretty good example of how to do it in pure pascal, but it still looks kinda awkward, just like the C++ code. This can actually be done in a single assembly instruction, though which one depends on whether you're using 32-bit or 16-bit integers:
function SwapEndian32(Value: integer): integer; register;
asm
bswap eax
end;
function SwapEndian16(Value: smallint): smallint; register;
asm
rol ax, 8
end;
Upvotes: 23
Reputation: 108963
To reverse the order of the bits:
procedure SwapEndiannessOfBits(var Value: cardinal);
var
tmp: cardinal;
i: Integer;
begin
tmp := 0;
for i := 0 to 8*sizeof(Value) - 1 do
inc(tmp, ((Value shr i) and $1) shl (8*sizeof(Value) - i - 1));
Value := tmp;
end;
To reverse the order of the bytes:
procedure SwapEndiannessOfBytes(var Value: cardinal);
var
tmp: cardinal;
i: Integer;
begin
tmp := 0;
for i := 0 to sizeof(Value) - 1 do
inc(tmp, ((Value shr (8*i)) and $FF) shl (8*(sizeof(Value) - i - 1)));
Value := tmp;
end;
I think the last one is what you are looking for. Most likely there are faster and more elegant solutions, though.
Disclaimer: I might be totally wrong. I feel a bit confused at the moment. Hopefully someone else will see this question and provide a more definite answer!
Upvotes: 4