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

Offline Morrison

  • Hrdina
  • ****
  • Příspěvků: 276
  • Karma: 12
    • Verze Delphi: D5, XE2
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #15 kdy: 09-07-2019, 22:27:51 »
Možná budu psát něco, co už znáš, tak to případně ignoruj. Maska je to, čím z toho velkého čísla vymaskuješ jen to, co tě právě zajímá. V tom mém příkladu třeba když chci z "code" vytáhnout "Table", tak na něj použiju masku and $FF00, čímž řeknu, že mě zajímají z celého čísla jen bity 8 až 15. Pak už se tahle hodnota jen posune o 8 bitů doprava a je z toho původní bajt, třeba "TABLE_ABC".

OT: Zatím nekoupil, rvu prachy převážně do auta a do dovolených. A utěšuji se tím, že vlastně čím horší židle, tím lépe pro zdraví, protože to nutí člověka se zvednout a jít se třeba chvíli projít :)
« Poslední změna: 09-07-2019, 22:41:28 od Morrison »
nil

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 796
  • Karma: 43
    • Verze Delphi: 10.3
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #16 kdy: 09-07-2019, 22:38:46 »
Excellent
Rated 1 time
Taky se dá použít "record with variant parts":

Kód: Delphi [Vybrat]
  1. type tZaznam=packed record
  2.       case integer of
  3.        0: ( Typ: Byte;
  4.             Form: Byte;
  5.             Table:  Byte;
  6.             Action: Byte; );
  7.        1: ( Value: cardinal; );
  8.      end;
  9.  

Hodnoty zapsané do Typ, Form, Table a Action se ihned promítají do Value, protože jsou v paměti na stejném místě. Totéž naopak - hodnota zapsaná do Value se projeví v těch ostatních.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2607
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #17 kdy: 09-07-2019, 22:50:03 »
No a taketo nejake moznosti:
Kód: Delphi [Vybrat]
  1. if enuSet * [ prvy, stvrty] = [ ] then..
jsou k nicemu v pripade, ze potrebujes dve a vice disjunktnich mnozit enuSet1, enuSet2, enuSet3 nasackovat do jednoho skalaru a operovat s nimi...

Typ set je v Delphi max. 256 hodnot ulozenych az v 32 bytech, ale jen pro jednu mnozinu, zatimco kdyz si to sklada rucne (to je to, o co se snazi), tak vlastne nema omezeni a tech mnozin si tam muze naskladat kolik chce. Ale nema pro to podporu na urovni jazyka, musi to delat rucne.

Jinak samozrejme cela aplikace by vnitrne mela byt napsana pomoci enumu a jejich mnozin, protoze prekladac tak ohlida silnou typovou kontrolu. To mapovani a skladani do nejakeho vlastniho kodu by mela byt otazka jen vnejsiho rozhrani napr. to sestavovani chybovych kodu. Obvykle se skladaji do jednoho skalaru, zpravidla dword, ktery poskytuje dostatecny rozsah i pro rozsahle systemy a strukturovat kod do 3-4 kategorii, ale klidne by se dal ten kod vyjadrit nekolika skalary, jen se to bezne nedela.


Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2607
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #18 kdy: 09-07-2019, 22:53:00 »
Pre masku nepredpokladám viac ako 9 položiek.
No hlavne bys tomu asi nemel rikat maska, kdyz to nema funkci masky, ta bude mit 4 bity, ktere potrebujes na zakodovani tech 9 polozek.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2607
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #19 kdy: 09-07-2019, 22:55:09 »
Taky se dá použít "record with variant parts":
Bohuzel je na hranici bytu, protoze Delphi nema struct

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4505
  • Karma: 40
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #20 kdy: 10-07-2019, 07:52:09 »
Citace
No hlavne bys tomu asi nemel rikat maska, kdyz to nema funkci masky, ta bude mit 4 bity, ktere potrebujes na zakodovani tech 9 polozek.
Máš pravdu. Ja som to prebral automaticky bez rozmýšľania. Aj tak rozmýšľam, že "prvej položke" vyhradím 2 pozície a druhej 3. Človek nikdy nevie. Hlavne ak to budem používať aj v iných programoch.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2607
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #21 kdy: 10-07-2019, 08:09:54 »
Citace
No hlavne bys tomu asi nemel rikat maska, kdyz to nema funkci masky, ta bude mit 4 bity, ktere potrebujes na zakodovani tech 9 polozek.
Máš pravdu. Ja som to prebral automaticky bez rozmýšľania. Aj tak rozmýšľam, že "prvej položke" vyhradím 2 pozície a druhej 3. Človek nikdy nevie. Hlavne ak to budem používať aj v iných programoch.
Zkus se zamyslet nad tim variantnim recordem, co posilal Vandrovnik s tim, jestli bys nemohl misto byte pouzit enum (o velikosti byte) a z tech max. 4 polozek neposkladal ten kod, ev. co by se stalo, kdybys ten kod rozsiril z 32 na 64 bitu a ten pocet polozek jeste zvysil ev. nekterym enumum nezvedl velikost direktivou $Z

