Q: How can I use huge arrays? (i.e. > 64K)
A: Unit provides support for arrays and huge (>64K) arrays of data. Each item size stored in the array must be a multiple of 2 (2,4,8,16,32..) in order to work using the huge arrays and matrices. This is needed so that you don't straddle the segment boundaries.
To use these objects merely create the object using the appropriate constructor. The object will be created with it's data initialized to zeros (GMEM_ZEROINIT). to access an element of the object use the AT() method. This will return you a pointer to the element you specified. for huge objects it will do the segment math correctly. Then you can dereference the pointer and work with the data.
This unit merely simplifies the use of huge type arrays and matrices. It does not do much more.
Unit Arrays;
{Author ROBERT WARREN CIS ID 70303,537}
interface
uses WObjects,WinTypes,WinProcs;
type
PArray = ^TArray;
TArray = object(TObject)
Handle: THandle;
ItemSize: Word;
Limit: LongInt;
Address: Pointer;
constructor Init(aItemSize: Word; aLimit: LongInt);
destructor done; virtual;
function At(index: LongInt): Pointer; virtual;
end;
PMatrix = ^TMatrix;
TMatrix = object(TObject)
Handle: THandle;
ItemSize: Word;
Rows,Cols: LongInt;
Address: Pointer;
constructor Init(aItemSize: Word; aRows,aCols: LongInt);
destructor done; virtual;
function At(aRow,aCol: LongInt): Pointer; virtual;
end;
PHugeMatrix = ^THugeMatrix;
THugeMatrix = object(TMatrix)
SegIncr : Word;
constructor Init(aItemSize: Word; aRows,aCols: LongInt);
function At(aRow,aCol: LongInt): Pointer; virtual;
end;
PHugeArray = ^THugeArray;
THugeArray = object(TArray)
SegIncr: Word;
constructor Init(aItemSize: Word; aLimit: LongInt);
function At(index: LongInt): Pointer; virtual;
end;
function NewArray(aItemSize: Word; aLimit: LongInt): PArray;
function NewMatrix(aItemSize: Word; aRows,aCols: LongInt): PMatrix;
implementation
{
returns a pointer to an Array if small enough otherwise a HugeArray
}
function NewArray(aItemSize: Word; aLimit: LongInt): PArray;
var
TempArrayPtr: PArray;
begin
TempArrayPtr:=New(PArray,Init(aItemSize,aLimit));
if TempArrayPtr = nil then
TempArrayPtr:=New(PHugeArray,Init(aItemSize,aLimit));
NewArray:=TempArrayPtr;
end;
{
returns a pointer to an Matrix if small enough otherwise a HugeMatrix
}
function NewMatrix(aItemSize: Word; aRows,aCols: LongInt): PMatrix;
var
TempMatrixPtr: PMatrix;
begin
TempMatrixPtr:=New(PMatrix,Init(aItemSize,aRows,aCols));
if TempMatrixPtr = nil then
TempMatrixPtr:=New(PHugeMatrix,Init(aItemSize,aRows,aCols));
NewMatrix:=TempMatrixPtr;
end;
procedure AHIncr; far; external 'KERNEL' index 114;
{ ----------------------------------------------
TMatrix
---------------------------------------------- }
constructor TMatrix.Init(aItemSize: Word; aRows,aCols: LongInt);
var
InitSize: LongInt;
begin
TObject.Init;
Rows:=aRows;
Cols:=aCols;
ItemSize:=aItemSize;
InitSize:=LongInt(ItemSize * Rows * Cols);
if InitSize > $FFFF then fail;
Handle:=GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT,ItemSize * Rows * Cols);
if handle = 0 then fail;
Address:=GlobalLock(Handle);
end;
destructor TMatrix.done;
begin
GlobalUnlock(Handle);
GlobalFree(Handle);
end;
function TMatrix.At(aRow,aCol: LongInt): Pointer;
var
pos: Word;
begin
pos:=(aRow * Cols * ItemSize) + (ACol * ItemSize);
At:=Pointer(MakeLong(pos,HiWord(LongInt(Address))));
end;
{ ----------------------------------------------
THugeMatrix
---------------------------------------------- }
constructor THugeMatrix.Init(aItemSize: Word; aRows,aCols: LongInt);
begin
TObject.Init;
Rows:=aRows;
Cols:=aCols;
ItemSize:=aItemSize;
Handle:=GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT,LongInt(ItemSize * Rows * Cols));
if handle = 0 then fail;
Address:=GlobalLock(Handle);
SegIncr:=Ofs(AHIncr);
end;
function THugeMatrix.At(aRow,aCol: LongInt): Pointer;
var
Segs,Offs: Word;
Pos: LongInt;
begin
pos:=(aRow * Cols * ItemSize) + (ACol * ItemSize);
Segs:=Pos div $FFFF;
Offs:=Pos mod $FFFF;
At:=Pointer(MakeLong(Offs,((Segs*SegIncr)+(HiWord(LongInt(Address))))));
end;
{ ----------------------------------------------
TArray
---------------------------------------------- }
constructor TArray.Init(aItemSize: Word; aLimit: LongInt);
var
InitSize: LongInt;
begin
TObject.Init;
ItemSize:=aItemSize;
Limit:=aLimit;
InitSize:=ItemSize * Limit;
if InitSize > $FFFF then fail;
Handle:=GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT,InitSize);
if handle = 0 then fail;
Address:=GlobalLock(Handle);
end;
destructor TArray.Done;
begin
TObject.Done;
GlobalUnlock(Handle);
GlobalFree(Handle);
end;
function TArray.At(index: LongInt): Pointer;
begin
At:=Pointer(LongInt(ItemSize * index) + LongInt(Address));
end;
{ ----------------------------------------------
THugeArray
---------------------------------------------- }
constructor THugeArray.Init(aItemSize: Word; aLimit: LongInt);
begin
TObject.Init;
ItemSize:=aItemSize;
Limit:=aLimit;
Handle:=GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT,ItemSize * Limit);
if handle = 0 then fail;
Address:=GlobalLock(Handle);
SegIncr:=Ofs(AHIncr);
end;
function THugeArray.At(index: LongInt): Pointer;
var
Segs,Offs: Word;
Pos: LongInt;
begin
Pos:=Index * ItemSize;
Segs:=Pos div $FFFF;
Offs:=Pos mod $FFFF;
At:=Pointer(MakeLong(Offs,((Segs*SegIncr)+(HiWord(LongInt(Address))))));
end;
begin
end.