| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- (*# call(o_a_size=>off) *)
- (*# call(o_a_copy=>off) *)
- (*# call(near_call=>on) *)
- IMPLEMENTATION MODULE FIOx;
- (*
- Copyright (C) 1988,1989,1990 Jensen & Partners International
- *)
- IMPORT FIO;
- (*%T _OS2 *) IMPORT Dos; (*%E*)
- (*%F _OS2 *) IMPORT Lib, SYSTEM, Str (*%T _mthread *),Process (*%E *); (*%E*)
- VAR
- _multi_mode : MultiMode;
- LocalError : CARDINAL;
- (*************************)
- (****** DOS Section ******)
- (*************************)
- (*%F _OS2 *)
- VAR
- DosVerMaj,
- DosVerMin : SHORTCARD;
- PROCEDURE FileLocks(f: File; VAR unlock,lock: LockRec): CARDINAL;
- VAR
- regs : SYSTEM.Registers;
- tmp : POINTER TO LockRec;
- mode : SHORTCARD;
- BEGIN
- mode := 1;
- tmp := SYSTEM.ADR(unlock);
- LOOP
- IF tmp#NIL THEN
- WITH regs DO
- AH := 5CH;
- AL := mode;
- BX := f;
- CX := CARDINAL(tmp^.pos DIV 65536);
- DX := CARDINAL(tmp^.pos MOD 65536);
- SI := CARDINAL(tmp^.len DIV 65536);
- DI := CARDINAL(tmp^.len MOD 65536);
- END;
- (*%T _mthread *) Process.Lock(); (*%E *)
- Lib.Dos(regs);
- (*%T _mthread *) Process.Unlock(); (*%E *)
- IF SYSTEM.CarryFlag IN regs.Flags THEN
- RETURN regs.AX;
- END;
- END;
- IF mode=0 THEN
- EXIT;
- END;
- tmp := SYSTEM.ADR(lock);
- DEC(mode);
- END;
- RETURN NO_ERROR;
- END FileLocks;
- PROCEDURE Multi(): MultiMode;
- BEGIN
- RETURN _multi_mode;
- END Multi;
- PROCEDURE MultiFile(f: File): BOOLEAN;
- VAR
- regs : SYSTEM.Registers;
- BEGIN
- IF _multi_mode=_multi_file THEN
- WITH regs DO
- AH := 44H;
- AL := 0AH;
- BX := f;
- Lib.Dos(regs);
- RETURN NOT (SYSTEM.CarryFlag IN Flags) AND (15 IN BITSET(DX));
- END;
- ELSE
- RETURN _multi_mode=_multi_yes;
- END;
- END MultiFile;
- (*# save *)
- (*%T _fcall *) (*# call(near_call=>off) *) (*%E *)
- PROCEDURE DelayDefault();
- BEGIN
- (*%T _mthread *) Process.Delay(DelayDefaultValue DIV 50); (*%E *)
- (*%F _mthread *) Lib.Delay(DelayDefaultValue); (*%E *)
- END DelayDefault;
- (*# restore *)
- PROCEDURE Init;
- VAR
- regs : SYSTEM.Registers;
- str : ARRAY[0..5] OF CHAR;
- BEGIN
- _multi_mode := _multi_file;
- WITH regs DO
- AH := 30H;
- Lib.Dos(regs);
- DosVerMaj := AL;
- DosVerMin := AH;
- Lib.EnvironmentFind('multi',str);
- Str.Caps(str);
- IF Str.Compare(str,'YES')=0 THEN
- _multi_mode := _multi_yes;
- ELSIF Str.Compare(str,'NO')=0 THEN
- _multi_mode := _multi_no;
- ELSIF DosVerMaj >= 3 THEN
- AH := 10H;
- AL := 0;
- Lib.Intr(regs,2FH);
- IF AL=0FFH THEN
- _multi_mode := _multi_yes;
- END;
- END;
- END;
- END Init;
- (*%E *)
- (**************************)
- (****** OS/2 Section ******)
- (**************************)
- (*%T _OS2 *)
- PROCEDURE Multi(): MultiMode;
- BEGIN
- RETURN _multi_yes;
- END Multi;
- PROCEDURE MultiFile(f: File): BOOLEAN;
- BEGIN
- RETURN TRUE;
- END MultiFile;
- (*%F _fptr *)
- (*# save *)
- (*# call(inline=>on) *)
- (*# call(reg_param=>(cx)) *)
- (*# call(reg_return=>(cx,dx)) *)
- (*# call(reg_saved=>(ax,bx,cx,si,di,ds,es,st1,st2)) *)
- (*# data(near_ptr=>off) *)
- TYPE
- A6 = ARRAY[0..5] OF SHORTCARD;
- LR_PTR = POINTER TO Dos.LOCKRANGE;
- PROCEDURE LR_ptr(a: NearADDRESS): LR_PTR=A6(033H,0D2H, (* xor dx,dx *)
- 0E3H,002H, (* jcxz $0 *)
- 08CH,0DAH);(* mov dx,ds *)
- (* $0: *)
- (*# restore *)
- (*%E *)
- PROCEDURE FileLocks(f: File; VAR unlock,lock: LockRec): CARDINAL;
- BEGIN
- (*%T _fptr *)
- RETURN Dos.FileLocks(f,Dos.LOCKRANGE(unlock),Dos.LOCKRANGE(lock));
- (*%E *)
- (*%F _fptr *)
- RETURN Dos.FileLocks(f,LR_ptr(ADR(unlock))^,LR_ptr(ADR(lock))^);
- (*%E *)
- END FileLocks;
- (*# save *)
- (*%T _fcall *) (*# call(near_call=>off) *) (*%E *)
- PROCEDURE DelayDefault();
- BEGIN
- Dos.Sleep(DelayDefaultValue);
- END DelayDefault;
- (*# restore *)
- PROCEDURE Init();
- BEGIN
- END Init;
- (*%E *)
- (****************************)
- (****** Common Section ******)
- (****************************)
- PROCEDURE Open(Name: ARRAY OF CHAR; Share,ReadOnly,Create: BOOLEAN): File;
- TYPE
- Mn = ARRAY BOOLEAN OF BITSET;
- Mj = ARRAY BOOLEAN OF Mn;
- ST = ARRAY[0..64] OF CHAR;
- CONST
- m_Std = {};
- m_ReadWrite = {1};
- m_ReadOnly = {};
- m_DenyAll = {4};
- m_DenyWrite = {5};
- m_DenyNone = {6};
- M = Mj(Mn((m_Std+m_ReadWrite+m_DenyAll),
- (m_Std+m_ReadWrite+m_DenyNone)),
- Mn((m_Std+m_ReadOnly +m_DenyAll),
- (m_Std+m_ReadOnly +m_DenyWrite)));
- m_Test = (m_Std+m_ReadOnly+m_DenyNone);
- VAR
- multi : BOOLEAN;
- h : File;
- savesharemode : BITSET;
- BEGIN
- IF Create AND (ReadOnly OR Share) THEN
- RETURN MAX(CARDINAL);
- END;
- (*%T _mthread *) (*%F _OS2*) Process.Lock(); (*%E*) (*%E *)
- IF Create THEN
- h := FIO.Create(ST(Name));
- ELSE
- savesharemode := FIO.ShareMode;
- IF Share AND (_multi_mode=_multi_file) THEN
- FIO.ShareMode := m_Test;
- h := FIO.OpenRead(ST(Name));
- multi := MultiFile(h);
- FIO.Close(h);
- ELSE
- multi := _multi_mode=_multi_yes;
- END;
- FIO.ShareMode := M[ReadOnly,Share AND multi];
- h := FIO.OpenRead(ST(Name));
- FIO.ShareMode := savesharemode;
- END;
- (*%T _mthread *) (*%F _OS2*) Process.Unlock(); (*%E *) (*%E*)
- RETURN h;
- END Open;
- PROCEDURE Truncate(f: File; l: LONGCARD);
- VAR
- s : LONGCARD;
- BEGIN
- s := Size(f);
- IF FIO.IOresult()=0 THEN
- IF s<l THEN
- Seek(f,l-1);
- IF FIO.IOresult()=0 THEN
- Write(f,0,1);
- IF FIO.IOresult()<>0 THEN
- LocalError := FIO.IOresult();
- IF (Size(f)#s) THEN
- Truncate(f,s);
- END;
- END;
- END;
- ELSIF s>l THEN
- Seek(f,l);
- FIO.Truncate(f);
- END;
- END;
- END Truncate;
- CONST
- Locking = _mthread AND NOT _OS2;
- (*# save *)
- (*# call(result_optional=>on) *)
- PROCEDURE Common(f: File; x: LockRec; l: BOOLEAN): BOOLEAN;
- VAR
- cnt,
- res : CARDINAL;
- BEGIN
- cnt := RetryCount();
- LOOP
- IF l THEN
- res := FileLocks(f,NULL^,x);
- ELSE
- res := FileLocks(f,x,NULL^);
- END;
- IF (res=NO_ERROR) OR (cnt=0) OR NOT l THEN
- EXIT;
- END;
- DEC(cnt);
- Delay();
- END;
- RETURN res=NO_ERROR;
- END Common;
- (*# restore *)
- PROCEDURE Lock(f: File; x: LockRec): BOOLEAN;
- BEGIN
- RETURN Common(f,x,TRUE);
- END Lock;
- PROCEDURE UnLock(f: File; x: LockRec);
- BEGIN
- Common(f,x,FALSE);
- END UnLock;
- (*# save *)
- (*# call(o_a_size=>on) *)
- (*# call(o_a_copy=>off) *)
- (*# call(result_optional=>on) *)
- PROCEDURE RangeCommon(f: File; x: ARRAY OF LockRec; lock: BOOLEAN): BOOLEAN;
- VAR
- i,
- j : CARDINAL;
- res : BOOLEAN;
- BEGIN
- res := TRUE;
- i := 0;
- LOOP
- IF NOT res OR (i>HIGH(x)) OR (x[i].pos=MAX(LONGCARD)) THEN
- EXIT;
- END;
- res := Common(f,x[i],lock);
- INC(i);
- END;
- IF NOT res AND (i>1) THEN
- DEC(i);
- LOOP
- DEC(i);
- Common(f,x[i],NOT lock);
- IF i = 0 THEN
- EXIT;
- END;
- END;
- END;
- RETURN res;
- END RangeCommon;
- (*# restore *)
- (*# save *)
- (*# call(o_a_size=>on) *)
- (*# call(o_a_copy=>off) *)
- PROCEDURE LockRange(f: File; x: ARRAY OF LockRec): BOOLEAN;
- BEGIN
- RETURN RangeCommon(f,x,TRUE);
- END LockRange;
- (*# restore *)
- (*# save *)
- (*# call(o_a_size=>on) *)
- (*# call(o_a_copy=>off) *)
- PROCEDURE UnLockRange(f: File; x: ARRAY OF LockRec);
- BEGIN
- RangeCommon(f,x,FALSE);
- END UnLockRange;
- (*# restore *)
- PROCEDURE Error(): CARDINAL;
- VAR res : CARDINAL;
- BEGIN
- IF LocalError<>0 THEN
- LocalError := 0;
- ELSE
- res := FIO.IOresult();
- END;
- RETURN res;
- END Error;
- (*# save *)
- (*%T _fcall *) (*# call(near_call=>off) *) (*%E *)
- PROCEDURE RetryCountDefault() : CARDINAL;
- BEGIN
- RETURN RetryCountDefaultValue;
- END RetryCountDefault;
- (*# restore *)
- PROCEDURE Read(f: File; VAR b: ARRAY OF BYTE; c: CARDINAL);
- VAR p : ADDRESS;
- BEGIN
- p := ADR(b);
- IF FIO.RdBin(f,p^,c)<>c THEN
- LocalError := PAST_EOF;
- END;
- END Read;
- PROCEDURE Write(f: File; b: ARRAY OF BYTE; c: CARDINAL);
- VAR p : ADDRESS;
- BEGIN
- p := ADR(b);
- FIO.WrBin(f,p^,c);
- IF FIO.IOresult()=FIO.DiskFull THEN
- LocalError := PAST_EOF;
- END;
- END Write;
- BEGIN
- _multi_mode := _multi_yes;
- LocalError := 0;
- RetryCount := RetryCountDefault;
- Delay := DelayDefault;
- Init();
- END FIOx.
|