To by ti umoznilo bez nejakeho matlani bitiku nastrkat do clenu recordu rovnou hodnoty enumu a vysledek si precist z te variantni casti a obracene, stracit tam kod a jednotlive hodnoty si brat v celenech te druhe varianty.

Tim by se ti to cele zjednodusilo a program by byl spolehlivejsi a udrzovatelnejsi, jen bys nesmel v budoucnu vytect z velikosti toho kodu. Ale myslim, ze dneska neni duvod to neudelat 64bitove.
« Poslední změna: 10-07-2019, 08:13:44 od pf1957 »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4505
  • Karma: 40
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #22 kdy: 11-07-2019, 20:44:23 »

V kuse nad tým sedím a spojazdnil som príklad od Morrisona. Snáď aj nejako pochopil.
Kód: Delphi [Vybrat]
  1. procedure TfrmForTesting.btnMorrisonClick(Sender: TObject);
  2. var
  3.   Mask: Byte;
  4.   Group, Group2, Group3: Byte;
  5.   Delete , Delete2, Delete3, Delete4: Byte;
  6. begin  ///  OK
  7. // Mask Group Delete
  8. //  $8  765    9753
  9.   Mask := (EDB_Detail and  $F0000000) shr 28;  // = 8
  10.   Group3 := (EDB_Detail and $F000000) shr 24;  // = 7
  11.   Group2 := (EDB_Detail and  $F00000) shr 20;  // = 6
  12.   Group := (EDB_Detail and    $F0000) shr 16;  // = 5
  13.   Delete4 := (EDB_Detail and   $F000) shr 12;  // = 9
  14.   Delete3 := (EDB_Detail and    $F00) shr 8;   // = 7
  15.   Delete2 := EDB_Detail and      $F0  shr 4;   // = 5
  16.   Delete := EDB_Detail and        $F;          // = 3
  17. end;
Ukážku od pf1957 nedokážem nijako sfunkčniť a už vôbec nie pochopiť :'(  Netuším načo tam sú konštanty typu EDB_y. V konečnom výsledku to sú násobky čísla 256. (256, 512, 768, 1024). Ako to vidím ja, tak pre mňa nemajú výpovednú hodnotu.
Kód: Delphi [Vybrat]
  1. procedure TfrmForTesting.btnpf1957Click(Sender: TObject);
  2. var
  3.   Group: LongWord;
  4. begin
  5. // Mask Group Delete
  6. //  $8  765    9753
  7. //           $87659753        $7 shl 8
  8.   Group := (EDB_Detail and EDB_GroupMask);  // = 1972
  9. end;
Čo sa týka variantného recordu, tak viem akurát record
  • definovať
  • použiť ho vo VirtualStringTree. Lebo sa oň postará
Hlavne neviem pochopiť jednú vec. Priznávam sa, že som si o tom nič neprečítal, čo idem teraz napraviť. Ale aj tak. V case mám pod 0: štyri hodnoty a pod 1: len jednu. Netuším ako sa s tým má pracovať. Idem čítať.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 796
  • Karma: 43
    • Verze Delphi: 10.3
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #23 kdy: 11-07-2019, 21:11:36 »
Hlavne neviem pochopiť jednú vec. Priznávam sa, že som si o tom nič neprečítal, čo idem teraz napraviť. Ale aj tak. V case mám pod 0: štyri hodnoty a pod 1: len jednu. Netuším ako sa s tým má pracovať. Idem čítať.

