📄 ezindygis.pas
字号:
resourcestring
SEz_GisIndyVersion = 'TEzIndyClientGIS Version 1.95 (Ene, 2003)';
SUnassignedTCPCLient = 'Indy TIdTCPClient not assigned';
Type
{ Item management for TMWSparseList }
PMWItem = ^TMWItem;
TMWItem = Record
LocalRecno: Integer; // the record number in the local storage
//DataExists: Boolean; // exists database information ?
End;
{ Exception classes }
EAggregateSparseListError = Class( Exception );
Function NewMWItem( ALocalRecno: Integer; ADataExists: Boolean ): PMWItem;
Begin
New( Result );
Result^.LocalRecno := ALocalRecno;
//Result^.DataExists := ADataExists;
End;
Procedure DisposeMWItem( P: PMWItem );
Begin
If P=Nil then Exit;
Dispose( P );
End;
{ TSparsePointerArray }
Const
SPAIndexMask: Array[TSPAQuantum] Of Byte = ( 15, 255 );
SPASecShift: Array[TSPAQuantum] Of Byte = ( 4, 8 );
Function ExpandDir( secDir: PSecDir; Var slotsInDir: Word;
newSlots: Word ): PSecDir;
Begin
Result := secDir;
ReallocMem( Result, newSlots * SizeOf( Pointer ) );
FillChar( Result^[slotsInDir], ( newSlots - slotsInDir ) * SizeOf( Pointer ), 0 );
slotsInDir := newSlots;
End;
Function MakeSec( SecIndex: Integer; SectionSize: Word ): Pointer;
Var
SecP: Pointer;
Size: Word;
Begin
Size := SectionSize * SizeOf( Pointer );
GetMem( secP, size );
FillChar( secP^, size, 0 );
MakeSec := SecP
End;
Constructor TSparsePointerArray.Create( Quantum: TSPAQuantum );
Begin
SecDir := Nil;
SlotsInDir := 0;
FHighBound := -1;
FSectionSize := Word( SPAIndexMask[Quantum] ) + 1;
IndexMask := Word( SPAIndexMask[Quantum] );
SecShift := Word( SPASecShift[Quantum] );
CachedIndex := -1
End;
Destructor TSparsePointerArray.Destroy;
Var
i: Integer;
size: Word;
Begin
i := 0;
size := FSectionSize * SizeOf( Pointer );
While i < slotsInDir Do
Begin
If secDir^[i] <> Nil Then
FreeMem( secDir^[i], size );
Inc( i )
End;
If secDir <> Nil Then
FreeMem( secDir, slotsInDir * SizeOf( Pointer ) );
End;
Function TSparsePointerArray.GetAt( Index: Integer ): Pointer;
Var
byteP: PChar;
secIndex: Cardinal;
Begin
If Index = cachedIndex Then
Result := cachedPointer
Else
Begin
secIndex := Index Shr secShift;
If secIndex >= slotsInDir Then
byteP := Nil
Else
Begin
byteP := secDir^[secIndex];
If byteP <> Nil Then
Begin
Inc( byteP, ( Index And indexMask ) * SizeOf( Pointer ) );
End
End;
If byteP = Nil Then
Result := Nil
Else
Result := PPointer( byteP )^;
cachedIndex := Index;
cachedPointer := Result
End
End;
Function TSparsePointerArray.MakeAt( Index: Integer ): PPointer;
Var
dirP: PSecDir;
p: Pointer;
byteP: PChar;
secIndex: Word;
Begin
secIndex := Index Shr secShift; { Unsigned shift }
If secIndex >= slotsInDir Then
dirP := expandDir( secDir, slotsInDir, secIndex + 1 )
Else
dirP := secDir;
secDir := dirP;
p := dirP^[secIndex];
If p = Nil Then
Begin
p := makeSec( secIndex, FSectionSize );
dirP^[secIndex] := p
End;
byteP := p;
Inc( byteP, ( Index And indexMask ) * SizeOf( Pointer ) );
If Index > FHighBound Then
FHighBound := Index;
Result := PPointer( byteP );
cachedIndex := -1
End;
Procedure TSparsePointerArray.PutAt( Index: Integer; Item: Pointer );
Begin
If ( Item <> Nil ) Or ( GetAt( Index ) <> Nil ) Then
Begin
MakeAt( Index )^ := Item;
If Item = Nil Then
ResetHighBound
End
End;
Function TSparsePointerArray.ForAll( ApplyFunction: Pointer {TSPAApply} ):
Integer;
Var
itemP: PChar;
item: Pointer;
i, callerBP: Cardinal;
j, index: Integer;
Begin
Result := 0;
i := 0;
Asm
mov eax,[ebp]
mov callerBP,eax
End;
While ( i < slotsInDir ) And ( Result = 0 ) Do
Begin
itemP := secDir^[i];
If itemP <> Nil Then
Begin
j := 0;
index := i Shl SecShift;
While ( j < FSectionSize ) And ( Result = 0 ) Do
Begin
item := PPointer( itemP )^;
If item <> Nil Then
{ ret := ApplyFunction(index, item.Ptr); }
Asm
mov eax,index
mov edx,item
push callerBP
call ApplyFunction
pop ecx
mov @Result,eax
End;
Inc( itemP, SizeOf( Pointer ) );
Inc( j );
Inc( index )
End
End;
Inc( i )
End;
End;
Procedure TSparsePointerArray.ResetHighBound;
Var
NewHighBound: Integer;
Function Detector( TheIndex: Integer; TheItem: Pointer ): Integer; Far;
Begin
If TheIndex > FHighBound Then
Result := 1
Else
Begin
Result := 0;
If TheItem <> Nil Then
NewHighBound := TheIndex
End
End;
Begin
NewHighBound := -1;
ForAll( @Detector );
FHighBound := NewHighBound
End;
{ TSparseList }
Constructor TSparseList.Create( Quantum: TSPAQuantum );
Begin
NewList( Quantum )
End;
Destructor TSparseList.Destroy;
Begin
If FList <> Nil Then
FList.Destroy
End;
Function TSparseList.Add( Item: Pointer ): Integer;
Begin
Result := FCount;
FList[Result] := Item;
Inc( FCount )
End;
Procedure TSparseList.Clear;
Begin
FList.Destroy;
NewList( FQuantum );
FCount := 0
End;
Procedure TSparseList.Delete( Index: Integer );
Var
I: Integer;
Begin
If ( Index < 0 ) Or ( Index >= FCount ) Then
Exit;
For I := Index To FCount - 1 Do
FList[I] := FList[I + 1];
FList[FCount] := Nil;
Dec( FCount );
End;
Procedure TSparseList.Error;
Begin
Raise EListError.Create( 'List Index Error!' )
End;
Procedure TSparseList.Exchange( Index1, Index2: Integer );
Var
temp: Pointer;
Begin
temp := Get( Index1 );
Put( Index1, Get( Index2 ) );
Put( Index2, temp );
End;
Function TSparseList.First: Pointer;
Begin
Result := Get( 0 )
End;
{ Jump to TSparsePointerArray.ForAll so that it looks like it was called
from our caller, so that the BP trick works. }
Function TSparseList.ForAll( ApplyFunction: Pointer {TSPAApply} ): Integer; Assembler;
Asm
MOV EAX,[EAX].TSparseList.FList
JMP TSparsePointerArray.ForAll
End;
Function TSparseList.Get( Index: Integer ): Pointer;
Begin
If Index < 0 Then
Error;
Result := FList[Index]
End;
Function TSparseList.IndexOf( Item: Pointer ): Integer;
Var
MaxIndex, Index: Integer;
Function IsTheItem( TheIndex: Integer; TheItem: Pointer ): Integer; Far;
Begin
If TheIndex > MaxIndex Then
Result := -1 { Bail out }
Else If TheItem <> Item Then
Result := 0
Else
Begin
Result := 1; { Found it, stop traversal }
Index := TheIndex
End
End;
Begin
Index := -1;
MaxIndex := FList.HighBound;
FList.ForAll( @IsTheItem );
Result := Index
End;
Procedure TSparseList.Insert( Index: Integer; Item: Pointer );
Var
i: Integer;
Begin
If Index < 0 Then
Error;
I := FCount;
While I > Index Do
Begin
FList[i] := FList[i - 1];
Dec( i )
End;
FList[Index] := Item;
If Index > FCount Then
FCount := Index;
Inc( FCount )
End;
Function TSparseList.Last: Pointer;
Begin
Result := Get( FCount - 1 );
End;
Procedure TSparseList.Move( CurIndex, NewIndex: Integer );
Var
Item: Pointer;
Begin
If CurIndex <> NewIndex Then
Begin
Item := Get( CurIndex );
Delete( CurIndex );
Insert( NewIndex, Item );
End;
End;
Procedure TSparseList.NewList( Quantum: TSPAQuantum );
Begin
FQuantum := Quantum;
FList := TSparsePointerArray.Create( Quantum )
End;
Procedure TSparseList.Pack;
Var
i: Integer;
Begin
For i := FCount - 1 Downto 0 Do
If Items[i] = Nil Then
Delete( i )
End;
Procedure TSparseList.Put( Index: Integer; Item: Pointer );
Begin
If Index < 0 Then Error;
FList[Index] := Item;
FCount := FList.HighBound + 1
End;
Function TSparseList.Remove( Item: Pointer ): Integer;
Begin
Result := IndexOf( Item );
If Result <> -1 Then
Delete( Result )
End;
{ TMWSparseList }
Constructor TMWSparseList.Create( Capacity: Integer );
Var
quantum: TSPAQuantum;
Begin
If Capacity > 256 Then
quantum := SPALarge
Else
quantum := SPASmall;
FList := TSparseList.Create( Quantum );
End;
Destructor TMWSparseList.Destroy;
Begin
If FList <> Nil Then
Begin
Clear;
FList.Destroy
End
End;
Function TMWSparseList.HasData( Index: Integer ): Boolean;
Begin
Result:= FList[Index] <> Nil;
End;
Function TMWSparseList.Get( Index: Integer ): Integer;
Var
p: PMWItem;
Begin
p := PMWItem( FList[Index] );
If p = Nil Then
Result := 0
Else
Result := p^.LocalRecno;
End;
{Function TMWSparseList.GetDataExists( Index: Integer ): Boolean;
Var
p: PMWItem;
Begin
p := PMWItem( FList[Index] );
If p = Nil Then
Result := False
Else
Result := p^.DataExists;
End; }
Procedure TMWSparseList.Put( Index: Integer; Value: Integer );
Var
p: PMWItem;
Begin
p := PMWItem( FList[Index] );
If p = Nil Then
FList[Index] := NewMWItem( Value, False )
Else
p^.LocalRecno := Value;
End;
{Procedure TMWSparseList.PutDataExists( Index: Integer; Value: Boolean );
Var
p: PMWItem;
Begin
p := PMWItem( FList[Index] );
If p = Nil Then
FList[Index] := NewMWItem( 0, Value )
Else
p^.DataExists := Value;
End; }
Procedure TMWSparseList.Error;
Begin
Raise EAggregateSparseListError.Create( 'Put Counts Error!' )
End;
Procedure TMWSparseList.Delete( Index: Integer );
Var
p: PMWItem;
Begin
p := PMWItem( FList[Index] );
If p <> Nil Then
DisposeMWItem( p );
FList.Delete( Index );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -