home *** CD-ROM | disk | FTP | other *** search
- unit KeyTree;
- {$M 4096,0,655360}
- { FEBRUARY 1991 version 3
-
- *****************************************************************************
- * *
- * KeyTree Toolbox *
- * *
- * Copyright 1991 by Rewse Consultants Limited *
- * *
- * The KeyTree Toolbox is issued as shareware. In case you are unaware of *
- * how the shareware system works, it is NOT 'free' software. *
- * No initial charge is made for the software, so that you can try it out *
- * without obligation. However, if you continue to use the software (and in *
- * the case of the KeyTree Toolbox, use programs created using it), *
- * then you are required to pay a registration fee. To register your use of *
- * the KeyTree Toolbox, we ask you to pay a miserly £30 (UK Pounds), a mere *
- * fraction of the cost that you are saving in time and effort. Please send *
- * your registration fee to : *
- * *
- * Rewse Consultants Limited *
- * 44, Horseshoe Road, Pangbourne, Reading, Berkshire RG8 7JL, UK *
- ****************************************************************************}
-
- interface
- uses crt,dos;
-
- type arrayn = array[0..1] of integer;
- arrayp = ^arrayn;
- Chars = array[0..1] of char;
- charp = ^Chars;
-
- const ktRUNCH : char = #0;
- ktRUNSC : integer = 0;
- var ktSCAN,ktERRNO,ktFKEY : integer;
- ktCHAR : char;
- ktINDEXED : Boolean;
-
- function ktCreate(name : string; chain, indexct : integer; var keys )
- : Boolean;
- function ktOpen(name : string; mode, indexno : integer) : integer;
- function ktChangeIndex(f, indexno : integer) : Boolean;
- function ktFlush(f : integer) : Boolean;
- function ktClose(f : integer) : Boolean;
- function ktAdd(f : integer; var data; size : integer) : Boolean;
- function ktAddPhys(f : integer; var data; size : integer) : Boolean;
- function ktRead(f : integer; var data; key : string) : integer;
- function ktReadAfter(f : integer; var data; key : string) : integer;
- function ktReadBefore(f : integer; var data; key : string) : integer;
- function ktLength(f : integer; key : string) : integer;
- function ktNext(f : integer; var data) : integer;
- function ktPrev(f : integer; var data) : integer;
- function ktNextPhys(f : integer; var data) : integer;
- function ktPrevPhys(f : integer; var data) : integer;
- function ktDelete(f : integer; var data) : Boolean;
- function ktUndelete(f : integer; var data) : Boolean;
- function ktRewrite(f : integer; var data; size : integer) : Boolean;
- procedure ktGetChar;
- procedure ktGetPress;
- function ktGetStr(var data; maxlen : integer) : integer;
- function ktGetKey(f : integer; var data,key) : integer;
- function ktReadAll(f : integer; var data; key : string) : integer;
- function ktNextAll(f : integer; var data) : integer;
- function ktPrevAll(f : integer; var data) : integer;
- function ktAddChain(f : integer; var data; size : integer) : Boolean;
- function ktNextChain(f : integer; var data) : integer;
- function ktPrevChain(f : integer; var data) : integer;
- function ktStart(f : integer; var data) : integer;
- function ktEnd(f : integer; var data) : integer;
- function ktStartPhys(f : integer; var data) : integer;
- function ktEndPhys(f : integer; var data) : integer;
- function ktLock(f : integer) : Boolean;
- function ktUnlock(f : integer) : Boolean;
- function ktLocked(f : integer; key : string) : Boolean;
- function ktSize(f : integer) : longint;
- function ktRecords(f,typ : integer) : longint;
- function ktMaxRead(f,max : integer) : integer;
- procedure KtBuildKey(f : integer; var d ;f1,f2 : string);
-
- implementation
-
- uses funckey;
-
- type
- Bytes = array[0..MaxInt] of byte;
- kt_rec = record dup,inxct,curinx,inx_entry,access,ksz : integer;
- fd : file;
- curtyp,maxkey,ixdes,ixlen,kt,minsiz,hks : integer;
- chain : array[0..1] of longint;
- inx_pos,base,recptr,nexrec,fsize : longint;
- BaseEntry,start : longint;
- status : byte;
- filename : string[15];
- keys : arrayp;
- del,maxread : integer;
- end;
- bb_ptr = ^Bytes;
- strptr = ^string;
- kt_ptr = ^kt_rec;
- kt_ptr_ptr = array[0..1] of kt_ptr;
- kt_list = ^kt_ptr_ptr;
- ix_dets = record ix : longint;
- en,x : integer;
- end;
-
- const kt_inx_size : array[0..3] of integer = (30,13,40,99);
- kt_filect : integer = 0;
- kt_function : Boolean = False;
- ext_fil : string[5] = '.fil';
- my_list : kt_list = nil;
- cur_ind_ind : integer = 1000;
- cur_ind_fd : integer = 1000;
- cur_ind_pos : longint = 1000;
-
- var KT : kt_ptr;
- kt_alter : array[0..10] of ix_dets;
- kt_tmplen : array[0..1] of integer;
- kt_inx_char : longint;
- kt_inx : array[0..99] of longint;
- kt_FORWARD,ktCT : integer;
- old_length : array[0..1] of integer;
- oldix : array[0..10] of ix_dets;
- record_moved : Boolean;
- kt_found : Boolean;
- my_k,my_x,my_y : integer;
- oldk,newk : pointer;
-
- {$I-}
-
- procedure kt_wrt_data(var ptr ; len : integer);
- var b : integer;
- begin BlockWrite(KT^.fd,Chars(ptr),word(len));
- b := IOresult;
- end;
- procedure kt_read_data(var ptr ; len : integer);
- var b : integer;
- begin BlockRead(KT^.fd,Chars(ptr),len);
- b := IOresult;
- end;
-
- procedure kt_seek(offs : longint);
- var b : integer;
- begin seek(KT^.fd,offs);
- b := IOresult;
- end;
-
- procedure kt_wrt_status;
- begin kt_seek(KT^.recptr);
- kt_wrt_data(KT^.status,1);
- end;
-
- procedure kt_wrt_elem(var recpt; y : integer);
-
- var x : integer;
-
- begin kt_wrt_status;
- x := 0;
- if (KT^.dup <> 0) then kt_wrt_data(KT^.chain[0],KT^.dup);
- kt_wrt_data(y,2);
- kt_wrt_data(x,2);
- kt_wrt_data(recpt,y);
- x := y + KT^.dup + 7;
- kt_wrt_data(x,2);
- Inc(KT^.fsize,x);
- end;
- function kt_FileOpen(fno : integer) : Boolean;
- begin if (fno > 0) then
- begin Dec(fno);
- if (fno < kt_filect) then
- begin KT := my_list^[fno];
- if (KT <> nil) then
- begin ktERRNO := 0;
- kt_FileOpen := True;
- exit;
- end;
- end;
- end;
- ktERRNO := 9;
- kt_FileOpen := False;
- end;
-
- function kt_FileReady(fno : integer) : Boolean;
- var x : integer;
- begin kt_FileReady := True;
- if kt_FileOpen(fno) then
- begin x := KT^.status and $80;
- if x <> 0 then ktERRNO := 28
- else begin if (KT^.recptr > 0) then exit;
- ktERRNO := 20;
- end;
- end;
- kt_FileReady := False;
- end;
-
- function kt_OKtowrite : Boolean;
- begin kt_OKtowrite := True;
- if (KT^.access <> 0) then exit;
- ktERRNO := 12;
- kt_OKtowrite := False;
- end;
-
- function kt_locked(fno : integer) : Boolean;
- var x : integer;
- begin kt_locked := True;
- if not kt_FileReady(fno) then exit;
- if not kt_OKtowrite then exit;
- x := KT^.status and 1;
- if x <> 0 then begin ktERRNO := 22;
- exit;
- end;
- kt_locked := False;
- end;
-
- function kt_inx_key(keychar : char) : integer;
- var z : byte; x : char;
- begin x := keychar;
- z := Ord(x);
- if z <> 0 then case KT^.curtyp of
-
- 0 : begin if (x = ' ') then z := 2
- else begin if (x >= 'a') and (x <= 'z') then Dec(z,94)
- else begin if (x >= 'A') and (x <= 'Z')
- then Dec(z,62)
- else z := 1;
- end;
- end;
- end;
- 1 : begin if (z < 47) or (z > 57) then z := 1
- else Dec(z,46);
- end;
- 2 : begin if (x = ' ') then z := 2
- else begin if (x >= 'a') and (x <= 'z') then Dec(z,84)
- else begin
- if (x >= 'A') and (x <= 'Z') then Dec(z,52)
- else begin Dec(z,45);
- if (z < 3) or (z > 12) then z := 1;
- end;
- end;
- end;
- end;
- 3 : begin if (z < 31) or (z > 127) then z := 1
- else Dec(z,30);
- end;
- end;
- KT^.inx_entry := z + 1;
- kt_inx_key := z + 1;
- end;
-
- procedure kt_setupkey(var key, recpt);
- var x,y,z,L,S,b,c : integer;
-
- begin for x := 1 to KT^.maxkey do Chars(key)[x] := #0;
- y := KT^.ixdes;
- z := 1;
- c := KT^.keys^[3*(KT^.curinx) + 2];
- for x := 1 to c
- do begin L := KT^.keys^[y];
- Inc(y);
- S := KT^.keys^[y];
- Inc(y);
- while (Bytes(recpt)[s] <> 0) and (L > 0) do
- begin Chars(key)[z] := Chars(recpt)[S];
- Inc(z);
- Inc(S);
- Dec(L);
- end;
- if (x < c) and (L > 0) then Inc(z);
- end;
- Bytes(key)[0] := z - 1;
- end;
- procedure kt_readkey(var ptr);
- var trec : charp; x : word;
- begin
- kt_seek(kt_inx_char);
- kt_read_data(KT^.status,1);
- if (KT^.dup <> 0) then kt_seek(kt_inx_char + KT^.dup + 1);
- kt_read_data(kt_tmplen[0],2);
- kt_read_data(x,2);
- if kt_tmplen[0] > KT^.maxkey then x := kt_tmplen[0]
- else x := KT^.maxkey + 1;
- GetMem(trec,x);
- if (trec = nil) then ktERRNO := 7
- else begin FillChar(trec^,x,#0);
- kt_read_data(trec^,kt_tmplen[0]);
- kt_setupkey(ptr,trec^);
- FreeMem(trec,x);
- end;
- end;
- procedure kt_setname(var ptr1,ptr2);
- var x,y : integer;
- begin
- x := 1;
- y := Bytes(ptr1)[0];
- move(Bytes(ptr1)[0], Bytes(ptr2)[0], y + 1);
- while (x <= y) and (Chars(ptr1)[x] <> '.') do Inc(x);
- if (x > y) then
- begin Move(ext_fil[1],Bytes(ptr2)[x],4);
- Bytes(ptr2)[0] := x + 3;
- end;
- end;
- function kt_read_elem(var recpt) : integer;
- var x,a : integer;
- begin
- kt_read_elem := 0;
- ktINDEXED := ((KT^.status and 2) = 0);
- if (KT^.dup <> 0) then kt_read_data(KT^.chain[0],KT^.dup);
- kt_read_data(x,2);
- kt_read_data(a,2);
- if (x > 0) then
- begin KT^.nexrec := KT^.recptr + x + a + KT^.dup + 7;
- kt_read_elem := x;
- if (KT^.maxread > 0) and (x > KT^.maxread) then
- x := KT^.maxread;
- kt_read_data(recpt,x);
- end
- else ktERRNO := 18;
- end;
-
- function kt_read_indexed(var recpt) : integer;
- begin kt_seek(KT^.recptr);
- kt_read_data(KT^.status,1);
- kt_read_indexed := kt_read_elem(recpt);
- end;
-
- procedure kt_next_index(y : integer);
- var x,z : integer;
- begin
- KT^.curinx := y;
- KT^.curtyp := KT^.keys^[3*y + 1];
- KT^.maxkey := 0;
- z := 3*KT^.inxct;
- if y > 0 then for x := 0 to y - 1 do Inc(z,2*KT^.keys^[3*x + 2]);
- KT^.ixdes := z;
- for x := 1 to KT^.keys^[3*y + 2] do
- begin Inc(KT^.maxkey,KT^.keys^[z]);
- Inc(z,2);
- end;
- end;
-
- procedure kt_read_index;
- begin
- if (KT^.kt <> cur_ind_fd) or (KT^.inx_pos <> cur_ind_pos) or
- (cur_ind_ind <> KT^.curinx) then
- begin kt_seek(-KT^.inx_pos + 1);
- kt_read_data(kt_inx,kt_inx_size[KT^.curtyp]*SizeOf(longint));
- cur_ind_ind := KT^.curinx;
- cur_ind_fd := KT^.kt;
- cur_ind_pos := KT^.inx_pos;
- end;
- end;
-
- procedure kt_wrt_index;
- var b : integer; a : array[0..1] of byte;
- begin
- kt_seek(-KT^.inx_pos);
- a[0] := byte('0') + KT^.curinx;
- kt_wrt_data(a,1);
- b := kt_inx_size[KT^.curtyp]*SizeOf(longint);
- kt_wrt_data(kt_inx,b);
- if KT^.fsize = -KT^.inx_pos then begin Inc(b,3);
- kt_wrt_data(b,2);
- Inc(KT^.fsize,b);
- end;
- cur_ind_ind := KT^.curinx;
- cur_ind_fd := KT^.kt;
- cur_ind_pos := KT^.inx_pos;
- end;
-
- procedure kt_zero_index(k : integer);
- var L,Q : longint; x,y,b : integer;
- begin
- kt_inx[KT^.inx_entry] := 0;
- if kt_inx[0] <> 0 then
- begin y := 0;
- b := 0;
- Q := 0;
- for x := 1 to kt_inx_size[KT^.curtyp] - 1 do
- begin if kt_inx[x] <> 0 then
- begin Inc(y);
- if y > 1 then x := kt_inx_size[KT^.curtyp] - 1
- else begin Q := kt_inx[x];
- if x < KT^.inx_entry then b := 1
- else b := 2;
- end;
- end;
- end;
- if (y < 2) and (Q >= 0) then
- begin while (y < 2) and (kt_inx[0] <> 0) do
- begin L := KT^.inx_pos;
- KT^.inx_pos := kt_inx[0];
- kt_read_index;
- KT^.inx_entry := 1;
- while (L <> kt_inx[KT^.inx_entry]) do
- Inc(KT^.inx_entry);
- if (KT^.BaseEntry <> 0) and (L = KT^.base) then
- begin KT^.base := KT^.inx_pos;
- KT^.BaseEntry := KT^.inx_entry;
- end;
- kt_inx[KT^.inx_entry] := Q;
- y := 0;
- for x := 1 to kt_inx_size[KT^.curtyp] - 1 do
- begin if kt_inx[x] <> 0 then Inc(y);
- if y > 1 then x := kt_inx_size[KT^.curtyp] - 1
- end;
- end;
- if k = KT^.curinx then KT^.del := b;
- end;
- end;
- kt_wrt_index;
- end;
-
- procedure set_values(x,z : integer);
- begin
- kt_alter[KT^.curinx].ix := KT^.inx_pos;
- kt_alter[KT^.curinx].x := x;
- kt_alter[KT^.curinx].en := z;
- end;
-
- function kt_lookup(var key) : Boolean;
- var x,y,z,k : integer;
- begin
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- y := KT^.maxkey;
- if y > Bytes(key)[0] then y := Bytes(key)[0];
- kt_lookup := False;
- for x := 1 to y + 1 do
- begin kt_read_index;
- if x = y + 1 then z := kt_inx_key(#0)
- else z := kt_inx_key(Chars(key)[x]);
- if kt_inx[z] = 0 then begin set_values(x,z);
- exit;
- end;
- kt_inx_char := kt_inx[z];
- if kt_inx_char > 0 then begin KT^.recptr := kt_inx_char;
- kt_lookup := True;
- set_values(x,z);
- exit;
- end;
- KT^.inx_pos := kt_inx_char;
- end;
- end;
-
- procedure kt_record_lookup(var recpt);
- var temk : pointer; x : Boolean; f : integer;
- begin f := KT^.maxkey+1;
- GetMem(temk,f);
- if (temk <> nil) then begin kt_setupkey(temk^,recpt);
- x := kt_lookup(temk^);
- FreeMem(temk,f);
- end;
- end;
-
- function kt_keysmatch(var new,old) : integer;
- var x,y,z,f,q : integer; a,b : char;
- begin
- kt_keysmatch := 0;
- f := 0;
- if Ord(chars(new)[0]) > KT^.maxkey then q := KT^.maxkey
- else q := Ord(chars(new)[0]);
- for x := 1 to q do
- begin if f >= Ord(chars(old)[0]) then
- begin kt_keysmatch := 1;
- exit;
- end;
- Inc(f);
- a := Chars(new)[x];
- b := Chars(old)[x];
- if a <> b then begin z := KT^.inx_entry;
- y := kt_inx_key(a) - kt_inx_key(b);
- KT^.inx_entry := z;
- if y <> 0 then
- begin kt_keysmatch := y;
- exit;
- end;
- end;
- end;
- if f < Ord(chars(old)[0]) then kt_keysmatch := -1;
- end;
-
- function kt_exists(var key) : integer;
- var z,f : integer; temk : charp; s : string;
- begin
- if kt_lookup(key) then
- begin f := KT^.maxkey+1;
- GetMem(temk,f);
- if (temk <> nil) then
- begin
- kt_readkey(temk^);
- z := kt_keysmatch(chars(key),temk^);
- FreeMem(temk,f);
- if z = 0 then begin kt_exists := kt_tmplen[0];
- exit;
- end;
- end;
- end;
- kt_exists := 0;
- end;
-
- procedure compare_chars;
- var i : integer; q : longint;
- begin q := -KT^.fsize;
- while True do begin my_k := kt_inx_key(Chars(oldk^)[my_y]);
- my_x := kt_inx_key(Chars(newk^)[my_y]);
- if my_k <> my_x then exit;
- kt_inx[my_k] := q;
- kt_wrt_index;
- kt_inx[0] := KT^.inx_pos;
- KT^.inx_pos := q;
- Dec(q,kt_inx_size[KT^.curtyp]*SizeOf(longint) + 3);
- for i := 1 to kt_inx_size[KT^.curtyp] do
- kt_inx[i] := 0;
- Inc(my_y);
- end;
- end;
- procedure kt_update_index(var recpt; s : integer);
- var L : longint; f : integer;
- begin
- L := KT^.recptr;
- if s <> 0 then KT^.inx_pos := -KT^.keys^[3*KT^.curinx]
- else KT^.inx_pos := kt_alter[KT^.curinx].ix;
- f := KT^.maxkey+1;
- GetMem(newk,f);
- if newk = nil then begin ktERRNO := 7;
- exit;
- end;
- FillChar(newk^,f,#0);
- kt_setupkey(newk^,recpt);
- kt_read_index;
- if s <> 0 then
- begin my_y := 1;
- kt_inx_char := -1;
- while kt_inx_char < 0 do
- begin my_x := kt_inx_key(Chars(newk^)[my_y]);
- kt_inx_char := kt_inx[my_x];
- if kt_inx_char < 0 then
- begin KT^.inx_pos := kt_inx_char;
- kt_read_index;
- Inc(my_y);
- end;
- end;
- end
- else begin my_x := kt_alter[KT^.curinx].en;
- my_y := kt_alter[KT^.curinx].x;
- end;
- kt_inx_char := kt_inx[my_x];
- if kt_inx_char <> 0 then begin GetMem(oldk,f);
- if (oldk <> nil) then
- begin kt_readkey(oldk^);
- compare_chars;
- kt_inx[my_k] := kt_inx_char;
- FreeMem(oldk,f);
- end;
- end;
- KT^.recptr := L;
- kt_inx[my_x] := KT^.recptr;
- KT^.inx_entry := my_x;
- kt_wrt_index;
- FreeMem(newk,f);
- end;
- function kt_OKtoadd(var recpt; err : integer) : Boolean;
- var y,z,k,j,f : integer; L : longint; keypt : charp; s : string;
- c : char;
- begin
- kt_OKtoadd := False;
- k := KT^.curinx;
- L := KT^.recptr;
- for y := 0 to KT^.inxct - 1 do
- begin kt_alter[y].ix := 0;
- kt_next_index(y);
- f := KT^.maxkey+1;
- GetMem(keypt,f);
- if keypt = nil then begin ktERRNO := 7;
- exit;
- end;
- FillChar(keypt^,f,#0);
- kt_setupkey(keypt^,recpt);
- j := kt_exists(keypt^);
- FreeMem(keypt,f);
- if j <> 0 then begin ktERRNO := y + err;
- kt_next_index(k);
- KT^.recptr := L;
- exit;
- end;
- end;
- kt_next_index(k);
- KT^.recptr := L;
- kt_OKtoadd := True;
- end;
-
- function ktCreate(name : string; chain, indexct : integer; var keys) : Boolean;
- var x,y,z,k,n,f,b : integer; zz : array[0..1] of char; t : kt_rec;
- begin
- ktERRNO := 13;
- ktCreate := False;
- if (chain <> 0) then chain := 2*SizeOf(longint);
- if (indexct > 10) or (indexct <= 0) then exit;
- k := 0;
- y := 0;
- for x := 1 to indexct do
- begin if (arrayn(keys)[y] < 0) or
- (arrayn(keys)[y] > 3) then exit;
- if (arrayn(keys)[y + 1] < 1) then exit;
- Inc(y);
- while arrayn(keys)[y] >= 0 do
- begin Inc(k,2);
- if arrayn(keys)[y] < 1 then exit;
- Inc(y);
- if arrayn(keys)[y] < 0 then exit;
- Inc(y);
- end;
- Inc(y);
- end;
- kt_setname(name,t.filename);
- Assign(t.fd,t.filename);
- Reset(t.fd,1);
- if IOresult = 0 then begin Close(t.fd);
- ktERRNO := 1;
- exit;
- end;
- Rewrite(t.fd,1);
- ktERRNO := 2;
- if IOresult <> 0 then exit;
- t.inxct := indexct;
- t.dup := 19284;
- if chain <> 0 then Inc(t.dup);
- t.curinx := 2*(k + 3*indexct);
- BlockWrite(t.fd,t.dup,6);
- if IOresult <> 0 then begin Close(t.fd);
- exit;
- end;
- f := t.curinx;
- GetMem(t.keys,f);
- if t.keys = nil then begin ktERRNO := 7;
- Close(t.fd);
- exit;
- end;
- n := t.curinx + 6;
- z := 3*indexct;
- y := 0;
- for x := 0 to 3*indexct - 1 do
- begin t.keys^[x] := n;
- Inc(x);
- Inc(n, kt_inx_size[arrayn(keys)[y]]*SizeOf(longint) + 3);
- t.keys^[x] := arrayn(keys)[y];
- Inc(x);
- Inc(y);
- t.keys^[x] := 0;
- while arrayn(keys)[y] >= 0 do
- begin Inc(t.keys^[x]);
- t.keys^[z] := arrayn(keys)[y];
- Inc(z);
- Inc(y);
- t.keys^[z] := arrayn(keys)[y];
- Inc(z);
- Inc(y);
- end;
- Inc(y);
- end;
- BlockWrite(t.fd,t.keys^,t.curinx);
- if IOresult <> 0 then begin Close(t.fd);
- FreeMem(t.keys,f);
- exit;
- end;
- for x := 0 to 98 do kt_inx[x] := 0;
- for x := 0 to indexct - 1 do
- begin zz[0] := char(byte('0') + x);
- BlockWrite(t.fd,zz,1);
- if IOresult <> 0 then begin Close(t.fd);
- FreeMem(t.keys,f);
- exit;
- end;
- b := kt_inx_size[t.keys^[3*x + 1]]*SizeOf(longint);
- BlockWrite(t.fd,kt_inx,b);
- if IOresult <> 0 then begin Close(t.fd);
- FreeMem(t.keys,f);
- exit;
- end;
- Inc(b,3);
- BlockWrite(t.fd,b,2);
- if IOresult <> 0 then begin Close(t.fd);
- FreeMem(t.keys,f);
- exit;
- end;
- end;
- Close(t.fd);
- FreeMem(t.keys,f);
- ktERRNO := 0;
- ktCreate := True;
- end;
- procedure set_min_size;
- var x,y,z,q,a : integer;
- begin z := 3*KT^.inxct;
- KT^.minsiz := 1;
- KT^.hks := 1;
- for x := 0 to KT^.inxct - 1 do
- begin y := KT^.keys^[3*x + 2];
- for a := 1 to y do
- begin q := KT^.keys^[z] + KT^.keys^[z+1];
- if KT^.minsiz < q then KT^.minsiz := q;
- if KT^.keys^[z+1] > KT^.hks - 1 then
- KT^.hks := KT^.keys^[z+1] + 1;
- Inc(z,2);
- end;
- end;
- end;
-
- function ktOpen(name : string; mode, indexno : integer) : integer;
- var x,y : integer; t : kt_ptr; tt : kt_list; bb : bb_ptr; c : char;
- begin
- ktOpen := 0;
- if (indexno < 0) then begin ktERRNO := 4;
- exit;
- end;
- ktERRNO := 0;
- y := 0;
- tt := my_list;
- if kt_filect > 0 then
- begin while (y < kt_filect) and (my_list^[y] <> nil) do Inc(y);
- if y = kt_filect then
- begin Inc(kt_filect);
- GetMem(tt,kt_filect*SizeOf(kt_ptr));
- if tt = nil then begin ktERRNO := 7;
- exit;
- end;
- for x := 0 to y - 1 do tt^[x] := my_list^[x];
- FreeMem(my_list,y*SizeOf(kt_ptr));
- my_list := tt;
- end;
- end
- else begin GetMem(my_list,SizeOf(kt_ptr));
- if my_list = nil then begin ktERRNO := 7;
- exit;
- end;
- kt_filect := 1;
- end;
- GetMem(my_list^[y],SizeOf(kt_rec));
- KT := my_list^[y];
- if KT = nil then begin ktERRNO := 7;
- exit;
- end;
- KT^.kt := y;
- kt_setname(name,KT^.filename);
- Assign(KT^.fd,KT^.filename);
- Reset(KT^.fd,1);
- if IOresult <> 0 then begin ktERRNO := 2;
- FreeMem(my_list^[y],SizeOf(kt_rec));
- my_list^[y] := nil;
- exit;
- end
- else begin
- KT^.maxread := 0;
- KT^.fsize := FileSize(KT^.fd);
- if KT^.fsize <= 0 then ktERRNO := 6
- else begin
- kt_seek(0);
- kt_read_data(KT^,6);
- x := KT^.dup - 19284;
- if (x <> 0) and (x <> 1) and (x <> $100) and (x <> $101)
- then ktERRNO := 3
- else begin
- KT^.dup := x and 1;
- if KT^.dup <> 0 then KT^.dup := 2*SizeOf(longint);
- if KT^.inxct <= indexno then ktERRNO := 4
- else begin
- GetMem(KT^.keys,KT^.curinx);
- if KT^.keys = nil then ktERRNO := 7
- else begin KT^.ksz := KT^.curinx;
- kt_read_data(KT^.keys^,KT^.curinx);
- kt_next_index(indexno);
- KT^.access := mode;
- KT^.inx_entry := 0;
- KT^.recptr := 0;
- KT^.BaseEntry := 0;
- KT^.start :=
- kt_inx_size[KT^.keys^[3*(KT^.inxct-1) + 1]]*SizeOf(longint) +
- KT^.keys^[3*KT^.inxct - 3] + 3;
- set_min_size;
- ktOpen := y + 1;
- exit;
- end;
- end;
- end;
- end;
- Close(KT^.fd);
- end;
- FreeMem(my_list^[y],SizeOf(kt_rec));
- my_list^[y] := nil;
- end;
-
- function ktChangeIndex(f, indexno : integer) : Boolean;
-
- begin ktChangeIndex := False;
- if not kt_FileOpen(f) then exit;
- if (indexno < 0) or (indexno >= KT^.inxct) then begin ktERRNO := 4;
- exit;
- end;
- if indexno <> KT^.curinx then
- begin kt_next_index(indexno);
- KT^.BaseEntry := 0;
- KT^.inx_entry := 0;
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- end;
- ktChangeIndex := True;
- end;
- function ktFlush(f : integer) : Boolean;
-
- begin ktFlush := False;
- if not kt_FileOpen(f) then exit;
- Close(KT^.fd);
- Assign(KT^.fd,KT^.filename);
- Reset(KT^.fd,1);
- ktFlush := True;
- end;
-
- function ktClose(f : integer) : Boolean;
-
- var y : integer;
- begin if not kt_FileOpen(f) then ktClose := False
- else begin Close(KT^.fd);
- cur_ind_fd := 1000;
- FreeMem(KT^.keys,KT^.ksz);
- FreeMem(my_list^[f-1],SizeOf(kt_rec));
- my_list^[f-1] := nil;
- ktClose := True;
- end;
- end;
- procedure add_indexes(var recpt);
- var k,y : integer;
-
- begin
- k := KT^.curinx;
- for y := 0 to KT^.inxct-1 do
- if y <> k then begin kt_next_index(y);
- kt_update_index(recpt,0);
- end;
- kt_next_index(k);
- kt_update_index(recpt,0);
- end;
-
- function ktAdd(f : integer; var data; size : integer) : Boolean;
- var areapt : charp; x,y : integer;
- begin ktAdd := True;
- if size < 1 then ktERRNO := 15
- else if kt_FileOpen(f) then
- begin if kt_OKtowrite then
- begin
- if size < KT^.minsiz then
- begin GetMem(areapt,KT^.minsiz);
- FillChar(areapt^,KT^.minsiz,#0);
- Move(Chars(data),areapt^,size);
- if size > KT^.hks then x := size
- else x := KT^.hks;
- if areapt^[x-1] <> #0 then Inc(x);
- end
- else areapt := nil;
- if kt_OKtoadd(data,40) then
- begin
- KT^.recptr := KT^.fsize;
- KT^.chain[0] := 0;
- KT^.chain[1] := 0;
- KT^.status := 0;
- if areapt <> nil then
- begin kt_wrt_elem(areapt^,x);
- add_indexes(areapt^);
- FreeMem(areapt,KT^.minsiz);
- end
- else
- begin kt_wrt_elem(data,size);
- add_indexes(data);
- end;
- exit;
- end
- else if areapt <> nil then
- FreeMem(areapt,KT^.minsiz);
- KT^.recptr := 0;
- end;
- end;
- ktAdd := False;
- end;
- function ktAddPhys(f : integer; var data; size : integer) : Boolean;
-
- begin if size < 1 then ktERRNO := 15
- else if kt_FileOpen(f) then
- if kt_OKtowrite then
- begin KT^.chain[0] := 0;
- KT^.chain[1] := 0;
- KT^.recptr := KT^.fsize;
- KT^.status := 2;
- kt_wrt_elem(data,size);
- ktAddPhys := True;
- exit;
- end;
- ktAddPhys := False;
- end;
- function NN_NN(var recpt; b, errs : integer) : integer;
-
- var a1 : integer; y,z,a2,comp,c2 : longint; q : Boolean;
- begin
- a1 := KT^.inx_entry;
- a2 := KT^.inx_pos;
- KT^.del := 0;
- kt_read_index;
- if (b <> 0) then comp := -KT^.keys^[3*KT^.curinx]
- else comp := KT^.base;
- while True do
- begin if kt_FORWARD <= 0 then begin Dec(KT^.inx_entry);
- q := (KT^.inx_entry <= 0) or
- ((b = 0) and (KT^.inx_pos = KT^.base) and
- (KT^.inx_entry <> KT^.BaseEntry));
- end
- else begin Inc(KT^.inx_entry);
- q := (KT^.inx_entry >= kt_inx_size[KT^.curtyp]) or
- ((b = 0) and (KT^.inx_pos = KT^.base) and
- (KT^.inx_entry <> KT^.BaseEntry));
- end;
- if q then begin if KT^.inx_pos >= comp then
- begin ktERRNO := errs;
- KT^.inx_entry := a1;
- KT^.inx_pos := a2;
- NN_NN := 0;
- exit;
- end;
- y := KT^.inx_pos;
- KT^.inx_pos := kt_inx[0];
- kt_read_index;
- KT^.inx_entry := 1;
- while y <> kt_inx[KT^.inx_entry] do
- Inc(KT^.inx_entry);
- end
- else begin z := kt_inx[KT^.inx_entry];
- if z > 0 then begin KT^.recptr := z;
- NN_NN := kt_read_indexed(recpt);
- exit;
- end;
- if z < 0 then begin
- KT^.inx_pos := z;
- kt_read_index;
- if kt_FORWARD > 0 then KT^.inx_entry := 0
- else KT^.inx_entry := kt_inx_size[KT^.curtyp];
- end;
- end;
- end;
- end;
-
- function ktFind(fno : integer;var recpt; key : string) : integer;
-
- var x,y : integer; temk : pointer;
-
- begin ktFind := 0;
- if not kt_FileOpen(fno) then exit;
-
- ktERRNO := 0;
- KT^.BaseEntry := 0;
- if kt_lookup(key) then
- begin y := kt_read_indexed(recpt);
- if y = 0 then exit;
- GetMem(oldk,KT^.maxkey+1);
- if oldk = nil then begin ktERRNO := 7;
- exit;
- end;
- kt_setupkey(oldk^,recpt);
- x := kt_keysmatch(key,oldk^);
- FreeMem(oldk,KT^.maxkey+1);
- if (x = 0) or
- ((kt_FORWARD > 0) and (x < 0)) or
- ((kt_FORWARD < 0) and (x > 0)) then
- begin ktFind := y;
- exit;
- end;
- end;
- if kt_FORWARD = 0 then begin ktERRNO := 17;
- y := 0;
- end
- else begin if kt_FORWARD > 0 then x := 26
- else x := 27;
- y := NN_NN(recpt,1,x);
- end;
- ktFind := y;
- end;
-
- function ktRead(f : integer; var data; key : string) : integer;
-
- begin kt_FORWARD := 0;
- ktRead := ktFind(f,data,key);
- end;
-
- function ktReadAfter(f : integer; var data; key : string) : integer;
-
- begin kt_FORWARD := 1;
- ktReadAfter := ktFind(f,data,key);
- end;
-
- function ktReadBefore(f : integer; var data; key : string) : integer;
-
- begin kt_FORWARD := -1;
- ktReadBefore := ktFind(f,data,key);
- end;
-
- function ktLength(f : integer; key : string) : integer;
-
- var x : integer; temk : pointer;
-
- begin x := 0;
- if kt_FileOpen(f) then
- begin x := kt_exists(key);
- if x = 0 then ktERRNO := 17;
- end;
- ktLength := x;
- end;
-
- function kt_goon(fno : integer;var recpt ; s : integer) : integer;
-
- begin kt_goon := 0;
- if not kt_FileOpen(fno) then exit;
- if s = 0 then KT^.recptr := 0;
- if KT^.recptr <= 0 then begin KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- KT^.inx_entry := 0;
- end
- else if KT^.del = 2 then Dec(KT^.inx_entry);
- kt_FORWARD := 1;
- KT^.BaseEntry := 0;
- kt_goon := NN_NN(recpt,1,26);
- end;
- function ktNext(f : integer; var data) : integer;
- begin ktNext := kt_goon(f,data,1);
- end;
-
- function kt_goback(fno : integer; var recpt; s : integer) : integer;
-
- begin kt_goback := 0;
- if not kt_FileOpen(fno) then exit;
- if s = 0 then KT^.recptr := 0;
- if KT^.recptr <= 0 then begin
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- KT^.inx_entry := kt_inx_size[KT^.curtyp];
- end
- else if KT^.del = 1 then Inc(KT^.inx_entry);
- kt_FORWARD := 0;
- KT^.BaseEntry := 0;
- kt_goback := NN_NN(recpt,1,27);
- end;
- function ktPrev(f : integer; var data) : integer;
- begin ktPrev := kt_goback(f,data,1);
- end;
- procedure del_undel(a : byte);
- var q,r,s,t : longint; r1 : array[0..11] of longint; b : byte;
- begin r := KT^.chain[0];
- s := r;
- q := KT^.chain[1];
- r1[1] := q;
- t := q;
- if a = 2 then begin t := KT^.recptr;
- s := t;
- end;
- b := KT^.status;
- kt_wrt_status;
- if KT^.dup <> 0 then
- begin if r = 0 then
- begin KT^.status := a;
- while r1[1] <> 0 do
- begin kt_seek(r1[1]);
- kt_wrt_data(KT^.status,1);
- kt_read_data(r1[0],2*SizeOf(longint));
- end;
- KT^.status := b;
- end
- else begin
- kt_seek(r + 1 + SizeOf(longint));
- kt_wrt_data(t,SizeOf(longint));
- if q <> 0 then
- begin Inc(q);
- kt_seek(q);
- kt_wrt_data(s,SizeOf(longint));
- end;
- end;
- end;
- end;
- function ktDelete(f : integer; var data) : Boolean;
- var x,k : integer; temk : pointer;
- begin if kt_locked(f) then begin ktDelete := False;
- exit;
- end;
- KT^.status := KT^.status or $80;
- del_undel($82);
- if (KT^.status and 2) = 0 then
- begin k := KT^.curinx;
- if KT^.inxct > 1 then
- begin for x := 0 to KT^.inxct - 1 do
- if x <> k then
- begin kt_next_index(x);
- kt_record_lookup(data);
- kt_zero_index(x);
- end;
- kt_next_index(k);
- end;
- kt_record_lookup(data);
- kt_zero_index(k);
- end;
- ktDelete := True;
- end;
- function ktUndelete(f : integer; var data) : Boolean;
-
- begin ktUndelete := False;
- if not kt_FileOpen(f) or not kt_OKtowrite then exit;
- if KT^.recptr <= 0 then begin ktERRNO := 20;
- exit;
- end;
- if (KT^.status and $80) = 0 then begin ktERRNO := 29;
- exit;
- end;
- if (KT^.status and 2) = 0 then
- begin if not kt_OKtoadd(data,50) then exit;
- add_indexes(data);
- end;
- KT^.status := KT^.status and $7f;
- del_undel(2);
- ktUndelete := True;
- end;
-
- procedure kt_alter_index(y : integer; var recpt);
- begin kt_next_index(y);
- KT^.inx_pos := oldix[y].ix;
- KT^.inx_entry := oldix[y].en;
- if KT^.inx_pos <> 0 then
- begin kt_read_index;
- if kt_alter[y].ix <> 0 then
- begin KT^.inx_entry := oldix[y].en;
- kt_zero_index(y);
- kt_update_index(recpt,1);
- end
- else if record_moved then
- begin kt_inx[KT^.inx_entry] := KT^.recptr;
- kt_wrt_index;
- end;
- end;
- end;
- function ktRewrite(f : integer; var data; size : integer) : Boolean;
-
- var x,y,z,i,j,k,e,ff : integer; keypt,oldrec : pointer;
- areapt : charp; q,r,s,start : longint;
-
- begin ktRewrite := False;
- if size < 1 then begin ktERRNO := 15;
- exit;
- end;
- if kt_locked(f) then exit;
- if (size < KT^.minsiz) and (KT^.status and 2 = 0) then
- begin GetMem(areapt,KT^.minsiz);
- FillChar(areapt^,KT^.minsiz,#0);
- Move(Chars(data),areapt^,size);
- if size < KT^.hks then size := KT^.hks;
- if areapt^[size-1] <> #0 then Inc(size);
- end
- else areapt := nil;
- q := KT^.recptr;
- r := KT^.inx_pos;
- e := KT^.inx_entry;
- k := KT^.curinx;
- start := q + KT^.dup + 1;
- kt_seek(start);
- kt_read_data(old_length,4);
- record_moved := (size > old_length[0] + old_length[1]);
-
- if (KT^.status and 2) = 0 then
- begin kt_inx_char := q;
- z := 1;
- if old_length[0] > KT^.maxkey then ff := old_length[0]
- else ff := KT^.maxkey+1;
- GetMem(oldrec,ff);
- FillChar(oldrec^,ff,#0);
- if oldrec = nil then
- begin ktERRNO := 7;
- if areapt <> nil then FreeMem(areapt,KT^.minsiz);
- exit;
- end;
- kt_read_data(oldrec^,old_length[0]);
- for y := KT^.inxct - 1 downto 0 do
- begin kt_next_index(y);
- x := 0;
- GetMem(keypt,KT^.maxkey+1);
- if keypt = nil then
- begin ktERRNO := 7;
- FreeMem(oldrec,ff);
- if areapt <> nil then
- FreeMem(areapt,KT^.minsiz);
- exit;
- end;
- if areapt <> nil then
- kt_setupkey(keypt^,areapt^)
- else kt_setupkey(keypt^,Chars(data));
- GetMem(oldk,KT^.maxkey+1);
- if oldk = nil then
- begin ktERRNO := 7;
- FreeMem(keypt,KT^.maxkey+1);
- FreeMem(oldrec,ff);
- if areapt <> nil
- then FreeMem(areapt,KT^.minsiz);
- exit;
- end;
-
- kt_setupkey(oldk^,oldrec^);
- kt_alter[y].ix := 0;
- oldix[y].ix := 0;
- if kt_keysmatch(oldk^,keypt^) <> 0 then
- x := kt_exists(keypt^);
- if (x = 0) and ((record_moved) or (kt_alter[y].ix <> 0)) then
- begin
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- for j := 1 to KT^.maxkey do
- begin kt_read_index;
- i := kt_inx_key(Chars(oldk^)[j]);
- if kt_inx[i] = 0 then
- j := KT^.maxkey
- else begin
- kt_inx_char := kt_inx[i];
- if kt_inx_char > 0 then
- begin KT^.recptr := kt_inx_char;
- j := KT^.maxkey
- end
- else KT^.inx_pos := kt_inx_char;
- end;
- end;
- oldix[KT^.curinx].ix := KT^.inx_pos;
- oldix[KT^.curinx].en := i;
- end;
- FreeMem(oldk,KT^.maxkey+1);
- FreeMem(keypt,KT^.maxkey+1);
- if x <> 0 then begin ktERRNO := 30 + y;
- z := 0;
- y := 0;
- end;
- end;
- kt_next_index(k);
- FreeMem(oldrec,ff);
- KT^.recptr := q;
- KT^.inx_pos := r;
- KT^.inx_entry := e;
- if z = 0 then
- begin if areapt <> nil then FreeMem(areapt,KT^.minsiz);
- exit;
- end;
- end;
- if record_moved then
- begin KT^.recptr := q;
- KT^.status := KT^.status or $80;
- kt_wrt_status;
- KT^.recptr := KT^.fsize;
- s := KT^.recptr;
- KT^.status := KT^.status and $7f;
- if areapt <> nil then
- kt_wrt_elem(areapt^,size)
- else kt_wrt_elem(Chars(data),size);
- if KT^.dup <> 0 then
- begin if KT^.chain[0] <> 0 then
- begin kt_seek(KT^.chain[0] + 1 + SizeOf(longint));
- kt_wrt_data(s,SizeOf(longint));
- end;
- if KT^.chain[1] <> 0 then
- begin kt_seek(KT^.chain[1] + 1);
- kt_wrt_data(s,SizeOf(longint));
- end;
- end;
- end
- else begin if size <> old_length[0] then
- begin Inc(old_length[1],old_length[0] - size);
- old_length[0] := size;
- kt_seek(start);
- kt_wrt_data(old_length,4);
- end
- else kt_seek(start + 4);
- if areapt <> nil then
- kt_wrt_data(areapt^,size)
- else kt_wrt_data(Chars(data),size);
- end;
- if (KT^.status and 2) = 0 then
- if areapt <> nil then
- begin for y := 0 to KT^.inxct- 1 do
- if y <> k then kt_alter_index(y,areapt^);
- kt_alter_index(k,areapt^);
- end
- else
- begin for y := 0 to KT^.inxct- 1 do
- if y <> k then kt_alter_index(y,Chars(data));
- kt_alter_index(k,Chars(data));
- end;
- if areapt <> nil then FreeMem(areapt,KT^.minsiz);
- ktRewrite := True;
- end;
-
- procedure ktGetChar;
-
- var d : integer; Regs : registers;
-
- begin if (ktRUNCH <> char(0)) or (ktRUNSC <> 0) then
- begin ktCHAR := ktRUNCH;
- ktSCAN := ktRUNSC;
- ktRUNCH := char(0);
- ktRUNSC := 0;
- end
- else while True do
- begin Regs.ax := 0;
- intr($16,Regs);
- ktSCAN := integer(regs.ah);
- ktCHAR := char(regs.al);
- if (ktSCAN < 59) or (ktSCAN > 68) or (kt_function)
- then exit;
- ktFKEY := ktSCAN - 58;
- kt_function := True;
- ktProcessFunctionKey;
- kt_function := False;
- end;
- end;
- procedure ktGetPress;
- begin ktGetChar;
- ktRUNCH := ktCHAR;
- ktRUNSC := ktSCAN;
- end;
- function ktGetStr(var data ; maxlen : integer) : integer;
- var x,z : integer;
- begin if maxlen = 0 then maxlen := -1;
- x := 1;
- z := 0;
- while (z = 0) do
- begin ktGetChar;
- if (ktSCAN = 1) or (ktSCAN = 28) then z := 1
- else begin if (ktSCAN = 14) then
- begin if x > 1 then begin Dec(x);
- Chars(data)[x] := #0;
- ktBackSpace;
- end;
- end
- else begin if (ktCHAR = #0) then
- begin if (ktSCAN = 75) and (x > 0) then
- begin ktPutChar(#8);
- Dec(x);
- end else if (ktSCAN = 77) and
- (x < maxlen) then
- begin if Chars(data)[x] < #32 then
- Chars(data)[x] := ' ';
- ktPutChar(Chars(data)[x]);
- Inc(x);
- end;
- end
- else begin if x >= maxlen then z := 1
- else if ktCHAR > #31 then
- begin Chars(data)[x] := ktCHAR;
- Inc(x);
- ktPutChar(ktCHAR);
- end;
- end;
- end;
- end;
- end;
- ktGetStr := x;
- Dec(x);
- Chars(data)[0] := char(x);
- end;
- function get_next_part(k : integer; var recpt, keypt) : integer;
- var x,y,z,L : integer; q : longint;
-
- begin L := KT^.keys^[KT^.ixdes + 2*k];
- y := 1;
- for x := ktCT to ktCT + L - 1 do Chars(keypt)[x] := #0;
- get_next_part := 0;
- for x := 1 to L do
- begin ktGetChar;
- if (ktSCAN = 14) or
- ((ktCHAR = #0) and (ktSCAN = 75)) then
- begin if ktCT > 1 then
- begin Dec(ktCT);
- Chars(keypt)[ktCT] := #0;
- Dec(Chars(keypt)[0]);
- ktBackSpace;
- if ktCT = 1 then
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx]
- else begin KT^.inx_pos := q;
- kt_read_index;
- q := kt_inx[0];
- end;
- end;
- end
- else begin if ktSCAN = 1 then exit;
- if ktSCAN = 28 then ktCHAR := #0
- else if ktCHAR > #31 then ktPutChar(ktCHAR);
- Chars(keypt)[ktCT] := ktCHAR;
- Inc(Chars(keypt)[0]);
- Inc(ktCT);
- kt_read_index;
- z := kt_inx_key(ktCHAR);
- kt_inx_char := kt_inx[z];
- if kt_inx_char > 0 then
- begin KT^.recptr := kt_inx_char;
- get_next_part :=
- kt_read_indexed(recpt);
- kt_found := True;
- exit;
- end;
- if kt_inx_char = 0 then
- begin if ktCHAR = #0 then get_next_part := -1;
- exit;
- end;
- q := KT^.inx_pos;
- KT^.inx_pos := kt_inx_char;
- if ktCHAR = #0 then begin get_next_part := 1;
- exit;
- end;
- end;
- end;
- get_next_part := y;
- end;
- function ktGetKey(f : integer; var data,key) : integer;
-
- var y,k : integer;
-
- begin if not kt_FileOpen(f) then y := 0
- else begin
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- KT^.del := 0;
- KT^.BaseEntry := 0;
- KT^.recptr := 0;
- Chars(key)[0] := #0;
- ktCT := 1;
- for k := 0 to KT^.keys^[3*KT^.curinx + 2] - 1 do
- begin kt_found := False;
- y := get_next_part(k,data,key);
- if (kt_found) or (y <= 0) then
- begin ktGetKey := y;
- if ktCHAR = #0 then Dec(Chars(key)[0]);
- exit;
- end;
- ktSeparator;
- end;
- end;
- ktGetKey := y;
- end;
- function ktReadAll(f : integer; var data; key : string) : integer;
- var x,y,z,ff : integer; okey : pointer;
- begin ktReadAll := 0;
- if not kt_FileOpen(f) then exit;
- KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
- KT^.BaseEntry := 1;
- KT^.base := -1;
- y := integer(key[0]);
- if y > KT^.maxkey then y := KT^.maxkey;
- for x := 1 to y do
- begin KT^.base := KT^.inx_pos;
- kt_read_index;
- z := kt_inx_key(key[x]);
- if kt_inx[z] = 0 then begin KT^.BaseEntry := 0;
- ktERRNO := 17;
- exit;
- end;
- KT^.inx_entry := z;
- KT^.BaseEntry := KT^.inx_entry;
- kt_inx_char := kt_inx[z];
- if kt_inx_char > 0 then
- begin KT^.recptr := kt_inx_char;
- z := kt_read_indexed(data);
- if z <> 0 then
- begin ff := KT^.maxkey+1;
- GetMem(okey,ff);
- if (okey = nil) then exit;
- kt_setupkey(okey^,data);
- while (x <= y) do
- begin if kt_inx_key(key[x]) <>
- kt_inx_key(Chars(okey^)[x]) then
- begin KT^.BaseEntry := 0;
- z := 0;
- ktERRNO := 17;
- x := y + 1;
- end
- else Inc(x);
- end;
- FreeMem(okey,ff);
- ktReadAll := z;
- exit;
- end;
- end;
- KT^.inx_pos := kt_inx_char;
- end;
- KT^.inx_entry := 0;
- kt_FORWARD := 1;
- ktReadAll := NN_NN(data,0,0);
- end;
- function ktFileBase(var recpt; fno : integer) : integer;
- begin if kt_FileOpen(fno) then
- begin if (KT^.BaseEntry <> 0) and (KT^.base < 0) then
- begin if (KT^.del <> 0) and ((KT^.base > KT^.inx_pos) or
- (KT^.inx_entry = KT^.BaseEntry))
- then begin if kt_FORWARD <> 0 then
- begin if KT^.del = 2 then Dec(KT^.inx_entry);
- end
- else
- begin if KT^.del = 1 then Inc(KT^.inx_entry);
- end;
- end;
- ktFileBase := NN_NN(recpt,0,0);
- exit;
- end
- else begin if KT^.BaseEntry <> 0 then ktERRNO := 0
- else ktERRNO := 25;
- end;
- end;
- ktFileBase := 0;
- end;
- function ktNextAll(f : integer; var data) : integer;
- begin kt_FORWARD := 1;
- ktNextAll := ktFileBase(data,f);
- end;
- function ktPrevAll(f : integer; var data) : integer;
- begin kt_FORWARD := 0;
- ktPrevAll := ktFileBase(data,f);
- end;
- function ktAddChain(f : integer; var data; size : integer) : Boolean;
- var q,r : longint;
- begin ktAddChain := False;
- if kt_FileReady(f) then
- begin if KT^.dup = 0 then ktERRNO := 23
- else if kt_OKtowrite then
- begin if size < 1 then ktERRNO := 15
- else begin q := KT^.fsize;
- kt_seek(KT^.recptr + 1 + SizeOf(longint));
- kt_wrt_data(q,SizeOf(longint));
- r := KT^.chain[1];
- if r <> 0 then begin Inc(r);
- kt_seek(r);
- kt_wrt_data(q,SizeOf(longint));
- end;
- KT^.chain[0] := KT^.recptr;
- KT^.recptr := q;
- KT^.status := 2;
- kt_wrt_elem(data,size);
- ktAddChain := True;
- end;
- end;
- end;
- end;
- function NN_Chain(var recpt; fno, n : integer) : integer;
- var q : longint; x : integer;
- begin
- NN_Chain := 0;
- if kt_FileOpen(fno) then
- begin if KT^.dup = 0 then ktERRNO := 23 else
- begin if KT^.recptr <= 0 then ktERRNO := 20 else
- begin x := KT^.status and $80;
- if (x <> 0) and (KT^.chain[0] = 0) then
- ktERRNO := 28 else
- begin q := KT^.chain[n];
- if q <> 0 then
- begin KT^.recptr := q;
- kt_seek(q);
- kt_read_data(KT^.status,1);
- NN_Chain := kt_read_elem(recpt);
- end;
- end;
- end;
- end;
- end;
- end;
- function ktNextChain(f : integer; var data) : integer;
- begin ktNextChain := NN_Chain(data,f,1);
- end;
- function ktPrevChain(f : integer; var data) : integer;
- begin ktPrevChain := NN_Chain(data,f,0);
- end;
- function ktStart(f : integer; var data) : integer;
- begin ktStart := kt_goon(f,data,0);
- end;
- function ktEnd(f : integer; var data) : integer;
- begin ktEnd := kt_goback(f,data,0);
- end;
- function record_status : Boolean;
- begin kt_seek(KT^.recptr);
- kt_read_data(KT^.status,1);
- ktINDEXED := ( (KT^.status and 2) = 0);
- record_status := ((KT^.status < byte('0')) or (KT^.status > byte('9')));
- end;
- function kt_goonPhys(fno : integer; var recpt;s : integer) : integer;
- var y : integer; b : byte;
- begin kt_goonPhys := 0;
- if not kt_FileOpen(fno) then exit;
- if s = 0 then KT^.recptr := 0;
- if KT^.recptr <= 0 then KT^.recptr := KT^.start
- else KT^.recptr := KT^.nexrec;
- while True do
- begin if KT^.recptr >= KT^.fsize then
- begin ktERRNO := 19;
- exit;
- end;
- if record_status then
- begin y := kt_read_elem(recpt);
- if (KT^.status and $80) <> 0 then y := -y;
- kt_goonPhys := y;
- exit;
- end;
- b := KT^.status - 48;
- Inc(KT^.recptr, 3 + kt_inx_size[KT^.keys^[3*b + 1]]*SizeOf(longint));
- end;
- end;
- function ktNextPhys(f : integer; var data) : integer;
- begin ktNextPhys := kt_goonPhys(f,data,1);
- end;
- function kt_gobackPhys(var recpt; fno, s : integer) : integer;
- var z : integer;
- begin kt_gobackPhys := 0;
- if not kt_FileOpen(fno) then exit;
- if s = 0 then KT^.recptr := 0;
- if KT^.recptr <= 0 then KT^.recptr := KT^.fsize;
- while True do
- begin if KT^.recptr <= KT^.start then begin ktERRNO := 21;
- exit;
- end;
- kt_seek(KT^.recptr - 2);
- kt_read_data(z,2);
- Dec(KT^.recptr,z);
- if record_status then
- begin z := kt_read_elem(recpt);
- if (KT^.status and $80) <> 0 then z := -z;
- kt_gobackPhys := z;
- exit;
- end;
- end;
- end;
- function ktPrevPhys(f : integer; var data) : integer;
- begin ktPrevPhys := kt_gobackPhys(data,f,1);
- end;
- function ktStartPhys(f : integer; var data) : integer;
- begin ktStartPhys := kt_goonPhys(f,data,0);
- end;
- function ktEndPhys(f : integer; var data) : integer;
- begin ktEndPhys := kt_gobackPhys(data,f,0);
- end;
- function FirstChar(y, f : integer) : Boolean;
- begin FirstChar := False;
- if not kt_FileReady(f) then exit;
- if (KT^.status and $80) <> 0 then begin ktERRNO := 28;
- exit;
- end;
- KT^.status := (KT^.status and 254) or y;
- kt_wrt_status;
- FirstChar := ktFlush(f);
- end;
- function ktLock(f : integer) : Boolean;
- begin ktLock := FirstChar(1,f);
- end;
- function ktUnlock(f : integer) : Boolean;
- begin ktUnlock := FirstChar(0,f);
- end;
- function ktLocked(f : integer; key : string) : Boolean;
-
- begin ktLocked := False;
- if not kt_FileOpen(f) then exit;
- if kt_exists(key) = 0 then begin ktERRNO := 17;
- ktLocked := False;
- end
- else ktLocked := ((KT^.status and 1) <> 0);
- end;
- function ktSize(f : integer) : longint;
- begin if not kt_FileOpen(f) then ktSize := 0
- else ktSize := KT^.fsize;
- end;
- function ktRecords(f,typ : integer) : longint;
- var x,l : longint; b,c : byte; a : array[0..7] of char;
- begin
- if not kt_FileOpen(f) then begin ktRecords := 0;
- exit;
- end;
- l := KT^.start;
- x := 0;
- while (l < KT^.fsize) do
- begin kt_seek(l);
- kt_read_data(a,1);
- if (a[0] >= '0') and (a[0] <= '9') then
- Inc(l, kt_inx_size[KT^.keys^[3*(byte(a[0])-48) + 1]]*SizeOf(longint)
- + 3)
- else begin b := byte(a[0]) and $80;
- if (typ = 0) or
- ((typ > 0) and (b = 0)) or
- ((typ < 0) and (b <> 0)) then Inc(x);
- if KT^.dup <> 0 then kt_read_data(a,KT^.dup);
- kt_read_data(kt_tmplen[0],2);
- kt_read_data(kt_tmplen[1],2);
- Inc(l, 7 + KT^.dup + kt_tmplen[0] + kt_tmplen[1]);
- end;
- end;
- ktRecords := x;
- end;
- function ktMaxRead(f,max : integer) : integer;
- begin ktMaxRead := 0;
- if kt_FileOpen(f) then
- begin if (max < 0) or ((max > 0) and (max < KT^.minsiz)) then
- ktERRNO := 15
- else begin KT^.maxread := max;
- ktMaxRead := KT^.minsiz;
- end;
- end;
- end;
- procedure KtBuildKey(f : integer; var d ;f1,f2 : string);
- var x,y,m1,m2 : integer;
- type chars = array[0..1] of char;
- begin if not kt_FileOpen(f) then exit;
- y := 3*KT^.inxct;
- for x := 0 to KT^.curinx - 1 do Inc(y,2*KT^.keys^[3*x + 2]);
- m1 := KT^.keys^[y];
- m2 := KT^.keys^[y + 2];
- x := m1 + m2;
- FillChar(d,x + 1, #0);
- x := length(f1);
- if x > m1 then x := m1;
- Move(f1[1],chars(d)[1],x);
- if x < m1 then Inc(x);
- y := length(f2);
- if y > m2 then y := m2;
- Move(f2[1],chars(d)[1 + x],y);
- if y < m2 then Inc(y);
- chars(d)[0] := char(x + y);
- end;
- {$I+}
- end.