[Delphi] Typecasten naar byte of word

Pagina: 1
Acties:

  • Cheater
  • Registratie: Januari 2001
  • Laatst online: 20-08 20:59
Betreft: Delphi 7 / win2000prof
Ik wil een rechtensysteem opzetten dmv byte.
Dus elke optie die (aan of uit kan staan) heeft een word waarde

voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const
  may_login = $00000001;   // 1
  may_logout = $00000010;  // 2

function controlleer_permissions(item:integer):boolean;
var 
  ups:byte;
begin
  ups := byte(3);  // $00000011; { in plaats van de 3 komt 
                                   de gebruiker z'n security level 
                                   te staan. }
  case item of
    1: if (ups and may_login) = may_login then result := true;
    2: if (ups and may_logout) = may_logout then result := true;
    3: // andere dingen die gecontrolleerd moeten worden.
  end;
end;


Door dan een functie aan te roepen controlleer_permissions(1) kan ik dus controlleren of die gebruiker iets mag aan de hand van het item-nummer.

Ik krijg alleen dat typecasten niet goed, mag het zo? moet het zo? als ik debug, komt er in ups gewoon '3' te staan als integer...

In het voorbeeld geeft hij alleen bij case: 1 , een true waarde terug maar bij de andere 2 niet (3 is niet ingevuld, het is maar een voorbeeld)...

Nadere uitleg gewenst...

[ Voor 14% gewijzigd door Cheater op 21-10-2003 16:06 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Ik ken geen Delphi, maar weet je zeker dat je met die $-notatie wel het binaire getallenstelsel gebruikt? Met andere woorden, als je may_login en may_logout print, zijn ze dan wel 2 en 3? (Ken er anders voor de zekerheid direct 2 en 3 aan toe).

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18-08 21:00

Creepy

Tactical Espionage Splatterer

Eeh.. wat verwacht je te zien als je 3 in een byte stopt? Dat je in je debugger 3 zit klopt prima.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Cheater
  • Registratie: Januari 2001
  • Laatst online: 20-08 20:59
Nee ik weet dat niet zeker Soultaker, Ik had uit een windows-versie-controle dit eruit gehaald...

Wat is de notatie voor een byte of een word of een dword dan? gewoon ruwweg de getalletjes?

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 26-06 10:37

OZ-Gump

terug van weggeweest

De JEDI componenten die ik geïnstalleerd heb staan hiero geven me de functie OrdToByte. Deze zou, als je jouw variabele ups daarin gooit, een binaire weergave hiervan fabrieken.

Uit de help:
OrdToBinary returns a string representation of the specified value in its binary form. That is, a string of '1' and '0' characters representing the bits in the supplied value. The resulting string length is always equal to the number of bits in the supplied value (leading 0's aren't stripped).
Misschien JEDI installen dus een optie...? Of zelf eentje in elkaar knutselen natuurlijk, dat is helemaal niet moeilijk. ;)

My personal website


Verwijderd

ff uit het hoofd, ik neem aan dat je wilt "enumeren" omdat je klaagt over die 3 in de debugger.


Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
type 
   TRight = (mayLogin, mayLogout);
   TRights = set of TRight;

function controlleer_permissions(item:integer):boolean;
var 
  ups:TRights;
begin
   // Initieele waarde
  Result := false;

  // moet uit DB gehaald gaan worden
    ups := [mayLogin, mayLogout];

  // evalueer 
  case item of
    1:  IF mayLogin IN ups    then  result := true;
    2:  IF mayLogout IN ups  then result := true;
    3: // andere dingen die gecontrolleerd moeten worden.
  end;
end;

[ Voor 26% gewijzigd door Verwijderd op 21-10-2003 16:46 ]


  • Cheater
  • Registratie: Januari 2001
  • Laatst online: 20-08 20:59
nou dat loopt uit de hand bij de laatste, het kan zijn dat er wel 50 opties aan of uit moeten komen te staan...

Ik zie dat met een $ teken een hexidecimale waarde betekent. Ik wil nu eigenlijk dus gewoon 00000011 zien in een variable in de debugger, maar ik krijg gewoon 3. Nu weet ik wel dat die byte waarde 11, 3 representeerd, maar toch... de debugger hoort dat niet uit zichzelf om te zetten voor mij...

Verwijderd

Ik geloof niet dat Delphi binaire weergave ondersteund zoals jij dat wilt. Byte is gewoon een integer type wat niks speciaals heeft met binaire weergave. En jouw $0000011 is dus ook geen 3, houdt daar even rekening mee.

[ Voor 56% gewijzigd door Verwijderd op 21-10-2003 16:53 ]


  • Cheater
  • Registratie: Januari 2001
  • Laatst online: 20-08 20:59
ok klopt ;) die $00000011 is een hexadecimaal getal , en representeerd: 17
Dus ik moet gewoon de getallen 1 / 2 / 4 / 8 / 16 / 32 / 64 / 128 toekennen aan de MAY_LOGIN en MAY_LOGIN... ?

Verwijderd

Cheater schreef op 21 October 2003 @ 16:59:
ok klopt ;) die $00000011 is een hexadecimaal getal , en representeerd: 17
Dus ik moet gewoon de getallen 1 / 2 / 4 / 8 / 16 / 32 / 64 / 128 toekennen aan de MAY_LOGIN en MAY_LOGIN... ?
yep, als ik jouw was zou ik toch maar nadenken over mijn voorbeeldje biedt veel voordelen, is overzichtelijker voor later.

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

maui71, dat case-statementje is dan weer niet zo netjes, kun je beter een TRight direct aan de functie meegeven en controleren of die in de set voorkomt.

