Hi,
Can anyone let me have a snippet of (or pointers to) code that generates GUI.
I mean the whole code for CreateGUI() --one that does not use OS's GUID stuff.
Cheers,
Ray

Mailing lists / fpc-pascal / 2005-05
14 messages · 5 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Hi,
Can anyone let me have a snippet of (or pointers to) code that generates GUI.
I mean the whole code for CreateGUI() --one that does not use OS's GUID stuff.
Cheers,
Ray
Sorry for the typos. Here is a more correct form :-)
Can anyone let me have a snippet of (or pointers to) code that generates GUIDs.
I mean the whole code for CreateGUID() --one that does not use OS's GUID stuff.
Cheers,
Ray
See Subversion, SysUtils unit, more specific uuid.pp in the rtl/unix dir.
Michael.
Michael Van Canneyt wrote:
Hi Michael,
Thank you for the pointer.
Without creating incompatibility to the existing code (that of Deplphi and Kylix included), might I suggest a little extension to CreateGUID().
The reason I would like this is, there are timesone would want to create GUIDs based on self supplied MAC numbers.
Here is a template of what I propose. If no one objects to the idea, I can submit real code later.
---BEGIN PSEUDO CODE---
{These should be in Interface section of sysutils unit}
Type
TMACNumber = Array [0..5] Of Byte;
TUUIDCreationKind = (ucKernel, ucNIC, ucPseudoMAC);{I could not find where PreferKernelUUID was defined, but, with these changes we will not need it anymore}
Const
NullMAC: TMacArray = [0,0,0,0,0,0];
TUUIDCreationKind = (ucKernel, ucNIC, ucPseudoMAC);{This should be in the Implemantation section}
Function CreateGUID(
out GUID : TGUID;
const UUIDCreationKind: TUUIDCreationKind = ucKernel;
const MACNumber: TMACNumber = NullMAC
) : Integer;
begin
case UUIDCreationKind of
ucKernel: begin
if not CreateKernelGUID(Guid) then
if not CreateMACGuid(Guid) then
GetRandomBytes(GUID,SizeOf(Guid));
end;
end;
ucNIC: begin
if not CreateMACGuid(Guid) then
if not CreateKernelGUID(Guid) then
GetRandomBytes(GUID,SizeOf(Guid));
end;
ucPseudoMAC: begin
{Here comes code that uses MACNumber}
end;
end;
Result:=0;
end;
---END PSEUDO CODE---Cheers,
Adem
Well, the implementation as it is now for Unix turns out to be very Linux specific. Therefore, the system will be done slightly different.
An
OnCreateGUID : TCreateGUIDFunc = Nil;event will be made. if it is set, it will be used instead of the default implementation (which will still be system specific). You can then set this handler to supply your own GUID generation routine. I will supply some example code for Linux, one with the uuid C library, one with the implementation I made earlier (it will be in the packages).
I am working on this now, you can expect it in SubVersion tonight.
Michael.
It's in SubVersion.
2 demo units are in packages/extra/uuid, with testprograms.
Michael.
Michael Van Canneyt wroteIt'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.
A couple of questions, wrt FPC v2.x:
-- Is Int64 supported in all platforms?
-- Is there a Int128 or something like it?
When Windows was 32bit, Delphi had Int64; it's only natural that now we should have Int128 :-)
-- GUID unit being in extra/uuid/, does it mean it will not be available in, say, Windows since Windows has a native call for that.
Personally, I'd like 'OnCreateGUID : TCreateGUIDFunc = Nil;
to be available in all platforms.Cheers,
Basri
Yes.
-- Is there a Int128 or something like it? When Windows was 32bit, Delphi had Int64; it's only natural that now we should have Int128 :-)
Well, has it's purposes for e.g. file size. But tell me applications where you need an Int128?
I can not come up with a compelling arguement right now, much like I could not come up with one, say, 20 years ago.
Except that, it seems customary to have a data type double the available CPU/OS max bit size.
Ah, here is one: what happens if I wanted to multiply 2 Int64 numbers?
I don't know why I would need to do it right now, though :-)
http://svn.freepascal.org/svn/fpc/trunk/packages/extra/uuid/ It looks OK to me, except…
Feel free to submit patches and a testprogram to prove that your implementation is significantly faster :-)
A couple of questions, wrt FPC v2.x: -- Is Int64 supported in all platforms?
Yes.
-- Is there a Int128 or something like it?
No.
It is, sysutils is cross-platform.
On windows the default implementation calls CoCreateGUID, but with OnCreateGUID you can override this behaviour.
On Linux, the default behaviour is to use the kernel /proc/sys/kernel/random/uuid file, and fall back.
On BSD, /dev/urandom is used to generate a random GUID
on all other platforms, the system unit random() function is used.
On all platforms, the default behaviour can be changed using the OnCreateGUID event.
Michael.
On BSD, /dev/urandom is used to generate a random GUID
No, that was my first hunch, but it turned out to be a single kernel call. (FreeBSD 5.x+)
on all other platforms, the system unit random() function is used.
This is FreeBSD4 inclusive.
Feel free to submit patches and a testprogram to prove that your implementation is…
:-)
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
Thank you for the pointer. Without creating incompatibility to the existing code (that of…
The reason I would like this is, there are timesone would want to create GUIDs based on self supplied MAC numbers.
Except, this is not how GUID's are generated under Windows anymore. Microsoft bowed to preassure and now use a completely random key generation technique. This was because a reaction to the paranoid people shouting that Microsoft were attempting to track them via their MAC address. Okay, MAC address is by no means unique, but it does single out a very small subsection of users to be pinpointed by MAC address. Basing any GUID code on MAC address manipulation to gain pseudo random numbers is therefor on shaky ground.
Matt
Ah, but you seemed to have missed the gist of my request:
I am aware of Microsoft's plight, and, their problem was due to having embedded the GUID in to, say, MS Word Docs etc. Not a wise move wrt privacy, but completely understandable from POV of police etc.
Frankly, I still think the privacy issue is there; the GUID stuff generated during the MS Office install is stored persistently and every doc you create is watermarked with it. The only way to get rid of it is either by stripping the *.doc file of the GUID, or by reinstalling the OS.
Anyway, back to the topic:
First, we all know that you can alter the MAC address reported to/by the OS, don't we? So, it never was too reliable in the first place.
The reason why one might "want to create GUIDs based on self supplied MAC numbers" is not for those semi-blackhat cases, we may need that in order to be able to generate truely unique (or, as unique as we can) GUIDs and do it faster (i.e. lower overhead) than polling a random number generator or the OS for the MAC address.
This sort of thing is neded for generating prime keys for disconnected database operation. As long as the *client* *count* for the database does not exceed 281,474,976,710,655 (max value you can store in a 6-byte number, i.e. MAC number) we are assured of uniqueness :-)
Cheers,