4 hodnoty po 1 bajtu a pak 1 hodnotu zabírající 4 bajty :-) Ten variantní záznam umí ty 4 "malé" hodnoty sloučit do jedné "velké" (projeví se to stejně jako bitový posun o 8, 16 a 24 bitů, ale nemusí se nad tím bádat, prostě se to "stane samo").

Pokud by pro nějaký údaj nestačil jeden bajt, tak jak psal myslím pf1957, tu jednu "velkou" hodnotu změnit třeba na UInt64 a ty malé podle potřeby zvětšit třeba na Word (jejich celková velikost by pak mohla být až 8 bajtů).

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4505
  • Karma: 40
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #24 kdy: 11-07-2019, 21:20:36 »
Ďakujem. Našiel som príklad aj použitím. To by malo pomôcť.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2607
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #25 kdy: 12-07-2019, 09:26:35 »
Ukážku od pf1957 nedokážem nijako sfunkčniť a už vôbec nie pochopiť :'(  Netuším načo tam sú konštanty typu EDB_y.
Ty konstanty jsou tam proto, kdybys definoval dalsi konstanty, aby se vsechno psalo prave jednou. Pokud si myslis, ze je k nicemu nepotrebujes a budes pouzivat vyhradne enumy, pak ti staci definovat pro kazdou hodnotu
  1. enum
  2. masku
  3. bitovy posun

tj.napr.
Kód: Delphi [Vybrat]
  1. type EGroupMembers  = (Table, x, ...);
  2. const EDB_GroupShift = 8;
  3. const EDB_GroupMask = $7 shl EDB_GroupShift;
  4.  
a pak ty operace vypadaji:
Kód: Delphi [Vybrat]
  1. var code: dword;
  2. ...
  3. code := (code and not EDB_GroupMask) or ((ord(AValue) shl EDB_GroupShift) and EDB_GroupMask);
  4.  
a inverzni
Kód: Delphi [Vybrat]
  1. var value: EGroupMembers;
  2. ...
  3. value := EGroupMembers((ACode and EDB_GroupMask) shr EDB_GroupShift);
  4.  

Variantni record by pak mohl vypadat (s tim, ze na Group bude zabrano 8 bitu a ne 3 a to jeste za podminky definicie EGroupMembers jako $Z1 - min Pascal neumi):
Kód: Delphi [Vybrat]
  1. TErrCode = packed record
  2.   case integer of
  3.      0: (Error: byte;
  4.           Group: EGroupMembers;
  5.           Unused:  word;
  6.          );
  7.      1: (Value: dword);
  8. end;
  9.  
a analogicke operace
Kód: Delphi [Vybrat]
  1. var r: TErrorCode;
  2. var code: dword;
  3. ...
  4. r.Group := AValue;
  5. code := r.Value;
  6.  
a obracene
Kód: Delphi [Vybrat]
  1. var r: TErrorCode;
  2. var group: EGroupMembers;
  3. ...
  4. r.Value := ACode;
  5. group := r.Group;
  6.  

Jinak uz nevim, jak bych ti to vysvetlil, protoze to jsou uplne zaklady, ktere se AFAIK, doctes na prvnich par desitkach stranek prirucky jazyka.


