home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 05 / grdlagen / lists.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-03-13  |  12.9 KB  |  471 lines

  1. (* ------------------------------------------------------ *)
  2. (*                      LISTS.PAS                         *)
  3. (*   SListNodePtr: Knotenobjekt für einfach verkettete    *)
  4. (*   Liste...                                             *)
  5. (*   DListNodePtr: und für doppelt verkettete Liste.      *)
  6. (*   AbstractList: Abstraktes Objekt, als Grundlage für   *)
  7. (*   Listen verwaltendes Objekt.                          *)
  8. (*   DListCollection: Implementiert Verwaltung für        *)
  9. (*   doppelt verkettete, unsortierte Liste.               *)
  10. (*            (C) 1991 R.Reichert & TOOLBOX               *)
  11. (* ------------------------------------------------------ *)
  12. UNIT Lists;
  13.  
  14. INTERFACE
  15.  
  16. USES UBase;
  17.  
  18. CONST
  19.   DLOk    = 0;
  20.   DLNoMem = 1;      { ReturnCode für Speicherplatzprobleme }
  21.  
  22. TYPE
  23.   SListNodePtr = ^SListNode;
  24.   SListNode    = OBJECT (Base)
  25.     Next : SListNodePtr;
  26.     Data : BasePtr;
  27.  
  28.     CONSTRUCTOR Init;
  29.     CONSTRUCTOR InitSet(N : SListNodePtr; D : BasePtr);
  30.     PROCEDURE   SetNext(N : SListNodePtr);
  31.     PROCEDURE   SetData(D : BasePtr);
  32.     FUNCTION    GetNextNode : SListNodePtr;
  33.     FUNCTION    GetData : BasePtr;
  34.     DESTRUCTOR  Done;                               VIRTUAL;
  35.   END;
  36.  
  37.   DListNodePtr = ^DListNode;
  38.   DListNode    = OBJECT (SListNode)
  39.     Prev : DListNodePtr;
  40.     CONSTRUCTOR Init;
  41.     CONSTRUCTOR InitSet(P, N : DListNodePtr; D : BasePtr);
  42.     PROCEDURE   SetNext(N : DListNodePtr);
  43.     PROCEDURE   SetPrev (P : DListNodePtr);
  44.     FUNCTION    GetPrev : DListNodePtr;
  45.     FUNCTION    GetNext : DListNodePtr;
  46.   END;
  47.  
  48.   AbstractListPtr = ^AbstractList;
  49.   AbstractList    = OBJECT (Base)
  50.     CONSTRUCTOR Init;
  51.     PROCEDURE   Put(D : BasePtr);                   VIRTUAL;
  52.     PROCEDURE   Insert(D : BasePtr);                VIRTUAL;
  53.     PROCEDURE   Delete;                             VIRTUAL;
  54.     PROCEDURE   Clear;                              VIRTUAL;
  55.     FUNCTION    GetActData : BasePtr;               VIRTUAL;
  56.     FUNCTION    GetNumber : LONGINT;                VIRTUAL;
  57.     DESTRUCTOR  Done;                               VIRTUAL;
  58.   END;
  59.  
  60.   DListCollectionPtr = ^DListCollection;
  61.   DListCollection    = OBJECT (AbstractList)
  62.     FreeHeap,
  63.     Counter     : LONGINT;
  64.     OverFlow    : BOOLEAN;
  65.     First, Last,
  66.     Act,
  67.     Left, Right : DListNodePtr;
  68.     ReturnCode  : BYTE;
  69.     CONSTRUCTOR Init;
  70.     PROCEDURE   SetFreeHeap(FrH : LONGINT);         VIRTUAL;
  71.     PROCEDURE   SetOverFlow(O : BOOLEAN);           VIRTUAL;
  72.     PROCEDURE   Put(D : BasePtr);                   VIRTUAL;
  73.     PROCEDURE   Insert(D : BasePtr);                VIRTUAL;
  74.     PROCEDURE   Delete;                             VIRTUAL;
  75.     PROCEDURE   Clear;                              VIRTUAL;
  76.     PROCEDURE   SetActNode(N : DListNodePtr);       VIRTUAL;
  77.     PROCEDURE   SetActNodeTo(Nr : LONGINT);         VIRTUAL;
  78.     FUNCTION    GetNumber : LONGINT;                VIRTUAL;
  79.     FUNCTION    GetFreeHeap : LONGINT;              VIRTUAL;
  80.     FUNCTION    GetOverFlow : BOOLEAN;              VIRTUAL;
  81.     FUNCTION    GetReturnCode : BYTE;               VIRTUAL;
  82.     { Die Node-Methoden geben einen Zeiger                 }
  83.     { auf den Knoten, die Data-Methoden auf das Daten-     }
  84.     { objekt dieser Methoden zurück.                       }
  85.     FUNCTION GetActNode : DListNodePtr;             VIRTUAL;
  86.     FUNCTION GetActData : BasePtr;                  VIRTUAL;
  87.     FUNCTION GetNextNode : DListNodePtr;            VIRTUAL;
  88.     FUNCTION GetNextData : BasePtr;                 VIRTUAL;
  89.     FUNCTION GetPrevNode : DListNodePtr;            VIRTUAL;
  90.     FUNCTION GetPrevData : BasePtr;                 VIRTUAL;
  91.     FUNCTION GetFirstNode: DListNodePtr;            VIRTUAL;
  92.     FUNCTION GetFirstData: BasePtr;                 VIRTUAL;
  93.     { GetLast... beziehen sich nicht auf den Knoten Last,  }
  94.     { der nie Daten enthält, sondern auf den letzten       }
  95.     { Knoten, der noch Daten enthält, also den             }
  96.     { Vorgänger von Last.                                  }
  97.     FUNCTION GetLastNode : DListNodePtr;            VIRTUAL;
  98.     FUNCTION GetLastData : BasePtr;                 VIRTUAL;
  99.     { Die folgenden Methoden verschieben den Knotenzeiger
  100.       Act zum nächsten, vorhergehenden, ersten oder letzten
  101.       Knoten und liefern einen Zeiger auf dessen Daten-
  102.       objekt.                                              }
  103.     FUNCTION GotoNextData: BasePtr;                 VIRTUAL;
  104.     FUNCTION GotoPrevData: BasePtr;                 VIRTUAL;
  105.     FUNCTION GotoFirstData: BasePtr;                VIRTUAL;
  106.     FUNCTION GotoLastData: BasePtr;                 VIRTUAL;
  107.     { IsOnLast ist TRUE, wenn Act^.Data auf das letzte
  108.       Datenobjekt zeigt (Act^.Next=Last).                  }
  109.     FUNCTION   IsOnLast : BOOLEAN;                  VIRTUAL;
  110.     DESTRUCTOR Done;                                VIRTUAL;
  111.   END;
  112.  
  113. IMPLEMENTATION
  114.  
  115.   CONSTRUCTOR SListNode.Init;
  116.   BEGIN
  117.     Next := NIL;  Data := NIL;
  118.   END;
  119.  
  120.   CONSTRUCTOR SListNode.InitSet(N:SListNodePtr; D:BasePtr);
  121.   BEGIN
  122.     Next := N;    Data := D;
  123.   END;
  124.  
  125.   PROCEDURE SListNode.SetNext(N : SListNodePtr);
  126.   BEGIN
  127.     Next := N;
  128.   END;
  129.  
  130.   PROCEDURE SListNode.SetData(D : BasePtr);
  131.   BEGIN
  132.     Data := D;
  133.   END;
  134.  
  135.   FUNCTION SListNode.GetNextNode : SListNodePtr;
  136.   BEGIN
  137.     GetNextNode := Next;
  138.   END;
  139.  
  140.   FUNCTION SListNode.GetData : BasePtr;
  141.   BEGIN
  142.     GetData := Data;
  143.   END;
  144.  
  145.   DESTRUCTOR SListNode.Done;
  146.   BEGIN
  147.     IF Data <> NIL THEN Dispose(Data, Done);
  148.   END;
  149.  
  150.   CONSTRUCTOR DListNode.Init;
  151.   BEGIN
  152.     SListNode.Init;   Prev := NIL;
  153.   END;
  154.  
  155.   CONSTRUCTOR DListNode.InitSet(P,N:DListNodePtr;D:BasePtr);
  156.   BEGIN
  157.     Next := N;  Prev := P;  Data := D
  158.   END;
  159.  
  160.   PROCEDURE DListNode.SetNext(N : DListNodePtr);
  161.   BEGIN
  162.     Next := N;
  163.   END;
  164.  
  165.   PROCEDURE DListNode.SetPrev(P : DListNodePtr);
  166.   BEGIN
  167.     Prev := P;
  168.   END;
  169.  
  170.   FUNCTION DListNode.GetPrev : DListNodePtr;
  171.   BEGIN
  172.     GetPrev := Prev;
  173.   END;
  174.  
  175.   FUNCTION DListNode.GetNext : DListNodePtr;
  176.   BEGIN
  177.     GetNext := DListNodePtr(Next);
  178.   END;
  179.  
  180.   CONSTRUCTOR AbstractList.Init;
  181.   BEGIN
  182.     Abstract('AbstractList');
  183.   END;
  184.  
  185.   PROCEDURE AbstractList.Put(D : BasePtr);
  186.   BEGIN
  187.     Abstract('AbstractList');
  188.   END;
  189.  
  190.   PROCEDURE AbstractList.Insert(D : BasePtr);
  191.   BEGIN
  192.     Abstract('AbstractList');
  193.   END;
  194.  
  195.   PROCEDURE AbstractList.Delete;
  196.   BEGIN
  197.     Abstract('AbstractList');
  198.   END;
  199.  
  200.   PROCEDURE AbstractList.Clear;
  201.   BEGIN
  202.     Abstract('AbstractList');
  203.   END;
  204.  
  205.   FUNCTION AbstractList.GetActData : BasePtr;
  206.   BEGIN
  207.     Abstract('AbstractList');
  208.   END;
  209.  
  210.   FUNCTION AbstractList.GetNumber : LONGINT;
  211.   BEGIN
  212.     Abstract('AbstractList');
  213.   END;
  214.  
  215.   DESTRUCTOR AbstractList.Done;
  216.   BEGIN
  217.     Abstract('AbstractList');
  218.   END;
  219.  
  220.   CONSTRUCTOR DListCollection.Init;
  221.   BEGIN
  222.     Counter := 0;    FreeHeap := 0;     OverFlow := TRUE;
  223.     First   := NIL;  Last     := NIL;   Act      := NIL;
  224.     Left    := NIL;  Right    := NIL;   ReturnCode := DLOk;
  225.   END;
  226.  
  227.   PROCEDURE DListCollection.SetFreeHeap(FrH : LONGINT);
  228.   BEGIN
  229.     FreeHeap := FrH;
  230.     IF FreeHeap>MemAvail THEN FreeHeap := MemAvail;
  231.   END;
  232.  
  233.   PROCEDURE DListCollection.SetOverFlow(O : BOOLEAN);
  234.   BEGIN
  235.     OverFlow := O;
  236.   END;
  237.  
  238.   PROCEDURE DListCollection.Put(D : BasePtr);
  239.   VAR
  240.     P : DListNodePtr;
  241.   BEGIN
  242.     IF D <> NIL THEN BEGIN
  243.       IF FreeHeap + SizeOf(D^) > MemAvail THEN BEGIN
  244.         Dispose(D);
  245.         ReturnCode := DLNoMem;
  246.       END ELSE IF First = Last THEN BEGIN
  247.         Last  := New(DListNodePtr, Init);
  248.         First := New(DListNodePtr, InitSet(NIL, Last, D));
  249.         Last^.SetNext(NIL);
  250.         Last^.SetPrev(First);
  251.         Act := First;  Inc(Counter);
  252.       END ELSE BEGIN
  253.         Left  := Act;
  254.         Right := Act^.GetNext;
  255.         P := New(DListNodePtr, InitSet(Left, Right, D));
  256.         Left^.SetNext(P);
  257.         Right^.SetPrev(P);
  258.         Act := P;      Inc(Counter);
  259.       END
  260.     END ELSE
  261.       ReturnCode := DLNoMem;
  262.   END;
  263.  
  264.   PROCEDURE DListCollection.Insert(D : BasePtr);
  265.   BEGIN
  266.     Put(D);
  267.   END;
  268.  
  269.   PROCEDURE DListCollection.Delete;
  270.   VAR
  271.     P : DListNodePtr;
  272.   BEGIN
  273.     IF First^.GetNext=Last THEN BEGIN
  274.       Dispose(First, Done);         { First ist gleich Act }
  275.       First := NIL;  Last := NIL;      { Liste wieder leer }
  276.       Act   := NIL;  Left := NIL; Right := NIL;
  277.       Dec(Counter);
  278.     END ELSE                     { sonst, wenn Liste nicht }
  279.     IF NOT (First = Last) THEN BEGIN     { leer, entfernen }
  280.       Left  := Act^.GetPrev;
  281.       Right := Act^.GetNext;
  282.       Left^.SetNext(Right);
  283.       Right^.SetPrev(Left);
  284.       P := Act;
  285.       IF NOT (Act^.GetNext = Last) THEN Act := Right
  286.                                    ELSE Act := Left;
  287.       Dispose(P, Done);
  288.       Dec(Counter);
  289.     END;
  290.   END;
  291.  
  292.   PROCEDURE DListCollection.Clear;
  293.   VAR
  294.     P : DListNodePtr;
  295.   BEGIN
  296.     IF NOT (First = Last) THEN BEGIN    { Wenn Liste nicht }
  297.       Act := First;                           { leer, dann }
  298.       WHILE (Act <> NIL) DO BEGIN            { durchlaufen }
  299.         P := Act^.GetNext;
  300.         Dispose(Act, Done);                  { und löschen }
  301.         Act := P;
  302.       END;
  303.       First := NIL;  Last := NIL;  Act := NIL;
  304.       Right := NIL;  Left := NIL;
  305.     END;
  306.   END;
  307.  
  308.   PROCEDURE DListCollection.SetActNode(N : DListNodePtr);
  309.   BEGIN
  310.     IF N <> NIL THEN Act := N;
  311.   END;
  312.  
  313.   PROCEDURE DListCollection.SetActNodeTo(Nr : LONGINT);
  314.   VAR
  315.     I : LONGINT;
  316.   BEGIN
  317.     IF First <> NIL THEN BEGIN
  318.       Act := First; I := 1;
  319.       WHILE (I < Counter) AND (I < Nr) DO BEGIN
  320.         Act := Act^.GetNext;  Inc(I);
  321.       END;
  322.     END;
  323.   END;
  324.  
  325.   FUNCTION DListCollection.GetNumber : LONGINT;
  326.   BEGIN
  327.     GetNumber := Counter;
  328.   END;
  329.  
  330.   FUNCTION DListCollection.GetFreeHeap : LONGINT;
  331.   BEGIN
  332.     GetFreeHeap := FreeHeap;
  333.   END;
  334.  
  335.   FUNCTION DListCollection.GetOverFlow : BOOLEAN;
  336.   BEGIN
  337.     GetOverFlow := OverFlow;
  338.   END;
  339.  
  340.   FUNCTION DListCollection.GetReturnCode : BYTE;
  341.   BEGIN
  342.     GetReturnCode := ReturnCode;  ReturnCode := DLOk;
  343.   END;
  344.  
  345.   FUNCTION DListCollection.GetActNode : DListNodePtr;
  346.   BEGIN
  347.     GetActNode := Act;
  348.   END;
  349.  
  350.   FUNCTION DListCollection.GetActData : BasePtr;
  351.   BEGIN
  352.     GetActData := Act^.GetData;
  353.   END;
  354.  
  355.   FUNCTION DListCollection.GetNextNode : DListNodePtr;
  356.   BEGIN
  357.     GetNextNode := Act^.GetNext;
  358.   END;
  359.  
  360.   FUNCTION DListCollection.GetNextData : BasePtr;
  361.   BEGIN
  362.     IF Act^.GetNext <> Last THEN
  363.       GetNextData := Act^.GetNext^.GetData
  364.     ELSE
  365.       GetNextData := NIL;
  366.   END;
  367.  
  368.   FUNCTION DListCollection.GetPrevNode : DListNodePtr;
  369.   BEGIN
  370.     GetPrevNode := Act^.GetPrev;
  371.   END;
  372.  
  373.   FUNCTION DListCollection.GetPrevData : BasePtr;
  374.   BEGIN
  375.     IF Act^.GetPrev <> NIL THEN
  376.       GetPrevData := Act^.GetPrev^.GetData
  377.     ELSE
  378.       GetPrevData := NIL;
  379.   END;
  380.  
  381.   FUNCTION DListCollection.GetFirstNode : DListNodePtr;
  382.   BEGIN
  383.     GetFirstNode := First;
  384.   END;
  385.  
  386.   FUNCTION DListCollection.GetFirstData : BasePtr;
  387.   BEGIN
  388.     IF First <> NIL THEN GetFirstData := First^.GetData
  389.                     ELSE GetFirstData := NIL;
  390.   END;
  391.  
  392.   FUNCTION DListCollection.GetLastNode : DListNodePtr;
  393.   BEGIN
  394.     IF Last <> NIL THEN GetLastNode := Last^.GetPrev
  395.                    ELSE GetLastNode := NIL;
  396.   END;
  397.  
  398.   FUNCTION DListCollection.GetLastData : BasePtr;
  399.   BEGIN
  400.     IF Last <> NIL THEN
  401.       GetLastData := Last^.GetPrev^.GetData
  402.     ELSE
  403.       GetLastData := NIL;
  404.   END;
  405.  
  406.   FUNCTION DListCollection.GotoNextData : BasePtr;
  407.   BEGIN
  408.     IF NOT (First = Last) THEN BEGIN
  409.       IF NOT (Act^.GetNext = Last) THEN BEGIN
  410.         Act := Act^.GetNext;
  411.         GotoNextData := Act^.GetData;
  412.       END ELSE
  413.         IF NOT OverFlow THEN
  414.           GotoNextData := NIL
  415.         ELSE BEGIN
  416.           Act := First;
  417.           GotoNextData := Act^.GetData;
  418.         END
  419.     END ELSE
  420.       GotoNextData := NIL;
  421.   END;
  422.  
  423.   FUNCTION DListCollection.GotoPrevData : BasePtr;
  424.   BEGIN
  425.     IF NOT (First = Last) THEN BEGIN
  426.       IF NOT (Act^.GetPrev = NIL) THEN BEGIN
  427.         Act := Act^.GetPrev;
  428.         GotoPrevData := Act^.GetData;
  429.       END ELSE
  430.         IF NOT OverFlow THEN
  431.           GotoPrevData := NIL
  432.         ELSE BEGIN
  433.           Act := Last^.GetPrev;
  434.           GotoPrevData := Act^.GetData;
  435.         END
  436.     END ELSE
  437.       GotoPrevData := NIL;
  438.   END;
  439.  
  440.   FUNCTION DListCollection.GotoFirstData : BasePtr;
  441.   BEGIN
  442.     IF NOT (First = Last) THEN BEGIN
  443.       Act := First;
  444.       GotoFirstData := Act^.GetData;
  445.     END ELSE
  446.       GotoFirstData := NIL;
  447.   END;
  448.  
  449.   FUNCTION DListCollection.GotoLastData : BasePtr;
  450.   BEGIN
  451.     IF NOT (First = Last) THEN BEGIN
  452.       Act := Last;
  453.       GotoLastData := Act^.GetData;
  454.     END ELSE
  455.       GotoLastData := NIL;
  456.   END;
  457.  
  458.   FUNCTION DListCollection.IsOnLast : BOOLEAN;
  459.   BEGIN
  460.     IsOnLast := (Act^.GetNext = Last);
  461.   END;
  462.  
  463.   DESTRUCTOR DListCollection.Done;
  464.   BEGIN
  465.     Clear;
  466.   END;
  467.  
  468. END.
  469. (* ------------------------------------------------------ *)
  470. (*                   Ende von LISTS.PAS                   *)
  471.