首页  编辑  

一个操作矩阵的类

Tags: /超级猛料/Language.Object Pascal/数组、集合和记录、枚举类型/   Date Created:

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.