home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* LISTS.PAS *)
- (* SListNodePtr: Knotenobjekt für einfach verkettete *)
- (* Liste... *)
- (* DListNodePtr: und für doppelt verkettete Liste. *)
- (* AbstractList: Abstraktes Objekt, als Grundlage für *)
- (* Listen verwaltendes Objekt. *)
- (* DListCollection: Implementiert Verwaltung für *)
- (* doppelt verkettete, unsortierte Liste. *)
- (* (C) 1991 R.Reichert & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT Lists;
-
- INTERFACE
-
- USES UBase;
-
- CONST
- DLOk = 0;
- DLNoMem = 1; { ReturnCode für Speicherplatzprobleme }
-
- TYPE
- SListNodePtr = ^SListNode;
- SListNode = OBJECT (Base)
- Next : SListNodePtr;
- Data : BasePtr;
-
- CONSTRUCTOR Init;
- CONSTRUCTOR InitSet(N : SListNodePtr; D : BasePtr);
- PROCEDURE SetNext(N : SListNodePtr);
- PROCEDURE SetData(D : BasePtr);
- FUNCTION GetNextNode : SListNodePtr;
- FUNCTION GetData : BasePtr;
- DESTRUCTOR Done; VIRTUAL;
- END;
-
- DListNodePtr = ^DListNode;
- DListNode = OBJECT (SListNode)
- Prev : DListNodePtr;
- CONSTRUCTOR Init;
- CONSTRUCTOR InitSet(P, N : DListNodePtr; D : BasePtr);
- PROCEDURE SetNext(N : DListNodePtr);
- PROCEDURE SetPrev (P : DListNodePtr);
- FUNCTION GetPrev : DListNodePtr;
- FUNCTION GetNext : DListNodePtr;
- END;
-
- AbstractListPtr = ^AbstractList;
- AbstractList = OBJECT (Base)
- CONSTRUCTOR Init;
- PROCEDURE Put(D : BasePtr); VIRTUAL;
- PROCEDURE Insert(D : BasePtr); VIRTUAL;
- PROCEDURE Delete; VIRTUAL;
- PROCEDURE Clear; VIRTUAL;
- FUNCTION GetActData : BasePtr; VIRTUAL;
- FUNCTION GetNumber : LONGINT; VIRTUAL;
- DESTRUCTOR Done; VIRTUAL;
- END;
-
- DListCollectionPtr = ^DListCollection;
- DListCollection = OBJECT (AbstractList)
- FreeHeap,
- Counter : LONGINT;
- OverFlow : BOOLEAN;
- First, Last,
- Act,
- Left, Right : DListNodePtr;
- ReturnCode : BYTE;
- CONSTRUCTOR Init;
- PROCEDURE SetFreeHeap(FrH : LONGINT); VIRTUAL;
- PROCEDURE SetOverFlow(O : BOOLEAN); VIRTUAL;
- PROCEDURE Put(D : BasePtr); VIRTUAL;
- PROCEDURE Insert(D : BasePtr); VIRTUAL;
- PROCEDURE Delete; VIRTUAL;
- PROCEDURE Clear; VIRTUAL;
- PROCEDURE SetActNode(N : DListNodePtr); VIRTUAL;
- PROCEDURE SetActNodeTo(Nr : LONGINT); VIRTUAL;
- FUNCTION GetNumber : LONGINT; VIRTUAL;
- FUNCTION GetFreeHeap : LONGINT; VIRTUAL;
- FUNCTION GetOverFlow : BOOLEAN; VIRTUAL;
- FUNCTION GetReturnCode : BYTE; VIRTUAL;
- { Die Node-Methoden geben einen Zeiger }
- { auf den Knoten, die Data-Methoden auf das Daten- }
- { objekt dieser Methoden zurück. }
- FUNCTION GetActNode : DListNodePtr; VIRTUAL;
- FUNCTION GetActData : BasePtr; VIRTUAL;
- FUNCTION GetNextNode : DListNodePtr; VIRTUAL;
- FUNCTION GetNextData : BasePtr; VIRTUAL;
- FUNCTION GetPrevNode : DListNodePtr; VIRTUAL;
- FUNCTION GetPrevData : BasePtr; VIRTUAL;
- FUNCTION GetFirstNode: DListNodePtr; VIRTUAL;
- FUNCTION GetFirstData: BasePtr; VIRTUAL;
- { GetLast... beziehen sich nicht auf den Knoten Last, }
- { der nie Daten enthält, sondern auf den letzten }
- { Knoten, der noch Daten enthält, also den }
- { Vorgänger von Last. }
- FUNCTION GetLastNode : DListNodePtr; VIRTUAL;
- FUNCTION GetLastData : BasePtr; VIRTUAL;
- { Die folgenden Methoden verschieben den Knotenzeiger
- Act zum nächsten, vorhergehenden, ersten oder letzten
- Knoten und liefern einen Zeiger auf dessen Daten-
- objekt. }
- FUNCTION GotoNextData: BasePtr; VIRTUAL;
- FUNCTION GotoPrevData: BasePtr; VIRTUAL;
- FUNCTION GotoFirstData: BasePtr; VIRTUAL;
- FUNCTION GotoLastData: BasePtr; VIRTUAL;
- { IsOnLast ist TRUE, wenn Act^.Data auf das letzte
- Datenobjekt zeigt (Act^.Next=Last). }
- FUNCTION IsOnLast : BOOLEAN; VIRTUAL;
- DESTRUCTOR Done; VIRTUAL;
- END;
-
- IMPLEMENTATION
-
- CONSTRUCTOR SListNode.Init;
- BEGIN
- Next := NIL; Data := NIL;
- END;
-
- CONSTRUCTOR SListNode.InitSet(N:SListNodePtr; D:BasePtr);
- BEGIN
- Next := N; Data := D;
- END;
-
- PROCEDURE SListNode.SetNext(N : SListNodePtr);
- BEGIN
- Next := N;
- END;
-
- PROCEDURE SListNode.SetData(D : BasePtr);
- BEGIN
- Data := D;
- END;
-
- FUNCTION SListNode.GetNextNode : SListNodePtr;
- BEGIN
- GetNextNode := Next;
- END;
-
- FUNCTION SListNode.GetData : BasePtr;
- BEGIN
- GetData := Data;
- END;
-
- DESTRUCTOR SListNode.Done;
- BEGIN
- IF Data <> NIL THEN Dispose(Data, Done);
- END;
-
- CONSTRUCTOR DListNode.Init;
- BEGIN
- SListNode.Init; Prev := NIL;
- END;
-
- CONSTRUCTOR DListNode.InitSet(P,N:DListNodePtr;D:BasePtr);
- BEGIN
- Next := N; Prev := P; Data := D
- END;
-
- PROCEDURE DListNode.SetNext(N : DListNodePtr);
- BEGIN
- Next := N;
- END;
-
- PROCEDURE DListNode.SetPrev(P : DListNodePtr);
- BEGIN
- Prev := P;
- END;
-
- FUNCTION DListNode.GetPrev : DListNodePtr;
- BEGIN
- GetPrev := Prev;
- END;
-
- FUNCTION DListNode.GetNext : DListNodePtr;
- BEGIN
- GetNext := DListNodePtr(Next);
- END;
-
- CONSTRUCTOR AbstractList.Init;
- BEGIN
- Abstract('AbstractList');
- END;
-
- PROCEDURE AbstractList.Put(D : BasePtr);
- BEGIN
- Abstract('AbstractList');
- END;
-
- PROCEDURE AbstractList.Insert(D : BasePtr);
- BEGIN
- Abstract('AbstractList');
- END;
-
- PROCEDURE AbstractList.Delete;
- BEGIN
- Abstract('AbstractList');
- END;
-
- PROCEDURE AbstractList.Clear;
- BEGIN
- Abstract('AbstractList');
- END;
-
- FUNCTION AbstractList.GetActData : BasePtr;
- BEGIN
- Abstract('AbstractList');
- END;
-
- FUNCTION AbstractList.GetNumber : LONGINT;
- BEGIN
- Abstract('AbstractList');
- END;
-
- DESTRUCTOR AbstractList.Done;
- BEGIN
- Abstract('AbstractList');
- END;
-
- CONSTRUCTOR DListCollection.Init;
- BEGIN
- Counter := 0; FreeHeap := 0; OverFlow := TRUE;
- First := NIL; Last := NIL; Act := NIL;
- Left := NIL; Right := NIL; ReturnCode := DLOk;
- END;
-
- PROCEDURE DListCollection.SetFreeHeap(FrH : LONGINT);
- BEGIN
- FreeHeap := FrH;
- IF FreeHeap>MemAvail THEN FreeHeap := MemAvail;
- END;
-
- PROCEDURE DListCollection.SetOverFlow(O : BOOLEAN);
- BEGIN
- OverFlow := O;
- END;
-
- PROCEDURE DListCollection.Put(D : BasePtr);
- VAR
- P : DListNodePtr;
- BEGIN
- IF D <> NIL THEN BEGIN
- IF FreeHeap + SizeOf(D^) > MemAvail THEN BEGIN
- Dispose(D);
- ReturnCode := DLNoMem;
- END ELSE IF First = Last THEN BEGIN
- Last := New(DListNodePtr, Init);
- First := New(DListNodePtr, InitSet(NIL, Last, D));
- Last^.SetNext(NIL);
- Last^.SetPrev(First);
- Act := First; Inc(Counter);
- END ELSE BEGIN
- Left := Act;
- Right := Act^.GetNext;
- P := New(DListNodePtr, InitSet(Left, Right, D));
- Left^.SetNext(P);
- Right^.SetPrev(P);
- Act := P; Inc(Counter);
- END
- END ELSE
- ReturnCode := DLNoMem;
- END;
-
- PROCEDURE DListCollection.Insert(D : BasePtr);
- BEGIN
- Put(D);
- END;
-
- PROCEDURE DListCollection.Delete;
- VAR
- P : DListNodePtr;
- BEGIN
- IF First^.GetNext=Last THEN BEGIN
- Dispose(First, Done); { First ist gleich Act }
- First := NIL; Last := NIL; { Liste wieder leer }
- Act := NIL; Left := NIL; Right := NIL;
- Dec(Counter);
- END ELSE { sonst, wenn Liste nicht }
- IF NOT (First = Last) THEN BEGIN { leer, entfernen }
- Left := Act^.GetPrev;
- Right := Act^.GetNext;
- Left^.SetNext(Right);
- Right^.SetPrev(Left);
- P := Act;
- IF NOT (Act^.GetNext = Last) THEN Act := Right
- ELSE Act := Left;
- Dispose(P, Done);
- Dec(Counter);
- END;
- END;
-
- PROCEDURE DListCollection.Clear;
- VAR
- P : DListNodePtr;
- BEGIN
- IF NOT (First = Last) THEN BEGIN { Wenn Liste nicht }
- Act := First; { leer, dann }
- WHILE (Act <> NIL) DO BEGIN { durchlaufen }
- P := Act^.GetNext;
- Dispose(Act, Done); { und löschen }
- Act := P;
- END;
- First := NIL; Last := NIL; Act := NIL;
- Right := NIL; Left := NIL;
- END;
- END;
-
- PROCEDURE DListCollection.SetActNode(N : DListNodePtr);
- BEGIN
- IF N <> NIL THEN Act := N;
- END;
-
- PROCEDURE DListCollection.SetActNodeTo(Nr : LONGINT);
- VAR
- I : LONGINT;
- BEGIN
- IF First <> NIL THEN BEGIN
- Act := First; I := 1;
- WHILE (I < Counter) AND (I < Nr) DO BEGIN
- Act := Act^.GetNext; Inc(I);
- END;
- END;
- END;
-
- FUNCTION DListCollection.GetNumber : LONGINT;
- BEGIN
- GetNumber := Counter;
- END;
-
- FUNCTION DListCollection.GetFreeHeap : LONGINT;
- BEGIN
- GetFreeHeap := FreeHeap;
- END;
-
- FUNCTION DListCollection.GetOverFlow : BOOLEAN;
- BEGIN
- GetOverFlow := OverFlow;
- END;
-
- FUNCTION DListCollection.GetReturnCode : BYTE;
- BEGIN
- GetReturnCode := ReturnCode; ReturnCode := DLOk;
- END;
-
- FUNCTION DListCollection.GetActNode : DListNodePtr;
- BEGIN
- GetActNode := Act;
- END;
-
- FUNCTION DListCollection.GetActData : BasePtr;
- BEGIN
- GetActData := Act^.GetData;
- END;
-
- FUNCTION DListCollection.GetNextNode : DListNodePtr;
- BEGIN
- GetNextNode := Act^.GetNext;
- END;
-
- FUNCTION DListCollection.GetNextData : BasePtr;
- BEGIN
- IF Act^.GetNext <> Last THEN
- GetNextData := Act^.GetNext^.GetData
- ELSE
- GetNextData := NIL;
- END;
-
- FUNCTION DListCollection.GetPrevNode : DListNodePtr;
- BEGIN
- GetPrevNode := Act^.GetPrev;
- END;
-
- FUNCTION DListCollection.GetPrevData : BasePtr;
- BEGIN
- IF Act^.GetPrev <> NIL THEN
- GetPrevData := Act^.GetPrev^.GetData
- ELSE
- GetPrevData := NIL;
- END;
-
- FUNCTION DListCollection.GetFirstNode : DListNodePtr;
- BEGIN
- GetFirstNode := First;
- END;
-
- FUNCTION DListCollection.GetFirstData : BasePtr;
- BEGIN
- IF First <> NIL THEN GetFirstData := First^.GetData
- ELSE GetFirstData := NIL;
- END;
-
- FUNCTION DListCollection.GetLastNode : DListNodePtr;
- BEGIN
- IF Last <> NIL THEN GetLastNode := Last^.GetPrev
- ELSE GetLastNode := NIL;
- END;
-
- FUNCTION DListCollection.GetLastData : BasePtr;
- BEGIN
- IF Last <> NIL THEN
- GetLastData := Last^.GetPrev^.GetData
- ELSE
- GetLastData := NIL;
- END;
-
- FUNCTION DListCollection.GotoNextData : BasePtr;
- BEGIN
- IF NOT (First = Last) THEN BEGIN
- IF NOT (Act^.GetNext = Last) THEN BEGIN
- Act := Act^.GetNext;
- GotoNextData := Act^.GetData;
- END ELSE
- IF NOT OverFlow THEN
- GotoNextData := NIL
- ELSE BEGIN
- Act := First;
- GotoNextData := Act^.GetData;
- END
- END ELSE
- GotoNextData := NIL;
- END;
-
- FUNCTION DListCollection.GotoPrevData : BasePtr;
- BEGIN
- IF NOT (First = Last) THEN BEGIN
- IF NOT (Act^.GetPrev = NIL) THEN BEGIN
- Act := Act^.GetPrev;
- GotoPrevData := Act^.GetData;
- END ELSE
- IF NOT OverFlow THEN
- GotoPrevData := NIL
- ELSE BEGIN
- Act := Last^.GetPrev;
- GotoPrevData := Act^.GetData;
- END
- END ELSE
- GotoPrevData := NIL;
- END;
-
- FUNCTION DListCollection.GotoFirstData : BasePtr;
- BEGIN
- IF NOT (First = Last) THEN BEGIN
- Act := First;
- GotoFirstData := Act^.GetData;
- END ELSE
- GotoFirstData := NIL;
- END;
-
- FUNCTION DListCollection.GotoLastData : BasePtr;
- BEGIN
- IF NOT (First = Last) THEN BEGIN
- Act := Last;
- GotoLastData := Act^.GetData;
- END ELSE
- GotoLastData := NIL;
- END;
-
- FUNCTION DListCollection.IsOnLast : BOOLEAN;
- BEGIN
- IsOnLast := (Act^.GetNext = Last);
- END;
-
- DESTRUCTOR DListCollection.Done;
- BEGIN
- Clear;
- END;
-
- END.
- (* ------------------------------------------------------ *)
- (* Ende von LISTS.PAS *)
-