[fpc-pascal] CreateGUID() [was Re: GUID code]
listmember
listmember at letterboxes.org
Sat May 21 23:12:07 CEST 2005
Michael Van Canneyt wrote:
>
> On Sat, 21 May 2005, listmember wrote:
>
>>Michael Van Canneyt wrote:
>>
>>>It's in SubVersion. 2 demo units are in packages/extra/uuid, with
>>>testprograms.
>>
>>http://svn.freepascal.org/svn/fpc/trunk/packages/extra/uuid/
>>
>>It looks OK to me, except that it may be a little more optimized
>>for speed since GUIDs are CPU-expensive to begin with.
>
> Feel free to submit patches and a testprogram to prove that your
> implementation is significantly faster :-)
:-)
I did not mean it to be condescending; but it probably came out
that way. I apologize if it did sound like that.
So, let me start afresh.
I am wet behind-the-ears when it comes to Free Pascal, I don't
even know wehere, say, TGUID is declared in FPC (yet).
But, I am not that new to Pascal/Delphi, and I have used
them to write engine stuff mainly, in the past.
I have found that it can be easier, faster and more convenient
to use variant records to do some 'sub-atomic' operations.
So, in unit uuid, I'd use one of these variant record types in
a couple of routines, say, Procedure UUIDPack() instead of SHR
ops.
And in Function GetMacAddr() instead of
P:=Pchar(@ifr.ifru_hwaddr.sa_data);
Result:=(p[0]<>#0) or (p[1]<>#0) or (p[2]<>#0)
or (p[3]<>#0) or (p[4]<>#0) or (p[5]<>#0);
we'd have
Move(ifr.ifru_hwaddr.sa_data, P.Bytes[0], SizeOf(TInt128Splitter));
Result:= (p.Int640 <> 0) Or (p.Int641 <> 0);
where
p: TInt128Splitter;
etc.
You might or might not agree with the above, so independent
of all that, here is some more blurb promoting it :-)
These variant arrays are, IMHO, more pascal-like than
bitwise operations for general users, more convenient
(yu get to pick and choose the kind of value you want),
and faster sometimes (instead of many SGR/SHL ops), plus
they can be useful to convert between little-endian and
big-endian numbers etc.
Here below is what they look like, I wonder if you'd
consider them.
TWordSplitter = Packed Record
Case Split: Byte Of
0: Self: Word;
1: (
Byte0 : Byte;
Byte1 : Byte;
);
2: (
Bytes : Packed Array [0..1] Of Byte;
);
End;
TIntegerSplitter = Packed Record
Case Split: Byte Of
0: Self: Integer;
1: (
Byte0 : Byte;
Byte1 : Byte;
Byte2 : Byte;
Byte3 : Byte;
);
2: (
Word0 : Word;
Word1 : Word;
);
3: (
Bytes : Packed Array [0..3] Of Byte;
);
4: (
Words : Packed Array [0..1] Of Word;
);
End;
TInt64Splitter = Packed Record
Case Split: Byte Of
0: Self: Int64;
1: (
Byte0 : Byte;
Byte1 : Byte;
Byte2 : Byte;
Byte3 : Byte;
Byte4 : Byte;
Byte5 : Byte;
Byte6 : Byte;
Byte7 : Byte;
);
2: (
Word0 : Word;
Word1 : Word;
Word2 : Word;
Word3 : Word;
);
3: (
Integer0 : Integer;
Integer1 : Integer;
);
4: (
Bytes : Packed Array [0..7] Of Byte;
);
5: (
Words : Packed Array [0..3] Of Word;
);
6: (
Integers : Packed Array [0..1] Of Integers;
);
End;
{This would be useful for 128-bit stuf, like GUIDs :-) }
TInt128Splitter = Packed Record
Case Split: Byte Of
// 0: Self: Int128; //This does not exist
0: (
Byte0 : Byte;
Byte1 : Byte;
Byte2 : Byte;
Byte3 : Byte;
Byte4 : Byte;
Byte5 : Byte;
Byte6 : Byte;
Byte7 : Byte;
Byte8 : Byte;
Byte9 : Byte;
Byte10 : Byte;
Byte11 : Byte;
Byte12 : Byte;
Byte13 : Byte;
Byte14 : Byte;
Byte15 : Byte;
);
1: (
Word0 : Word;
Word1 : Word;
Word2 : Word;
Word3 : Word;
Word4 : Word;
Word5 : Word;
Word6 : Word;
Word7 : Word;
);
2: (
Integer0 : Integer;
Integer1 : Integer;
Integer2 : Integer;
Integer3 : Integer;
);
3: (
Int640 : Int64;
Int641 : Int64;
);
4: (
Bytes : Packed Array [0..15] Of Byte;
);
5: (
Words : Packed Array [0..7] Of Word;
);
6: (
Integers : Packed Array [0..3] Of Integers;
);
7: (
Int64s : Packed Array [0..1] Of Int64;
);
End;
Similar stuff can be made for single, double etc. just to
work on their byte content (not much more useful than that).
> On all platforms, the default behaviour can be changed using
> the OnCreateGUID event.
This is excellent. Thank you.
Cheers,
Basri
More information about the fpc-pascal
mailing list