home *** CD-ROM | disk | FTP | other *** search
- unit GS_DB_IX;
-
- { GS_DB_IX Copyright (c) Richard F. Griffin
-
- 8 January 1990
-
- 102 Molded Stone Pl
- Warner Robins, GA 31088
-
- -------------------------------------------------------------
- This unit handles the objects for all dBase III index (.NDX)
- operations.
-
- }
-
- {$N+,E+}
- interface
- uses dos;
-
- type
-
- GS_Indx_Head = Record
- Root : Longint;
- Next_Blk : Longint;
- Unknwn1 : Longint;
- Key_Lgth : Integer;
- Max_Keys : Integer;
- Data_Typ : Integer;
- Entry_Sz : Integer;
- Unknwn2 : Longint;
- Key_Form : array [0..487] of char;
- end;
-
- GS_Indx_Data = Record
- Entry_Ct : Integer;
- Unknwn1 : Integer;
- Data_Ary : array [0..507] of byte;
- end;
-
- GS_Indx_EntPtr = ^GS_Indx_Etry;
-
- GS_Indx_Etry = Record
- Block_Ax : Longint;
- Recrd_Ax : Longint;
- case Integer of
- 0 : (Char_Fld : array [1..255] of char);
- 1 : (Numb_Fld : double);
- end;
-
- GS_Indx_Tabl = Record
- Page_No : Longint;
- Etry_No : integer;
- Last_One : integer;
- Node_Pag : Boolean;
- end;
-
- GS_Indx_LPtr = ^GS_dBase_IX;
-
- GS_dBase_IX = object
- Ndx_Name : String[64];
- Ndx_Hdr : GS_Indx_Head;
- Ndx_File : file;
- Ndx_Tabl : array [1..25] of GS_Indx_Tabl;
- Ndx_Lvl : integer;
- Ndx_Data : GS_Indx_Data;
- Ndx_Pntr : GS_Indx_EntPtr;
- PROCEDURE Init(IName : String);
- FUNCTION KeyEOF : boolean;
- FUNCTION KeyRead(a : LongInt) : longint;
- FUNCTION KeyFind(st : String) : longint;
- end;
-
- implementation
-
- const
- Next_Record = -1;
- Prev_Record = -2;
- Top_Record = -3;
- Bttm_Record = -4;
-
- procedure GS_dBase_IX.Init(IName : String);
- var
- ct : word;
- begin
- Ndx_Name := IName + '.NDX';
- assign(Ndx_File,Ndx_Name);
- reset(Ndx_File,1);
- BlockRead(Ndx_File,Ndx_Hdr,512,ct);
- Ndx_Lvl := 0;
- end;
-
- function GS_dBase_IX.KeyEOF : boolean;
- var
- eflg : boolean;
- i : integer;
- begin
- eflg := true;
- if Ndx_Lvl = 0 then eflg := false
- else
- for i := 1 to Ndx_Lvl do
- if Ndx_Tabl[i].Etry_No < Ndx_Tabl[i].Last_One then
- eflg := false;
- KeyEOF := eflg;
- end;
-
-
- FUNCTION GS_dBase_IX.KeyRead(a : longint) : longint;
- var
- RNum : Longint;
- Result : Integer;
- RPag : Longint;
- N_L_Hold : Integer;
- ct : Integer;
-
- function Last_Entry(ix : longint) : boolean;
- begin
- if Ndx_Tabl[ix].Etry_No = Ndx_Tabl[ix].Last_One then
- Last_Entry := true else Last_entry := false;
- end;
-
-
- procedure Get_Next_RecPage;
- begin
- while RPag <> 0 do
- begin
- Seek(Ndx_File,RPag*512);
- BlockRead(Ndx_File,Ndx_Data,512,ct);
- inc(Ndx_Lvl);
- Ndx_Tabl[Ndx_Lvl].Page_No := RPag;
- Ndx_Tabl[Ndx_Lvl].Etry_No := 1;
- Ndx_Tabl[Ndx_Lvl].Last_One := Ndx_Data.Entry_Ct+1;
- Ndx_Tabl[Ndx_Lvl].Node_Pag := true;
- Ndx_Pntr := Addr(Ndx_Data.Data_Ary);
- RPag := Ndx_Pntr^.Block_Ax;
- end;
- Ndx_Tabl[Ndx_Lvl].Node_Pag := false;
- dec(Ndx_Tabl[Ndx_Lvl].Last_One);
- RNum := Ndx_Pntr^.Recrd_Ax;
- end;
-
- procedure Get_Prev_RecPage;
- begin
- while RPag <> 0 do
- begin
- Seek(Ndx_File,RPag*512);
- BlockRead(Ndx_File,Ndx_Data,512,ct);
- inc(Ndx_Lvl);
- Ndx_Tabl[Ndx_Lvl].Page_No := RPag;
- Ndx_Tabl[Ndx_Lvl].Etry_No := Ndx_Data.Entry_Ct+1;
- Ndx_Tabl[Ndx_Lvl].Last_One := Ndx_Data.Entry_Ct+1;
- Ndx_Tabl[Ndx_Lvl].Node_Pag := true;
- Ndx_Pntr :=
- Addr(Ndx_Data.Data_Ary[(
- (Ndx_Data.Entry_Ct)*Ndx_Hdr.Entry_Sz)]);
- RPag := Ndx_Pntr^.Block_Ax;
- end;
- Ndx_Pntr :=
- Addr(Ndx_Data.Data_Ary[(
- (Ndx_Data.Entry_Ct-1)*Ndx_Hdr.Entry_Sz)]);
- Ndx_Tabl[Ndx_Lvl].Etry_No := Ndx_Data.Entry_Ct;
- Ndx_Tabl[Ndx_Lvl].Node_Pag := false;
- dec(Ndx_Tabl[Ndx_Lvl].Last_One);
- RNum := Ndx_Pntr^.Recrd_Ax;
- end;
-
- { Start of KeyRead }
-
- begin
- RNum := a;
- if ((a = Next_Record) or (a = Prev_Record)) and
- (Ndx_Lvl = 0) then RNum := Top_Record;
- case RNum of
- Next_Record : begin
- N_L_Hold := Ndx_Lvl;
- if Last_Entry(Ndx_Lvl) then
- begin
- while (Last_Entry(Ndx_Lvl)) and (Ndx_Lvl > 0) do
- dec(Ndx_Lvl);
- if Ndx_Lvl = 0 then
- begin
- Ndx_Lvl := N_L_Hold;
- end else
- begin
- RPag := Ndx_Tabl[Ndx_Lvl].Page_No;
- Seek(Ndx_File,RPag*512);
- inc(Ndx_Tabl[Ndx_Lvl].Etry_No);
- BlockRead(Ndx_File,Ndx_Data,512,ct);
- Ndx_Pntr :=
- Addr(Ndx_Data.Data_Ary[(
- (Ndx_Tabl[Ndx_Lvl].Etry_No - 1) *
- Ndx_Hdr.Entry_Sz)]);
- RPag := Ndx_Pntr^.Block_Ax;
- Get_Next_RecPage;
- end;
- dec(Ndx_Tabl[Ndx_Lvl].Etry_No);
- end;
- inc(Ndx_Tabl[Ndx_Lvl].Etry_No);
- Ndx_Pntr :=
- Addr(Ndx_Data.Data_Ary[(
- (Ndx_Tabl[Ndx_Lvl].Etry_No - 1) *
- Ndx_Hdr.Entry_Sz)]);
- RNum := Ndx_Pntr^.Recrd_Ax;
- end;
- Prev_Record : begin
- N_L_Hold := Ndx_Lvl;
- if Ndx_Tabl[Ndx_Lvl].Etry_No = 1 then
- begin
- while (Ndx_Tabl[Ndx_Lvl].Etry_No = 1) and
- (Ndx_Lvl > 0) do
- dec(Ndx_Lvl);
- if Ndx_Lvl = 0 then
- begin
- Ndx_Lvl := N_L_Hold ;
- end else
- begin
- RPag := Ndx_Tabl[Ndx_Lvl].Page_No;
- Seek(Ndx_File,RPag*512);
- dec(Ndx_Tabl[Ndx_Lvl].Etry_No);
- BlockRead(Ndx_File,Ndx_Data,512,ct);
- Ndx_Pntr :=
- Addr(Ndx_Data.Data_Ary[(
- (Ndx_Tabl[Ndx_Lvl].Etry_No - 1) *
- Ndx_Hdr.Entry_Sz)]);
- RPag := Ndx_Pntr^.Block_Ax;
- Get_Prev_RecPage;
- end;
- inc(Ndx_Tabl[Ndx_Lvl].Etry_No);
- end;
- dec(Ndx_Tabl[Ndx_Lvl].Etry_No);
- Ndx_Pntr :=
- Addr(Ndx_Data.Data_Ary[(
- (Ndx_Tabl[Ndx_Lvl].Etry_No - 1) *
- Ndx_Hdr.Entry_Sz)]);
- RNum := Ndx_Pntr^.Recrd_Ax;
- end;
- Top_Record : begin
- Ndx_Lvl := 0;
- RPag := Ndx_Hdr.Root;
- Get_Next_RecPage;
- end;
- Bttm_Record : begin
- Ndx_Lvl := 0;
- RPag := Ndx_Hdr.Root;
- Get_Prev_RecPage;
- end;
- end;
- KeyRead := RNum;
- end;
-
-
- function GS_dBase_IX.KeyFind(st : string) : LongInt;
- var
- long_st : string[255];
- key_st : string[255];
- m_num : double;
- st_Lth : integer;
- RPag : LongInt;
- i : integer;
- rl : integer;
- ct : integer;
- Less_Than : boolean;
- begin
- FillChar(long_st[1], 255, ' ');
- long_st := st;
- st_Lth := Ndx_Hdr.Key_Lgth;
- long_st[0] := chr(st_Lth);
- if Ndx_Hdr.Data_Typ <> 0 then val(st,m_num,rl);
- Ndx_Lvl := 0;
- RPag := Ndx_Hdr.Root;
- while RPag <> 0 do
- begin
- Seek(Ndx_File,RPag*512);
- BlockRead(Ndx_File,Ndx_Data,512,ct);
- inc(Ndx_Lvl);
- with Ndx_Tabl[Ndx_Lvl] do
- begin
- Page_No := RPag;
- Etry_No := 0;
- Last_One := Ndx_Data.Entry_Ct+1;
- Node_Pag := true;
- i := 1;
- Less_Than := true;
- while (less_than) and (i <= Last_One) do
- begin
- Etry_No := i;
- Ndx_Pntr := Addr(Ndx_Data.Data_Ary[((i-1) * Ndx_Hdr.Entry_Sz)]);
- if Ndx_Hdr.Data_Typ = 0 then
- begin
- move(Ndx_Pntr^.Char_Fld,key_st[1],st_Lth);
- key_st[0] := chr(st_Lth);
- if key_st >= long_st then Less_Than := false;
- end else
- begin
- if Ndx_Pntr^.Numb_Fld >= m_num then Less_Than := false;
- end;
- inc(i);
- end;
- RPag := Ndx_Pntr^.Block_Ax;
- end;
- end;
- Ndx_Tabl[Ndx_Lvl].Node_Pag := false;
- dec(Ndx_Tabl[Ndx_Lvl].Last_One);
- if Ndx_Hdr.Data_Typ = 0 then
- begin
- if (key_st <> long_st) or
- (Ndx_Tabl[Ndx_Lvl].Last_One < Ndx_Tabl[Ndx_Lvl].Etry_No)
- then KeyFind := 0
- else
- KeyFind := Ndx_Pntr^.Recrd_Ax;
- end else
- begin
- if (Ndx_Pntr^.Numb_Fld <> m_num) or
- (Ndx_Tabl[Ndx_Lvl].Last_One < Ndx_Tabl[Ndx_Lvl].Etry_No)
- then KeyFind := 0
- else
- KeyFind := Ndx_Pntr^.Recrd_Ax;
- end;
- end;
-
-
-
-
-
- end.
-