Autor Téma: Kódy chýb - zistiť masku a skupinu  (Přečteno 1245 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Kódy chýb - zistiť masku a skupinu
« kdy: 09-07-2019, 14:54:16 »

Mám, okrem ďalších, definované
Kód: Delphi [Vybrat]
  1. EDB_0Mask = $10000000 // Mask
  2. EDB_Table =    $1000000  // Group
  3. EDB_Table_Delete = EDB_0Mask or EDB_Table or $0002;
Teraz potrebujem zistiť z kódu chyby Mask a Group. Neviem prísť nato ako sa to robí.

Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2586
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #1 kdy: 09-07-2019, 16:37:33 »

Mám, okrem ďalších, definované
Kód: Delphi [Vybrat]
  1. EDB_0Mask = $10000000 // Mask
  2. EDB_Table =    $1000000  // Group
  3. EDB_Table_Delete = EDB_0Mask or EDB_Table or $0002;
Teraz potrebujem zistiť z kódu chyby Mask a Group. Neviem prísť nato ako sa to robí.
Ja tomu tvemu zapisu nejake nerozumim: maskou se oznacuje skupina '1', ktera definuje skupinu bitu, ktera me zajima a maskuje vsechny ostatni nezajimave bity, takze priklad:
Kód: Delphi [Vybrat]
  1. EGroupMembers = (Table=1, x=2, y=3, z=4);
  2. EDB_Table = ord(EGroupMembers.Table) shl 8;
  3. EDB_x      = ord(EGroupMembers.x) shl 8;
  4. EDB_y      = ord(EGroupMembers.y) shl 8;
  5. EDB_z      = ord(EGroupMembers.z) shl 8;
  6.  
  7. EDB_GroupMask = $7 shl 8;
  8. EDB_CodeMask = $FF;
  9.  
  10. Group := EGroupMembers((ErrCode  and EDB_GroupMask) shr 8);
  11. Code := ErrCode and EDB_CodeMask;
  12.  
  13.  


Offline miroB

  • Guru
  • *****
  • Příspěvků: 516
  • Karma: 17
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #2 kdy: 09-07-2019, 19:14:09 »

Mám, okrem ďalších, definované
Kód: Delphi [Vybrat]
  1. EDB_0Mask = $10000000 // Mask
  2. EDB_Table =    $1000000  // Group
  3. EDB_Table_Delete = EDB_0Mask or EDB_Table or $0002;
Teraz potrebujem zistiť z kódu chyby Mask a Group. Neviem prísť nato ako sa to robí.
Ja pracujem s Enumerations a Enumeration Set:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Simple_Types_(Delphi)#Enumerated_Types
Myslím že to je plné náhrada za Mask & spol.
Čitateľné a pre laika veľmi zrozumiteľné.
Nezabudnúť na operátory pre Enum-Sets:  +, -, *
Interne mi to nahrádza "celú problematiku s maskovaním".
Navyše, každý Enum, ale aj Enum-Set sa dá previesť na číslo, alebo naopak.
Takže je možné ich ukladanie do "settings"/"ini" súborov.
Jediný krát, keď Enum-Set neviem použiť priamo, ale musím si ho premeniť na konštantu, je v prípade
"Case .. of"
Aj keď Enum-Set je konštanta (číslo), nedá sa u "Case .. of" využiť. Vtedy si "niekde vedľa" prevediem set [abc, bcd] na číselnú konštantu, do poznámky si dám aký to je set a ide aj to..
A to nevravím o RTTI, kde sa dá enum previesť aj na text.
« Poslední změna: 09-07-2019, 19:21:44 od miroB »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2586
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #3 kdy: 09-07-2019, 19:34:17 »
Myslím že to je plné náhrada za Mask & spol.
Čitateľné a pre laika veľmi zrozumiteľné.
Plna nahrada to neni, protoze to lze pouzit jen na 1 hodnotu v promenne, zatimco na binarni urovni lze do hodnoty zakodovat nekolik enumu a pomoci masek je izolovat. Delphi jako jazyk nema zadnou strukturu pro praci s bity jako struc  v C-like jazykach - tam to nepotrebujes maskovat a primo se odkazujes na cleny o velikosti nekolika bitu.

Citace
A to nevravím o RTTI, kde sa dá enum previesť aj na text.
To funguje jen u implicitne cislovanych members, pro explicitni hodnoty clenu introspekce v Delphi nefunguje.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #4 kdy: 09-07-2019, 19:42:19 »

Citace
Ja tomu tvemu zapisu nejake nerozumim: maskou se oznacuje skupina '1', ktera definuje skupinu bitu, ktera me zajima a maskuje vsechny ostatni nezajimave bity, takze priklad
Je to presne podľa tvojho príkladu pre vytvorenie číselníka chýb. V komentári za hodnotou mám čo to znamená. Trochu som upravil hodnoty. Aby sa dal kontrolovať výsledok.
Kód: Delphi [Vybrat]
  1. EDB_0Mask = $10000000 // Mask
  2. EDB_Table = $2000000  // Group
  3. EDB_Table_Delete = EDB_0Mask or EDB_Table or $0003;
Ja sa chcem dopracovať k výsledku kde:
Kód: Delphi [Vybrat]
  1. Mask = 1;
  2. Group = 2;
Teraz sa mi prvý krát stalo, že vysvetleniu totálne nerozumiem a neviem si ho ani upraviť. :( :( :(  Poďme podľa riadkov
1. EGroupMembers - vymenovaný typ. Načo to je dobré? Mňa zaujíma začiatok a nie koniec. 7 a 6 pozícia zprava (počítam od 0).
2. - 5. EDB_Table...EDB_z - konštanty, ktoré v príklade nie sú nikde použité. Ani som sa nedovtípil načo by mi boli. Ak to majú byť Group, tak to len zdvojuje to čo už mám
7. - 8 - To sú opäť konštatnty. Prečo sú tam práve také hodnoty vôbec netuším.
10. - out of bound. Ako to mám vyskladať, keď nemám ErrCode. Tak som namiesto ErrCode použil EDB_Table_Delete
11 - Keďže 10 je zle...
.
Pozrel som si čo je shl. Ale ako mám počítať bity v hexa som nepochopil :(
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #5 kdy: 09-07-2019, 19:47:28 »
Citace
Jediný krát, keď Enum-Set neviem použiť priamo, ale musím si ho premeniť na konštantu, je v prípade"Case .. of"
Myslíš niečo také?
Kód: Delphi [Vybrat]
  1. type
  2.  
  3.   {$SCOPEDENUMS ON}
  4.   TvstPart = (Name, HeightUp, FloorUpCount, HeightUn, FloorUnCount, IsNew);
  5.   {$SCOPEDENUMS Off}
Použitie
Kód: Delphi [Vybrat]
  1.   case TvstPart(Column) of
  2.     TvstPart.Name: CellText := NodeData.PartName;
  3.     TvstPart.HeightUp: CellText := CurrToStrPrec(NodeData.PartFireHeightUp);
  4.  
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline miroB

  • Guru
  • *****
  • Příspěvků: 516
  • Karma: 17
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #6 kdy: 09-07-2019, 20:05:13 »
Citace
Jediný krát, keď Enum-Set neviem použiť priamo, ale musím si ho premeniť na konštantu, je v prípade"Case .. of"
Myslíš niečo také?
Kód: Delphi [Vybrat]
  1. type
  2.  
  3.   {$SCOPEDENUMS ON}
  4.   TvstPart = (Name, HeightUp, FloorUpCount, HeightUn, FloorUnCount, IsNew);
  5.   {$SCOPEDENUMS Off}
Použitie
Kód: Delphi [Vybrat]
  1.   case TvstPart(Column) of
  2.     TvstPart.Name: CellText := NodeData.PartName;
  3.     TvstPart.HeightUp: CellText := CurrToStrPrec(NodeData.PartFireHeightUp);
  4.  
To je bežné, myslím CASE .. OF pre Enum-Set.
Teda asi takto (symbolicky ):
Kód: Delphi [Vybrat]
  1.   case MyColumnSet of
  2.     [FloorUpCount, HeightUn, FloorUnCount] : CellText := NodeData.PartName;
  3.     [FloorUpCount, HeightUn]: CellText := CurrToStrPrec(NodeData.PartFireHeightUp);
  4.  
Je však cesta, ako zistíš číselnú konštantu. Napr. z [FloorUpCount, HeightUn] a tú už môžeš v Case .. of využiť.
« Poslední změna: 09-07-2019, 20:07:00 od miroB »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #7 kdy: 09-07-2019, 20:19:42 »
Aha, tak už viem čo si myslel pod Enum-Set :)
Citace
Je však cesta, ako zistíš číselnú konštantu.
Viem o tom*. Ale ja som si vytvoril Enum preto, aby som žiadne konštanty nepoužíval.
* - mám to použité pri priraďovaní štýlov v TMS pre jednotlivé xxStyler. Ale tam si potrebujem zistiť názov štýlu.

Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2586
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #8 kdy: 09-07-2019, 20:42:40 »
EDB_0Mask = $10000000 // Mask
EDB_Table = $2000000  // Group
EDB_Table_Delete = EDB_0Mask or EDB_Table or $0003;[/code]
Ja sa chcem dopracovať k výsledku kde:
Kód: Delphi [Vybrat]
  1. Mask = 1;
  2. Group = 2;
[/code]
Na tehle definic me mate:
1. cemu rikas Mask = 1 bit - k cem u je to dobre.
2. definice EDB_Table = 2. Kde jsou dalsi vyctove hodnoty (alternativy) k te table, aby se dalo urcit, kolik bitu potrebujes na jejich zakodovani a tim i definovat jejich masku a ev. dalsi operace pro slozeni/rozlozeni hodnoty. To jsi nejak ten puvodni priklad vubec nepochopil.



To, co jsem ti posilal, nemelo nic spolecneho s tvymi hodnotami, ale melo ti naznacit, co je to maskovani  a jak se skladaji/extrahuji  bity v nejake hodnote. Analogicky se tam daji nastrkat dalsi "rozmery"  :-[

Citace
1. EGroupMembers - vymenovaný typ. Načo to je dobré? Mňa zaujíma začiatok a nie koniec. 7 a 6 pozícia zprava (počítam od 0).
Tohle je vzorova skupina hodnot, ktere chces zakodovat v nekolika bitech uvnitr zakodovane hodnoty

Citace
2. - 5. EDB_Table...EDB_z - konštanty, ktoré v príklade nie sú nikde použité. Ani som sa nedovtípil načo by mi boli. Ak to majú byť Group, tak to len zdvojuje to čo už mám
Tohle jsou definice, ktere umisti hodnoty enumu EGroupMembers  na pozice bitu 8-10:

  11  10   9   8   7   5   4   3   2   1   0
+---+---+---+---+---+---+---+---+---+---+---+
|   | x : x : x |   :   :   :   :   :   :   |
+---+---+---+---+---+---+---+---+---+---+---+
       EDB_xxx           ErrCode


Citace
2. - 5. EDB_Table...EDB_z - konštanty, ktoré v príklade nie sú nikde použité. Ani som sa nedovtípil načo by mi boli.
Na zakodovani EGroupMembers potrebujes 3 bity, takze toje binarne 111 = $7, na zakodovani ErrCode 8 bitu 11111111 = $FF.
A tohle jsou ty masky ktere definuji, jakych bitu si v te hodnote vsimat, kdyz chces tu hodnotu dostat ven.

To udelas ve dvou krocich:
1. zamaskujes bity, ktere te zajimaji  cilil bity = hodnota and maska
2. posunes bity tak, aby LSB byl b0 (pro kompozici obracene b0 na pozadovanou pozici b8, to je v tom prihladu delano operacemi posunu bitu vlevo/vpravo o 8)
3. Je to komutativni, takze na poradi maskovani a posunu nezalezi, pokud si ohlidas rozsahy hodnot, se kterymi operujes.



« Poslední změna: 09-07-2019, 20:44:34 od pf1957 »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #9 kdy: 09-07-2019, 20:46:40 »
Pokúsim sa to nejako pochopiť :)
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #10 kdy: 09-07-2019, 20:54:42 »
Citace
Na tehle definic me mate:
1. cemu rikas Mask = 1 bit - k cem u je to dobre.
2. definice EDB_Table = 2. Kde jsou dalsi vyctove hodnoty (alternativy) k te table, aby se dalo urcit, kolik bitu potrebujes na jejich zakodovani a tim i definovat jejich masku a ev. dalsi operace pro slozeni/rozlozeni hodnoty. To jsi nejak ten puvodni priklad vubec nepochopil.
Chcem to použiť na zostavenie vlastného textu pre výnimku. Ten budem zobrazovať pomocou TAdvTaskDialog, ktorý má 5 textových reťazcov
Kód: Delphi [Vybrat]
  1.     FConten: string;
  2.     FExpandedText: string;
  3.     FFooter: string;
  4.     FInstruction: string;
  5.     FTitle: string;
Napr.
  • Mask = 1 je Table
  • Mask = 2 je Query
  • ...
To použijem napr. pre FTitle. Podobne to je so skupinami
  • Group = 1 Delete
  • Group = 2 InsertInto
  • ...
Pre masku nepredpokladám viac ako 9 položiek. Je to "primitívny" spôsob, ale ten zvládnem. O inom nateraz neviem.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline miroB

  • Guru
  • *****
  • Příspěvků: 516
  • Karma: 17
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #11 kdy: 09-07-2019, 21:17:09 »
Myslím že to je plné náhrada za Mask & spol.
Čitateľné a pre laika veľmi zrozumiteľné.
Plna nahrada to neni, protoze to lze pouzit jen na 1 hodnotu v promenne, zatimco na binarni urovni lze do hodnoty zakodovat nekolik enumu a pomoci masek je izolovat. Delphi jako jazyk nema zadnou strukturu pro praci s bity jako struc  v C-like jazykach - tam to nepotrebujes maskovat a primo se odkazujes na cleny o velikosti nekolika bitu.
..
No a taketo nejake moznosti:
Kód: Delphi [Vybrat]
  1. if enuSet * [ prvy, stvrty] = [ ] then..
  2. if enuSet * [ prvy, stvrty] <> [ ] then..
  3. if enuSet * [ prvy, stvrty] = [ stvrty ] then..
alebo aj takto:
Kód: Delphi [Vybrat]
  1. if Byte( [ prvy, osmy] ) or .. then
Neviem teraz, či to ide už ako konštanta priamo Cast-núť, alebo až v rámci premennej.
Pri Enum-Set Cast je treba dodržať počet bytov, ale inak celý set prehodiť na číslo ide.
Enum-sety pracujú s bitmi a sú pekne výpovedné. Na rozdiel od čísel, na ktoré treba mať niekde prevodník..

Offline Morrison

  • Hrdina
  • ****
  • Příspěvků: 261
  • Karma: 12
    • Verze Delphi: D5, XE2
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #12 kdy: 09-07-2019, 21:23:30 »
Kód: Delphi [Vybrat]
  1. EDB_0Mask = $10000000 // Mask
  2. EDB_Table = $2000000  // Group
  3. EDB_Table_Delete = EDB_0Mask or EDB_Table or $0003;
Ja sa chcem dopracovať k výsledku kde:
Kód: Delphi [Vybrat]
  1. Mask = 1;
  2. Group = 2;

Stanislave, přiznám se, že vůbec netuším čeho ve výsledku chceš dosáhnout, nicméně pokusím se pomoci.
Nuže, když uděláš logický součet $10000000 or $2000000 or $3, dostaneš číslo $12000003
Pokud z něj chceš vyextrahovat zpět informace, které jsi do něj zakódoval, tak nějak takhle:
Kód: Delphi [Vybrat]
  1. Mask := ($12000003 and $F0000000) shr $1C;  // = 1
  2. Group := ($12000003 and $F000000) shr $18;  // = 2
  3. Delete := $12000003 and $F;  // = 3
  4.  
Pokud tomu chceš porozumět, chtělo by to nastudovat reprezentace čísel ve dvojkové a šestnáctkové soustavě a bitové operace.

EDIT: v podstatě jde o to, že máš k dispozici třeba 32bitový integer a je jen na tobě, jak těch 32 bitů využiješ. Můžeš použít třeba horní 4 bity jako nějaký hlavní identifikátor (4 bity ti dají rozsah 0..15, takže tam můžeš zakódovat 16 různých typů), dál použiješ třeba jen 3 bity jako identifikaci akce (rozsah 0..7), pak třeba dalších 6 bitů (rozsah 0..63) jako identifikátor řekněme třeba formuláře atd... Tohle ti v podstatě psal už pf1957
« Poslední změna: 09-07-2019, 21:38:28 od Morrison »
nil

Offline Morrison

  • Hrdina
  • ****
  • Příspěvků: 261
  • Karma: 12
    • Verze Delphi: D5, XE2
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #13 kdy: 09-07-2019, 22:03:08 »
Ještě bych ten příklad zjednodušil, aby to šlo snadněji pochopit.
Takže máš k dispozici 32bitový integer, t.j. 4 bajty a budeš si chtít do každého z těch bajtů uložit nějakou informaci (řekněme TYP, FORMULÁŘ, TABLE, AKCE).

Kód: Delphi [Vybrat]
  1. const
  2.   TYP_NONE = 0;
  3.   TYP_FATAL_ERROR = 1;
  4.   TYP_WRONG_USER_INPUT = 2;
  5.   TYP_ACCESS_DENIED = 3;
  6.   ...
  7.  
  8.   FORM_NONE = 0;
  9.   FORM_ABC = 1;
  10.   FORM_DEF = 2;
  11.   ...
  12.  
  13.   TABLE_NONE = 0;
  14.   TABLE_ABC = 1;
  15.   TABLE_DEF = 2;
  16.   TABLE_GHI = 3;
  17.   ...
  18.  
  19.   ACT_NONE = 0;
  20.   ACT_SELECT = 1;
  21.   ACT_EDIT = 2;
  22.   ACT_DELETE = 3;
  23.   ACT_UPDATE = 4;
  24.   ...
  25.  

Takhle z výše uvedených konstant sestavíš 32b integer:
Kód: Delphi [Vybrat]
  1. var
  2.   Code: Integer;
  3.   ...
  4.   Code := (TYP_WRONG_USER_INPUT shl 24) or // TYP bude první bajt zleva
  5.                (FORM_DEF shl 16) or // FORMULÁŘ bude zakódován do druhého bajtu
  6.                (TABLE_ABC shl 8) or // TABLE je ve třetím bajtu
  7.                ACT_UPDATE; // nejnižší bajt celého integeru
  8.  

A takhle to pak z něj zase dostaneš nazpátek:
Kód: Delphi [Vybrat]
  1. var
  2.   Typ: Byte;
  3.   Form: Byte;
  4.   Table:  Byte;
  5.   Action: Byte;
  6.   ...
  7.   Typ := (Code and $FF000000) shr 24;
  8.   Form := (Code and $FF0000) shr 16;
  9.   Table := (Code and $FF00) shr 8;
  10.   Action := Code and $FF;
  11.  
nil

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4397
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #14 kdy: 09-07-2019, 22:14:16 »
Kódu od Morrisona rozumiem :) Chcem pochopiť aj kód pf1957. Pracujem na tom.
Aspoň viem, že sa k výsledku dopracujem.
.
To Morrison: stoličku si si kúpil?
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.