FIOX.MOD 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. (*# call(o_a_size=>off) *)
  2. (*# call(o_a_copy=>off) *)
  3. (*# call(near_call=>on) *)
  4. IMPLEMENTATION MODULE FIOx;
  5. (*
  6. Copyright (C) 1988,1989,1990 Jensen & Partners International
  7. *)
  8. IMPORT FIO;
  9. (*%T _OS2 *) IMPORT Dos; (*%E*)
  10. (*%F _OS2 *) IMPORT Lib, SYSTEM, Str (*%T _mthread *),Process (*%E *); (*%E*)
  11. VAR
  12. _multi_mode : MultiMode;
  13. LocalError : CARDINAL;
  14. (*************************)
  15. (****** DOS Section ******)
  16. (*************************)
  17. (*%F _OS2 *)
  18. VAR
  19. DosVerMaj,
  20. DosVerMin : SHORTCARD;
  21. PROCEDURE FileLocks(f: File; VAR unlock,lock: LockRec): CARDINAL;
  22. VAR
  23. regs : SYSTEM.Registers;
  24. tmp : POINTER TO LockRec;
  25. mode : SHORTCARD;
  26. BEGIN
  27. mode := 1;
  28. tmp := SYSTEM.ADR(unlock);
  29. LOOP
  30. IF tmp#NIL THEN
  31. WITH regs DO
  32. AH := 5CH;
  33. AL := mode;
  34. BX := f;
  35. CX := CARDINAL(tmp^.pos DIV 65536);
  36. DX := CARDINAL(tmp^.pos MOD 65536);
  37. SI := CARDINAL(tmp^.len DIV 65536);
  38. DI := CARDINAL(tmp^.len MOD 65536);
  39. END;
  40. (*%T _mthread *) Process.Lock(); (*%E *)
  41. Lib.Dos(regs);
  42. (*%T _mthread *) Process.Unlock(); (*%E *)
  43. IF SYSTEM.CarryFlag IN regs.Flags THEN
  44. RETURN regs.AX;
  45. END;
  46. END;
  47. IF mode=0 THEN
  48. EXIT;
  49. END;
  50. tmp := SYSTEM.ADR(lock);
  51. DEC(mode);
  52. END;
  53. RETURN NO_ERROR;
  54. END FileLocks;
  55. PROCEDURE Multi(): MultiMode;
  56. BEGIN
  57. RETURN _multi_mode;
  58. END Multi;
  59. PROCEDURE MultiFile(f: File): BOOLEAN;
  60. VAR
  61. regs : SYSTEM.Registers;
  62. BEGIN
  63. IF _multi_mode=_multi_file THEN
  64. WITH regs DO
  65. AH := 44H;
  66. AL := 0AH;
  67. BX := f;
  68. Lib.Dos(regs);
  69. RETURN NOT (SYSTEM.CarryFlag IN Flags) AND (15 IN BITSET(DX));
  70. END;
  71. ELSE
  72. RETURN _multi_mode=_multi_yes;
  73. END;
  74. END MultiFile;
  75. (*# save *)
  76. (*%T _fcall *) (*# call(near_call=>off) *) (*%E *)
  77. PROCEDURE DelayDefault();
  78. BEGIN
  79. (*%T _mthread *) Process.Delay(DelayDefaultValue DIV 50); (*%E *)
  80. (*%F _mthread *) Lib.Delay(DelayDefaultValue); (*%E *)
  81. END DelayDefault;
  82. (*# restore *)
  83. PROCEDURE Init;
  84. VAR
  85. regs : SYSTEM.Registers;
  86. str : ARRAY[0..5] OF CHAR;
  87. BEGIN
  88. _multi_mode := _multi_file;
  89. WITH regs DO
  90. AH := 30H;
  91. Lib.Dos(regs);
  92. DosVerMaj := AL;
  93. DosVerMin := AH;
  94. Lib.EnvironmentFind('multi',str);
  95. Str.Caps(str);
  96. IF Str.Compare(str,'YES')=0 THEN
  97. _multi_mode := _multi_yes;
  98. ELSIF Str.Compare(str,'NO')=0 THEN
  99. _multi_mode := _multi_no;
  100. ELSIF DosVerMaj >= 3 THEN
  101. AH := 10H;
  102. AL := 0;
  103. Lib.Intr(regs,2FH);
  104. IF AL=0FFH THEN
  105. _multi_mode := _multi_yes;
  106. END;
  107. END;
  108. END;
  109. END Init;
  110. (*%E *)
  111. (**************************)
  112. (****** OS/2 Section ******)
  113. (**************************)
  114. (*%T _OS2 *)
  115. PROCEDURE Multi(): MultiMode;
  116. BEGIN
  117. RETURN _multi_yes;
  118. END Multi;
  119. PROCEDURE MultiFile(f: File): BOOLEAN;
  120. BEGIN
  121. RETURN TRUE;
  122. END MultiFile;
  123. (*%F _fptr *)
  124. (*# save *)
  125. (*# call(inline=>on) *)
  126. (*# call(reg_param=>(cx)) *)
  127. (*# call(reg_return=>(cx,dx)) *)
  128. (*# call(reg_saved=>(ax,bx,cx,si,di,ds,es,st1,st2)) *)
  129. (*# data(near_ptr=>off) *)
  130. TYPE
  131. A6 = ARRAY[0..5] OF SHORTCARD;
  132. LR_PTR = POINTER TO Dos.LOCKRANGE;
  133. PROCEDURE LR_ptr(a: NearADDRESS): LR_PTR=A6(033H,0D2H, (* xor dx,dx *)
  134. 0E3H,002H, (* jcxz $0 *)
  135. 08CH,0DAH);(* mov dx,ds *)
  136. (* $0: *)
  137. (*# restore *)
  138. (*%E *)
  139. PROCEDURE FileLocks(f: File; VAR unlock,lock: LockRec): CARDINAL;
  140. BEGIN
  141. (*%T _fptr *)
  142. RETURN Dos.FileLocks(f,Dos.LOCKRANGE(unlock),Dos.LOCKRANGE(lock));
  143. (*%E *)
  144. (*%F _fptr *)
  145. RETURN Dos.FileLocks(f,LR_ptr(ADR(unlock))^,LR_ptr(ADR(lock))^);
  146. (*%E *)
  147. END FileLocks;
  148. (*# save *)
  149. (*%T _fcall *) (*# call(near_call=>off) *) (*%E *)
  150. PROCEDURE DelayDefault();
  151. BEGIN
  152. Dos.Sleep(DelayDefaultValue);
  153. END DelayDefault;
  154. (*# restore *)
  155. PROCEDURE Init();
  156. BEGIN
  157. END Init;
  158. (*%E *)
  159. (****************************)
  160. (****** Common Section ******)
  161. (****************************)
  162. PROCEDURE Open(Name: ARRAY OF CHAR; Share,ReadOnly,Create: BOOLEAN): File;
  163. TYPE
  164. Mn = ARRAY BOOLEAN OF BITSET;
  165. Mj = ARRAY BOOLEAN OF Mn;
  166. ST = ARRAY[0..64] OF CHAR;
  167. CONST
  168. m_Std = {};
  169. m_ReadWrite = {1};
  170. m_ReadOnly = {};
  171. m_DenyAll = {4};
  172. m_DenyWrite = {5};
  173. m_DenyNone = {6};
  174. M = Mj(Mn((m_Std+m_ReadWrite+m_DenyAll),
  175. (m_Std+m_ReadWrite+m_DenyNone)),
  176. Mn((m_Std+m_ReadOnly +m_DenyAll),
  177. (m_Std+m_ReadOnly +m_DenyWrite)));
  178. m_Test = (m_Std+m_ReadOnly+m_DenyNone);
  179. VAR
  180. multi : BOOLEAN;
  181. h : File;
  182. savesharemode : BITSET;
  183. BEGIN
  184. IF Create AND (ReadOnly OR Share) THEN
  185. RETURN MAX(CARDINAL);
  186. END;
  187. (*%T _mthread *) (*%F _OS2*) Process.Lock(); (*%E*) (*%E *)
  188. IF Create THEN
  189. h := FIO.Create(ST(Name));
  190. ELSE
  191. savesharemode := FIO.ShareMode;
  192. IF Share AND (_multi_mode=_multi_file) THEN
  193. FIO.ShareMode := m_Test;
  194. h := FIO.OpenRead(ST(Name));
  195. multi := MultiFile(h);
  196. FIO.Close(h);
  197. ELSE
  198. multi := _multi_mode=_multi_yes;
  199. END;
  200. FIO.ShareMode := M[ReadOnly,Share AND multi];
  201. h := FIO.OpenRead(ST(Name));
  202. FIO.ShareMode := savesharemode;
  203. END;
  204. (*%T _mthread *) (*%F _OS2*) Process.Unlock(); (*%E *) (*%E*)
  205. RETURN h;
  206. END Open;
  207. PROCEDURE Truncate(f: File; l: LONGCARD);
  208. VAR
  209. s : LONGCARD;
  210. BEGIN
  211. s := Size(f);
  212. IF FIO.IOresult()=0 THEN
  213. IF s<l THEN
  214. Seek(f,l-1);
  215. IF FIO.IOresult()=0 THEN
  216. Write(f,0,1);
  217. IF FIO.IOresult()<>0 THEN
  218. LocalError := FIO.IOresult();
  219. IF (Size(f)#s) THEN
  220. Truncate(f,s);
  221. END;
  222. END;
  223. END;
  224. ELSIF s>l THEN
  225. Seek(f,l);
  226. FIO.Truncate(f);
  227. END;
  228. END;
  229. END Truncate;
  230. CONST
  231. Locking = _mthread AND NOT _OS2;
  232. (*# save *)
  233. (*# call(result_optional=>on) *)
  234. PROCEDURE Common(f: File; x: LockRec; l: BOOLEAN): BOOLEAN;
  235. VAR
  236. cnt,
  237. res : CARDINAL;
  238. BEGIN
  239. cnt := RetryCount();
  240. LOOP
  241. IF l THEN
  242. res := FileLocks(f,NULL^,x);
  243. ELSE
  244. res := FileLocks(f,x,NULL^);
  245. END;
  246. IF (res=NO_ERROR) OR (cnt=0) OR NOT l THEN
  247. EXIT;
  248. END;
  249. DEC(cnt);
  250. Delay();
  251. END;
  252. RETURN res=NO_ERROR;
  253. END Common;
  254. (*# restore *)
  255. PROCEDURE Lock(f: File; x: LockRec): BOOLEAN;
  256. BEGIN
  257. RETURN Common(f,x,TRUE);
  258. END Lock;
  259. PROCEDURE UnLock(f: File; x: LockRec);
  260. BEGIN
  261. Common(f,x,FALSE);
  262. END UnLock;
  263. (*# save *)
  264. (*# call(o_a_size=>on) *)
  265. (*# call(o_a_copy=>off) *)
  266. (*# call(result_optional=>on) *)
  267. PROCEDURE RangeCommon(f: File; x: ARRAY OF LockRec; lock: BOOLEAN): BOOLEAN;
  268. VAR
  269. i,
  270. j : CARDINAL;
  271. res : BOOLEAN;
  272. BEGIN
  273. res := TRUE;
  274. i := 0;
  275. LOOP
  276. IF NOT res OR (i>HIGH(x)) OR (x[i].pos=MAX(LONGCARD)) THEN
  277. EXIT;
  278. END;
  279. res := Common(f,x[i],lock);
  280. INC(i);
  281. END;
  282. IF NOT res AND (i>1) THEN
  283. DEC(i);
  284. LOOP
  285. DEC(i);
  286. Common(f,x[i],NOT lock);
  287. IF i = 0 THEN
  288. EXIT;
  289. END;
  290. END;
  291. END;
  292. RETURN res;
  293. END RangeCommon;
  294. (*# restore *)
  295. (*# save *)
  296. (*# call(o_a_size=>on) *)
  297. (*# call(o_a_copy=>off) *)
  298. PROCEDURE LockRange(f: File; x: ARRAY OF LockRec): BOOLEAN;
  299. BEGIN
  300. RETURN RangeCommon(f,x,TRUE);
  301. END LockRange;
  302. (*# restore *)
  303. (*# save *)
  304. (*# call(o_a_size=>on) *)
  305. (*# call(o_a_copy=>off) *)
  306. PROCEDURE UnLockRange(f: File; x: ARRAY OF LockRec);
  307. BEGIN
  308. RangeCommon(f,x,FALSE);
  309. END UnLockRange;
  310. (*# restore *)
  311. PROCEDURE Error(): CARDINAL;
  312. VAR res : CARDINAL;
  313. BEGIN
  314. IF LocalError<>0 THEN
  315. LocalError := 0;
  316. ELSE
  317. res := FIO.IOresult();
  318. END;
  319. RETURN res;
  320. END Error;
  321. (*# save *)
  322. (*%T _fcall *) (*# call(near_call=>off) *) (*%E *)
  323. PROCEDURE RetryCountDefault() : CARDINAL;
  324. BEGIN
  325. RETURN RetryCountDefaultValue;
  326. END RetryCountDefault;
  327. (*# restore *)
  328. PROCEDURE Read(f: File; VAR b: ARRAY OF BYTE; c: CARDINAL);
  329. VAR p : ADDRESS;
  330. BEGIN
  331. p := ADR(b);
  332. IF FIO.RdBin(f,p^,c)<>c THEN
  333. LocalError := PAST_EOF;
  334. END;
  335. END Read;
  336. PROCEDURE Write(f: File; b: ARRAY OF BYTE; c: CARDINAL);
  337. VAR p : ADDRESS;
  338. BEGIN
  339. p := ADR(b);
  340. FIO.WrBin(f,p^,c);
  341. IF FIO.IOresult()=FIO.DiskFull THEN
  342. LocalError := PAST_EOF;
  343. END;
  344. END Write;
  345. BEGIN
  346. _multi_mode := _multi_yes;
  347. LocalError := 0;
  348. RetryCount := RetryCountDefault;
  349. Delay := DelayDefault;
  350. Init();
  351. END FIOx.
  352.