I want to read these on a PC, which uses an lsb first storage system.
For Word data I can use Swap(), but not for Integers, Cardinals and
single precision floats that are 32 bit and certainly not for doubles
that are 64 bit size.
So I need a swap32 and a swap64 function or procedure that can handle
values of these sizes. I have googled a few but they are special cases
in that they swap integers OR cardinals OR something else, whereas I
would like to have a general type of function where I can use any
4-byte argument type to swap 32, etc.
Is there any such function available somewhere?
And it does not hurt if it is fast too, because there are many values
to convert.
/BoB
Note there's no guarantee that Integer and Cardinal are 32 bits. On a
64-bit version of Delphi, they'll likely be 64 bits. If you must have a
32-bit type, use LongInt or LongWord.
> So I need a swap32 and a swap64 function or procedure that can handle
> values of these sizes. I have googled a few but they are special cases
> in that they swap integers OR cardinals OR something else, whereas I
> would like to have a general type of function where I can use any
> 4-byte argument type to swap 32, etc.
>
> Is there any such function available somewhere?
> And it does not hurt if it is fast too, because there are many values
> to convert.
To do it type-safely, you need to have separate functions for each type
you want to be able to swap. The function bodies can all be identical to
the one below.
If you don't care about type safety, write a single function that takes
an untyped var parameter:
procedure Swap32(var X);
asm
mov ecx, [eax]
bswap ecx
mov [eax], ecx
end;
Just make sure you never call it on anything that isn't four bytes. The
compiler won't stop you.
--
Rob
Ok, thanks.
What happens if I use the swap32 above with a 64 bit value?
Will half of the variable be swapped only? In that case which end?
/Bo
/BoB
> What happens if I use the swap32 above with a 64 bit value?
> Will half of the variable be swapped only? In that case which end?
Bo,
To help get you educated in the endian area, can you find a local programmer to hire for an hour that knows about bits and bytes?
Rgds, JohnH
Nothing useful. Likewise if you call it on a 16-bit variable.
Like I said, the compiler won't stop you from trying. If you're afraid
you're going to do it accidentally, then do as I suggested and write a
type-specific function for each of the types you want to support. It's
probably a pretty short list, and you can do most of the work copy and
paste. Copy the function above, and simply give X a type. (Then use the
"overload" directive.)
Having a separate function for each type is no slower at run time.
> Will half of the variable be swapped only? In that case which end?
I don't know. You're welcome to try it and find out, though.
--
Rob
> What happens if I use the swap32 above with a 64 bit value?
> Will half of the variable be swapped only? In that case which end?
The 32 bits (4 bytes) that are at the address given. Since Delphi runs
on little endian processors, that means the lower 32 bits.
Untyped var parameters are in fact just untyped references, i.e.
untyped pointers with slightly different semantics.
More here:
http://rvelthuis.de/articles/articles-pointers.html#references
--
Rudy Velthuis [TeamB] http://www.teamb.com
"All things are possible, except skiing through a revolving door."
> Note there's no guarantee that Integer and Cardinal are 32 bits. On a
> 64-bit version of Delphi, they'll likely be 64 bits.
No, they won't. This was confirmed by Allen Bauer in non-tech. Windows
won't generally use 64 bit integers or cardinals either, of course with
the exception of things like memory sizes (size_t), file sizes, etc. In
MS languages, integers (signed or unsigned) will also remain 32 bit.
--
Rudy Velthuis [TeamB] http://www.teamb.com
"The surest way to corrupt a youth is to instruct him to hold in
higher esteem those who think alike than those who think
differently" -- Friedrich Nietzsche
function Swap64(const Value: Int64): Int64;
asm
mov edx,dword ptr [Value]
mov eax,dword ptr [Value+4]
bswap eax
bswap edx
end;