Bovendien zijn sets (mits 32 of minder onderdelen) prima te converteren van/naar een 32-bits integer. Anders wordt het 64-bits integer en niet iedere DBMS ondersteunt dat.

@TS: Controleren is met één L, dat doe je overal dus fout ;)

日本!🎌


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Delphi (eigenlijk Object Pascal) heeft taalelementen die precies bedoeld zijn voor wat jij nodig hebt: enumerated types en sets. Deze bieden het voordeel dat je met duidelijke namen kunt werken en dat de compiler veel duidelijker kan aangeven wat je fout doet (typt). Achter de schermen zijn enumerated types en sets gewoon bitmasks, alleen zie je dat niet.

Even de originele code herschrijven:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
type
  TPermission = (peMayLogin, peMayLogout, peSomethingElse);
  TPermissions = set of TPermission;

function UserHasSomePermissions(PermissionsToVerify: TPermissions): Boolean;
var
  UserPermissions: TPermissions;
begin
  UserPermissions := [peMayLogin, peSomethingElse]; // afhankelijk van de user

  // controleren of user TENMINSTE 1 te controleren permissie heeft:
  Result := ((PermissionsToVerify * UserPermissions) <> []);
end;

function UserHasAllPermissions(PermissionsToVerify: TPermissions): Boolean;
var
  UserPermissions: TPermissions;
begin
  UserPermissions := [peMayLogin, peSomethingElse]; // afhankelijk van de user

  // controleren of user ALLE te controleren permissies heeft:
  Result := ((PermissionsToVerify * UserPermissions) = PermissionsToVerify);
end;

{ Testje: }
procedure TForm1.Button1Click(Sender: TObject);
begin
 if UserHasSomePermissions([peMayLogin, peMayLogout]) then
   ShowMessage('Gebruiker heeft tenminste 1 van de gecontroleerde permissies');
 if UserHasAllPermissions([peMayLogin, peMayLogout]) then
   ShowMessage('Gebruiker heeft alle gecontroleerde permissies');
end;
Een hint bij deze code: met * bepaal je de doorsnede van twee sets. (De doorsnede van [A, B, C, D] en [A, C, F, H] is [A, C].)

Zoek in de helpfiles maar eens naar de onderwerpen 'Enumerated types', 'Sets (set types)', 'Set constructors' en 'Set operators'.

Een goede grap mag vrienden kosten.


Verwijderd

_Thanatos_ schreef op 22 October 2003 @ 00:48:
maui71, dat case-statementje is dan weer niet zo netjes, kun je beter een TRight direct aan de functie meegeven en controleren of die in de set voorkomt.
jaja :) was ff snel uit het hoofd ....

Ik ben trouwens niet zo'n voorstander van een rechtensysteem gebaseerd op deze methoden. Ik zie liever een rechtensysteem op basis van "tokens", zie o.a. dit draadje : [rml][ DB-Design] User Rights System[/rml]

[ Voor 11% gewijzigd door Verwijderd op 22-10-2003 08:15 ]


Verwijderd

En als je ondanks de goede voorbeelden over enums en sets toch zelf het wiel wil gaan uitvinden:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const
  PERMISSION_LOGIN   = $01;
  PERMISSION_LOGOUT  = $02;
  PERMISSION_READ    = $04;
  PERMISSION_WRITE   = $08;
  PERMISSION_DELETE  = $10;
  PERMISSION_CREATE  = $20;
  PERMISSION_EXECUTE = $40;

function DoesUserHavePermissions(const UserPermissions: DWORD; const CheckPermissions: DWORD): Boolean
begin
  Result:=(UserPermissions and CheckPermissions)=CheckPermissions;
end;

procedure GrantUser(const Permissions: DWORD; var UserPermissions: DWORD)
begin
  UserPermissions:=UserPermissions or Permissions;
end;

procedure Initialize
var
  UP: DWORD;
begin
  UP:=0;
  GrantUser(PERMISSION_LOGIN or PERMISSION_LOGOUT or PERMISSION_READ or PERMISSION_EXECUTE, UP);
  if DoesUserHavePermissions(UP, PERMISSION_WRITE or PERMISSION_CREATE) then
    ShowMessage('Deze boodschap hoort niet getoond te worden')
  else
    ShowMessage('De gebruiker heeft geen ''write'' en/of ''create'' rechten');
end;

Let er wel op dat enums en sets heel slim door de compiler worden geoptimaliseerd naar gelang het aantal items wat je gebruikt. Bovendien heb je met bovenstaande methode 'slechts' de beschikking over maximaal 64 items (64-bits integer) of je zult zelf allerlei vreemde dingen moeten uitvoeren. De sets die door Delphi worden ondersteund gaan verder dan 64-bits, als ik het me goed kan herinneren tot 256-bits (256 items) maar dit laatste kan ik fout hebben.

Verwijderd

Verwijderd schreef op 22 October 2003 @ 10:11:
Let er wel op dat enums en sets heel slim door de compiler worden geoptimaliseerd naar gelang het aantal items wat je gebruikt. Bovendien heb je met bovenstaande methode 'slechts' de beschikking over maximaal 64 items (64-bits integer) of je zult zelf allerlei vreemde dingen moeten uitvoeren. De sets die door Delphi worden ondersteund gaan verder dan 64-bits, als ik het me goed kan herinneren tot 256-bits (256 items) maar dit laatste kan ik fout hebben.
Uit de help:
the base type can have no more than 256 possible values, and their ordinalities must fall between 0 and 255
256 elementen/items dus

[ Voor 5% gewijzigd door Verwijderd op 22-10-2003 15:03 ]

Pagina: 1