home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1989 / 02 / anwendg / garbage.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1988-09-21  |  5.9 KB  |  189 lines

  1. (* ------------------------------------------------------ *)
  2. (*                  GARBAGE.PAS                           *)
  3. (*                                                        *)
  4. (*  Dieses Programm demonstriert den Komprimierungs-      *)
  5. (*  Mechanismus für die dBase III+ Memo-Feld Organisation *)
  6. (*                                                        *)
  7. (*       (c) 1988 by Dr.Lothar Wenzel und TOOLBOX         *)
  8. (* ------------------------------------------------------ *)
  9.  
  10. PROGRAM garbage_collection;
  11.  
  12. USES Crt;
  13.  
  14. CONST
  15.   ende = 8192;               (* Größe des Puffers für den *)
  16.                              (* Datenbankvorspann         *)
  17.   leer : BYTE = $20;
  18.   beginn_stufe = 1000000000; (* für Decodierung der       *)
  19.                              (* 10-stelligen Memoadresse  *)
  20.   pos1 = 0;
  21.   pos2 = 9;
  22.  
  23. TYPE
  24.   dateien = FILE OF BYTE;
  25.   INTEGER = longint;
  26.  
  27. VAR
  28.   laenge_vorher  : INTEGER;  (* Länge der Quell-DBT-Datei *)
  29.   laenge_nachher : INTEGER;  (* Länge der Ziel-TTT-Datei  *)
  30.   aktuell        : INTEGER;
  31.   anzahl_memo    : INTEGER;  (* Memo-Felder/Datensatz     *)
  32.   memo_pos       : ARRAY[1..128] OF INTEGER;
  33.  
  34.   laenge_satz    : INTEGER;  (* Länge eines dBase-Satzes  *)
  35.   anzahl_saetze  : INTEGER;  (* Anzahl der Datensätze     *)
  36.   beginn_daten   : INTEGER;
  37.   position       : INTEGER;
  38.   puffer         : ARRAY[1..ende] OF BYTE;
  39.   sektor         : ARRAY[1..512] OF BYTE;
  40.   vorher,nachher : dateien;
  41.   datenbank      : dateien;
  42.   index1,index2  : INTEGER;
  43.   name           : STRING[8];
  44.  
  45.  
  46. (* -----  Konvertierung byte --> integer ---------------- *)
  47. FUNCTION Wert(argument: BYTE): INTEGER;
  48. BEGIN
  49.   IF argument < $30 THEN Wert := 0
  50.   ELSE Wert := Ord(argument-$30);
  51. END;
  52.  
  53. (* -----  Auswertung der möglichen Fehler --------------- *)
  54. PROCEDURE Fehler(nummer: INTEGER);
  55. BEGIN
  56.   CASE nummer OF
  57.     1 : WriteLn('Datenbank ',name,' ist nicht vorhanden !');
  58.     2 : WriteLn('Keine ',name+'.DBT-Datei vorhanden!');
  59.     3 : WriteLn('Keine Memo-Felder vorhanden!');
  60.   END;
  61.   Halt;
  62. END;
  63.  
  64. (*-----   Aufbau der .TTT-Datei aus der DBT.Datei ------- *)
  65. PROCEDURE austausch;
  66. VAR
  67.   index, index3, nummer  : INTEGER;
  68.   stufe, beginn, ort     : INTEGER;
  69.   eintrag, zaehler       : INTEGER;
  70.   merk, merk1, ausgabe   : BYTE;
  71.  
  72. BEGIN
  73.   beginn := aktuell;
  74.   FOR index := 1 TO anzahl_saetze DO BEGIN
  75.     Seek(datenbank, beginn_daten + laenge_satz*(index-1));
  76.     FOR index1:=1 TO laenge_satz DO
  77.       Read(datenbank, puffer[index1]);
  78.     FOR index2:=1 TO anzahl_memo DO BEGIN
  79.       GotoXY(5,15);
  80.       Write('Satz= ',index:6,' Memo= ',index2:3);
  81.       nummer := 0;
  82.       stufe := beginn_stufe;
  83.       FOR index3:=pos1 TO pos2 DO
  84.         nummer:=10*nummer+
  85.                       wert(puffer[index3+memo_pos[index2]]);
  86.       IF nummer >0 THEN BEGIN
  87.         eintrag := $20;
  88.         FOR index3:=pos1 TO pos2 DO BEGIN
  89.           ort := -1+beginn_daten+(index-1)*laenge_satz+
  90.                                     index3+memo_pos[index2];
  91.           Seek(datenbank,ort);
  92.           IF beginn >= stufe THEN eintrag := $30;
  93.           ausgabe := eintrag + (beginn DIV stufe) * $01;
  94.           Write(datenbank,ausgabe);
  95.           beginn := aktuell MOD stufe;
  96.           stufe  := stufe DIV 10;
  97.         END;
  98.         zaehler := 0;
  99.         Write(nachher,leer);
  100.         IF (laenge_vorher>512*nummer) THEN BEGIN
  101.           Seek(vorher,512*nummer+zaehler);
  102.           Read(vorher,merk);
  103.           Seek(nachher,512*aktuell+zaehler);
  104.           Write(nachher,merk);
  105.           REPEAT
  106.             zaehler := Succ(zaehler);
  107.             merk1   := merk;
  108.             Read(vorher, merk); Write(nachher, merk);
  109.           UNTIL (merk=$1a) AND (merk1=$1a);
  110.           WHILE (FileSize(nachher) MOD 512 <> 0) DO
  111.             Write(nachher,leer);
  112.           aktuell := 1 + (zaehler DIV 512);
  113.         END;
  114.       END;
  115.     END;
  116.   END;
  117.   FOR index := 0 TO 3 DO BEGIN
  118.     Seek(nachher, index);
  119.     ausgabe := aktuell MOD 256;
  120.     Write(nachher, ausgabe);
  121.     aktuell:=aktuell DIV 256;
  122.   END;
  123. END;
  124.  
  125. (* ----- Anzahl der Datensätze und Memo-Felder ermitteln  *)
  126. PROCEDURE demontage;
  127. VAR
  128.   index, vorspann: INTEGER;
  129.  
  130. BEGIN
  131.   IF FileSize(datenbank) > ende THEN vorspann := ende
  132.   ELSE vorspann := FileSize(datenbank);
  133.   FOR index := 1 TO vorspann DO
  134.     Read(datenbank, puffer[index]);
  135.   anzahl_saetze := puffer[6]*256 + puffer[5];
  136.   WriteLn('Anzahl der Datensätze = ',anzahl_saetze);
  137.   laenge_satz := puffer[12]*256 + puffer[11];
  138.   anzahl_memo := 0;
  139.   index       := 33;
  140.   position    := 1;
  141.   beginn_daten:= 34;
  142.   REPEAT
  143.     beginn_daten := beginn_daten + 32;
  144.     IF puffer[index+11]=$4d THEN BEGIN
  145.       anzahl_memo := Succ(anzahl_memo);
  146.       memo_pos[anzahl_memo] := position;
  147.     END;
  148.     position := position + puffer[index+16];
  149.     index := index + 32;
  150.   UNTIL puffer[index] = $0d;
  151.   WriteLn('Anzahl der Memo-Felder= ',anzahl_memo);
  152.   IF anzahl_memo = 0 THEN Fehler(3);
  153. END;
  154.  
  155. (* -----  Hauptprogramm --------------------------------- *)
  156.  
  157. BEGIN
  158.   ClrScr;
  159.   Write('Geben Sie den Dateinamen an (ohne .DBF) --->');
  160.   ReadLn(name);
  161.   Assign(datenbank, name + '.DBF');
  162.   Assign(vorher, name + '.DBT');
  163.   Assign(nachher, name + '.TTT');
  164.   {$I-}
  165.   ReSet(datenbank);
  166.   IF IOResult <> 0 THEN Fehler(1);
  167.   ReSet(vorher);
  168.   laenge_vorher := FileSize(vorher);
  169.   IF IOResult <> 0 THEN Fehler(2);
  170.   ReWrite(nachher);
  171.   aktuell := 1;
  172.   FOR index1 := 1 TO 512 DO Write(nachher,leer);
  173.   Demontage;
  174.   Austausch;
  175.   laenge_nachher := FileSize(nachher);
  176.   Close(nachher);
  177.   Close(vorher);
  178.   Close(datenbank);
  179.   WriteLn;
  180.   WriteLn('Erfolgreich durchgeführte Garbage Collection!');
  181.   WriteLn;
  182.   WriteLn('Löschen Sie die Datei ',name+'.DBT !');
  183.   WriteLn;
  184.   WriteLn('Länge vor  Garbage Collection= ', laenge_vorher);
  185.   WriteLn('Länge nach Garbage Collection= ',laenge_nachher);
  186. END.
  187.  
  188. (* ------------------------------------------------------ *)
  189. (*                Ende von GARBAGE.PAS                    *)