unit NTX;
interface
Type NTX_Node = array[0..511] of word;
NTX_Head = Record
Sign : Word;
Version : Word;
Root : Longint;
Next_Blk : Longint;
Item_Size : Word;
Key_Lgth : Word;
Key_Dec : Word;
Max_Keys : word;
HalfPage : word;
Key_Form : array [0..255] of char;
Unique : boolean;
Ignored : array[1..746] of byte;
end;
TNTX = object
NTX_Name : String[64];
NTX_Hdr : NTX_Head;
NTX_File : file;
NodeRec : Ntx_Node;
NodeOfs : longInt;
L,R, ItemNo : word;
Constructor Init(IName : String);
FUNCTION KeyFind(st : String) : longint;
Function KeyNext(Var Key : string) : longInt;
Destructor Done;
end;
implementation
function CharStr(Ch : Char; Len : Byte) : string;
{-Return a string of length len filled with ch}
var
S : string;
begin
if Len = 0 then
CharStr[0] := #0
else begin
S[0] := Chr(Len);
FillChar(S[1], Len, Ch);
CharStr := S;
end;
end;
Constructor TNTX.Init(IName : String);
var
ct : word;
begin
NTX_Name := IName;
assign(NTX_File,NTX_Name);
reset(NTX_File,1);
BlockRead(NTX_File,NTX_Hdr,1024,ct);
end;
Destructor TNTX.Done;
begin
Close(NTX_File);
end;
FUNCTION TNTX.KeyFind(st : String) : longint;
var
Position : Word;
Function GetKey(Item : word) : string;
Var
tempSt : string;
begin
TempSt := CharStr(' ',NTX_Hdr.Key_Lgth);
Position := NodeRec[Item];
Move(NodeRec[Round(Position/2)+4],TempSt[1],NTX_Hdr.Key_Lgth);
GetKey := TempSt;
end;
Function GetRecNo(Item : word) : longInt;
var
I : LongInt;
begin
Position := NodeRec[Item];
Move(NodeRec[Round(Position/2)+2],I,4);
GetRecNo := I;
end;
Function GetNodeOfs(Item : Word) : longint;
var
I : LongInt;
begin
Position := NodeRec[Item];
Move(NodeRec[Round(Position/2)],I,4);
GetNodeOfs := I;
end;
begin
KeyFind := 0;
NodeOfs := NTX_Hdr.Root;
While NodeOfs > 0 do
begin
Seek(NTX_File,NodeOfs);
BlockRead(NTX_File,NodeRec,1024);
if NodeRec[0] > 0 then
begin
L := 1;
R := NodeRec[0];
repeat
if Ntx_hdr.Unique then
ItemNo := (L+R) shr 1
else
ItemNo := L;
if St = GetKey(ItemNo) then
begin
if Ntx_Hdr.Unique then
begin
KeyFind := GetRecNo(ItemNo);
Exit;
end
else
begin
if GetNodeOfs(ItemNo) > 0 then
break
else
begin
KeyFind := GetRecNo(ItemNo);
Exit;
end;
end
end
else
if St < GetKey(ItemNo) then
R := Pred(ItemNo)
else
L := Succ(ItemNo)
until R < L;
NodeOfs := GetNodeOfs(ItemNo);
end
else
NodeOfs := 0;
end;
end;
Function Tntx.KeyNext(Var Key : string) : longInt;
var
Position : Word;
Function GetKey(Item : word) : string;
Var
tempSt : string;
begin
TempSt := CharStr(' ',NTX_Hdr.Key_Lgth);
Position := NodeRec[Item];
Move(NodeRec[Round(Position/2)+4],TempSt[1],NTX_Hdr.Key_Lgth);
GetKey := TempSt;
end;
Function GetRecNo(Item : word) : longInt;
var
I : LongInt;
begin
Position := NodeRec[Item];
Move(NodeRec[Round(Position/2)+2],I,4);
GetRecNo := I;
end;
Function GetNodeOfs(Item : Word) : longint;
var
I : LongInt;
begin
Position := NodeRec[Item];
Move(NodeRec[Round(Position/2)],I,4);
GetNodeOfs := I;
end;
begin
KeyNext := 0;
if ((NodeOfs = FileSize(Ntx_File) - 1024 ) and (L = NodeRec[0])) then
Exit;
if L = NodeRec[0] then
begin
repeat
NodeOfs := NodeOfs + 1024;
if (NodeOfs > FileSize(Ntx_File) - 1024 ) then
Exit;
Seek(NTX_File,NodeOfs);
BlockRead(NTX_File,NodeRec,1024);
until NodeRec[0] > 0;
L := 0;
end;
Inc(L);
ItemNo := L;
Key := GetKey(ItemNo);
KeyNext := GetRecNo(ItemNo);
end;
end.
|