home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
375.lha
/
IncrStorageManager_v1.0
/
DynItem.mod
< prev
next >
Wrap
Text File
|
1990-05-02
|
5KB
|
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.