home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1990-05-02 | 5.3 KB | 246 lines |
- IMPLEMENTATION MODULE DynItem;
-
- (* Product: Incremental Storage Manager
-
- Version: 1.0
-
- Author:
- Daniel B. Hankins
- 143 Montgomery Street
- Poughkeepsie, NY 12601
- dan-hankins@cup.portal.com
-
- Creation Date: 1989
-
- Release Date: November 21, 1989
-
- Notice of Intellectual Property:
- This material is *NOT COPYRIGHTED*. By this notice, I hereby place
- this program and all its parts in the public domain, under the definitions
- and restrictions of United States law.
-
- History of Revisions:
- None yet.
- *)
-
- FROM SYSTEM IMPORT ADDRESS, TSIZE, WORD;
- FROM WordAlign IMPORT WordAlign;
-
- IMPORT DynamicItem;
- IMPORT DynItemList;
-
- TYPE
- Object = POINTER TO Item;
- WordPtr = POINTER TO WORD;
-
- Item = RECORD
- NextLower, NextHigher: Object;
- Size, RefCount: LONGCARD;
- Term: DynamicItem.TermProc;
- List: DynItemList.Object;
- Handle: DynamicItem.Object;
- END;
-
- VAR
- ItemTypeSize: LONGCARD;
-
-
- PROCEDURE New(Size: LONGCARD; TermIt: DynamicItem.TermProc): Object;
- VAR
- NewObject: Object;
- TotalSize: LONGCARD;
- List: DynItemList.Object;
- BEGIN
- (* New(Size, Object) <-
- WordAlign(Size, Size),
- Plus(Size, ItemTypeSize, TotalSize),
- DynItemList.GetListWithSpace(TotalSize, List),
- New2(TotalSize, List, Object).
- New2(TotalSize, List, Object) <-
- DynItemList.Nil(List),
- SetValue(Object, NIL).
- New2(TotalSize, List, Object) <-
- DynItemList.GetChunk(List, TotalSize, NewObject),
- SetValue(NewObject^.Size, TotalSize),
- SetValue(NewObject^.RefCount, 1),
- SetValue(NewObject^.List, List),
- SetValue(NewObject^.Handle, NIL),
- DynItemList.LinkItem(List, NewObject),
- SetValue(Object, NewObject).
- *)
- Size := WordAlign(Size);
- TotalSize := Size + ItemTypeSize;
- List := DynItemList.GetListWithSpace(TotalSize);
-
- IF DynItemList.Nil(List) THEN
- RETURN(NIL);
- END;
-
- NewObject := DynItemList.GetChunk(List, TotalSize);
- NewObject^.Size := TotalSize;
- NewObject^.RefCount := 1;
- NewObject^.List := List;
- NewObject^.Term := TermIt;
- DynItemList.LinkItem(List, NewObject);
-
- RETURN NewObject;
- END New;
-
-
- PROCEDURE Init(DObject: Object; InitIt: DynamicItem.InitProc);
- BEGIN
- InitIt(Access(DObject));
- END Init;
-
-
- PROCEDURE SetHandle(DObject: Object; Handle: DynamicItem.Object);
- BEGIN
- DObject^.Handle := Handle;
- END SetHandle;
-
-
- PROCEDURE Dispose(DObject: Object): BOOLEAN;
- BEGIN
- DObject^.RefCount := DObject^.RefCount - 1;
- IF DObject^.RefCount = 0 THEN
- DObject^.Term(Access(DObject));
- Kill(DObject);
- RETURN TRUE;
- END;
- RETURN FALSE;
- END Dispose;
-
-
- PROCEDURE Kill(DObject: Object);
- BEGIN
- DynItemList.UnlinkItem(DObject^.List, DObject);
- END Kill;
-
-
- PROCEDURE Ref(DObject: Object);
- BEGIN
- DObject^.RefCount := DObject^.RefCount + 1;
- END Ref;
-
-
- PROCEDURE Access(DObject: Object): ADDRESS;
- BEGIN
- RETURN ADDRESS(LONGCARD(DObject) + ItemTypeSize);
- END Access;
-
-
- PROCEDURE GetList(DObject: Object): DynItemList.Object;
- BEGIN
- RETURN DObject^.List;
- END GetList;
-
-
- PROCEDURE Percolate(DObject: Object);
- BEGIN
- DynItemList.Percolate(DObject^.List);
- END Percolate;
-
-
- PROCEDURE LinkAfter(DObjectNew, DObjectOld: Object);
- BEGIN
- IF DObjectOld <> NIL THEN
- DObjectNew^.NextLower := DObjectOld;
- DObjectNew^.NextHigher := DObjectOld^.NextHigher;
- DObjectNew^.NextLower^.NextHigher := DObjectNew;
- IF DObjectNew^.NextHigher <> NIL THEN
- DObjectNew^.NextHigher^.NextLower := DObjectNew;
- END;
- ELSE
- DObjectNew^.NextLower := NIL;
- DObjectNew^.NextHigher := NIL;
- END;
- END LinkAfter;
-
-
- PROCEDURE Unlink(DObject: Object);
- BEGIN
- IF DObject^.NextLower <> NIL THEN
- DObject^.NextLower^.NextHigher := DObject^.NextHigher;
- END;
- IF DObject^.NextHigher <> NIL THEN
- DObject^.NextHigher^.NextLower := DObject^.NextLower;
- END;
- END Unlink;
-
-
- PROCEDURE GetPrev(DObject: Object): Object;
- BEGIN
- RETURN DObject^.NextLower;
- END GetPrev;
-
-
- PROCEDURE GetNext(DObject: Object): Object;
- BEGIN
- RETURN DObject^.NextHigher;
- END GetNext;
-
-
- PROCEDURE MoveDown(DObject: Object): Object;
- VAR
- DestinationAddr: ADDRESS;
- SourceWord, DestinationWord: WordPtr;
- BytesToMove: LONGCARD;
- BEGIN
- IF DObject^.NextLower = NIL THEN
- DestinationAddr := DynItemList.NextAddr(DObject^.List);
- ELSE
- DestinationAddr := NextAddr(DObject^.NextLower);
- END;
-
- DynamicItem.Set(DObject^.Handle, DestinationAddr);
-
- BytesToMove := DObject^.Size;
- SourceWord := ADDRESS(DObject);
- DestinationWord := DestinationAddr;
-
- LOOP
- IF BytesToMove = 0 THEN
- EXIT;
- END;
- DestinationWord^ := SourceWord^;
- DestinationWord := ADDRESS(LONGCARD(DestinationWord) + 2);
- SourceWord := ADDRESS(LONGCARD(SourceWord) + 2);
- BytesToMove := BytesToMove - 2;
- END;
-
- DObject := DestinationAddr;
-
- IF DObject^.NextLower <> NIL THEN
- DObject^.NextLower^.NextHigher := DObject;
- END;
-
- IF DObject^.NextHigher <> NIL THEN
- DObject^.NextHigher^.NextLower := DObject;
- END;
-
- RETURN Object(DestinationAddr);
- END MoveDown;
-
-
- PROCEDURE NextAddr(DObject: Object): ADDRESS;
- BEGIN
- RETURN ADDRESS(LONGCARD(DObject) + DObject^.Size);
- END NextAddr;
-
-
- PROCEDURE NilObject(): Object;
- BEGIN
- RETURN NIL;
- END NilObject;
-
-
- PROCEDURE Nil(DObject: Object): BOOLEAN;
- BEGIN
- RETURN (DObject = NIL);
- END Nil;
-
-
- BEGIN
- ItemTypeSize := WordAlign(TSIZE(Item));
- END DynItem.
-