[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