« Poslední změna: 12-07-2019, 09:56:58 od pf1957 »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4505
  • Karma: 40
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #26 kdy: 12-07-2019, 09:50:53 »
Citace
Jinak uz nevim, jak bych ti to vysvetlil, protoze to jsou uplne zaklady, ktere se AFAIK, doctes na prvnich par desitkach stranek prirucky jazyka.
Ďalej to už vysvetľovať nemusíš. Buď to zvládnem alebo nie. Bodka.
Ja som o tom čítal, ale žiaľ to je nad moje schopnosti, ktoré som dostal do vienka pri narodení :( :( :(  V tomto smere sa víly veľmi nečinili >:( Ja som si myslel, že si to už so mnou vzdal ;D
Ďakujem.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4505
  • Karma: 40
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #27 kdy: 12-07-2019, 12:57:14 »
Citace
Pokud si myslis, ze je k nicemu nepotrebujes a budes pouzivat vyhradne enumy, pak ti staci definovat pro kazdou hodnotu
Práve, že ja neviem načo tam sú a ako sa majú použiť. Možno to s posledným príspevkom #25 pochopím.
Idem bojovať.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2607
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #28 kdy: 12-07-2019, 15:03:21 »
Práve, že ja neviem načo tam sú a ako sa majú použiť.
Ja zase nevim, co je cilem tveho snazeni. Udelal sis nejakou analyzu, ze ktere ti vylezl strom informaci o chybe, ktere chces nejak zakodovat a v aplikaci s nimi pracovat.

1. Prvni je taxonomie vyjimek, ktere rozsiris o ty informace. A tim to muze skoncit. Informace budou na urovni enumu a kodovat se nebudou a predavat se budou v instanci vyjimky. Pripadny chybovy kod lze metodou exception vyrenderovat. Cilil bezna prace s objekty.

2. Pokud by ta skladba informaci byla natolik heterogenni, ze by se spatne navrhovaly spolecni predkove vyjimek resp. by to bylo neprehledne ev. nesrozumitelne,
lze pouzit nejake zakodovani do jedne hodnoty, ktera by se pak predavala a pri praci se zase zpatky dekodovala apod (asi nema smysl uvazovat, ze by to nemusela byt nutne jedina hodnota, ale mohlo by jich byt nekolik)

3. Pokud by se informace musela/mela kodovat, zalezi, jakeho rozsahu jsou ty informace a jestli se ti vsechny vejdou treba do UInt64 s nejmensi jednotkou informace 1. byte. Pak je IMHO vhodne pouzit ten variantni record a enumy.

4. Pokud se nevejdou a bude nutne matlat bitiky, no tak si to budes muset rucne poskladat. Na jedne strane se nabizi reseni s enumy - tj. uplna silna typova kontrola v aplikaci tj. to, co jsem ti ted naznacoval naposledy, na opacne strane jsou normalni ciselne konstanty, to bude zrejme nejaky ten uplne prvni stary priklad error subsystemu.

A z toho se odviji, jake konstanty potrebujes nadefinovat. A definovat bys je mel tak, aby se vsechno definovalo jen jednou a aby kdyz zmenis nekde neco, aby se to automaticky promitlo do vsech ostatnich definic a nemusel jsi rucne prepisovat buhvi co vsechno.








Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4505
  • Karma: 40
    • Verze Delphi: XE7 professional
Re:Kódy chýb - zistiť masku a skupinu
« Odpověď #29 kdy: 12-07-2019, 21:10:23 »
Veľmi sa čudujem, že vlastne nikto nevie čo chcem :o . Idem to vysvetliť. Možno mi navrhnete aj iné riešenie. Jednoduchá štruktúra chýb:
  • Category - DB, JSON, VST...
  • Group - pre DB: Table, Query...
  • Detail - pre Table: Insert, Edit, Post...
  • ErrorCode = Category or Group or Detail
potom v kóde:
Kód: Delphi [Vybrat]
  1. try
  2.   MyTable.Post;
  3. except on E: Exception
  4. do
  5.   MyError.Create(ErrorCode_Table_Post, ...)  // Chcem využiť vnorenie chýb. S tým bude najťažší boj.
  6.    // Ak sa dá, tak ošetriť chybu
  7.   ...
  8.   raise;
  9. end;
Potom v MyError rozložím ErrorCode späť na Category, Group a Detail. Podľa jednotlivých hodnôt poskladám textové reťazce pre oznam (AdvTaskDialog - 5 x string) a log. Budú sa skladať z vlastných textov a Message jednotlivých chýb. Podľa situácie zapíšem chybu do logu/DB a prípadne si ju pošlem.
To je všetko.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.