file.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. {
  2. This file is part of the Free Pascal Run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WithOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {****************************************************************************
  11. subroutines For UnTyped File handling
  12. ****************************************************************************}
  13. type
  14. UnTypedFile=File;
  15. procedure InitFile(var f : file);
  16. begin
  17. FillChar(f,SizeOf(FileRec),0);
  18. FileRec(f).Handle:=UnusedHandle;
  19. FileRec(f).mode:=fmClosed;
  20. end;
  21. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  22. Procedure Assign(out f:File;const Name: UnicodeString);
  23. {
  24. Assign Name to file f so it can be used with the file routines
  25. }
  26. Begin
  27. InitFile(F);
  28. {$ifdef FPC_ANSI_TEXTFILEREC}
  29. FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(Name);
  30. {$else FPC_ANSI_TEXTFILEREC}
  31. FileRec(f).Name:=Name;
  32. {$endif FPC_ANSI_TEXTFILEREC}
  33. { null terminate, since the name array is regularly used as p(wide)char }
  34. FileRec(f).Name[high(FileRec(f).Name)]:=#0;
  35. End;
  36. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  37. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  38. Procedure Assign(out f:File;const Name: RawByteString);
  39. {
  40. Assign Name to file f so it can be used with the file routines
  41. }
  42. Begin
  43. InitFile(F);
  44. {$ifdef FPC_ANSI_TEXTFILEREC}
  45. { ensure the characters in the record's filename are encoded correctly }
  46. FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(Name);
  47. {$else FPC_ANSI_TEXTFILEREC}
  48. FileRec(f).Name:=Name;
  49. {$endif FPC_ANSI_TEXTFILEREC}
  50. { null terminate, since the name array is regularly used as p(wide)char }
  51. FileRec(f).Name[high(FileRec(f).Name)]:=#0;
  52. End;
  53. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  54. Procedure Assign(out f:File;const Name: ShortString);
  55. {
  56. Assign Name to file f so it can be used with the file routines
  57. }
  58. Begin
  59. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  60. Assign(f,AnsiString(Name));
  61. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  62. InitFile(f);
  63. { warning: no encoding support }
  64. FileRec(f).Name:=Name;
  65. { null terminate, since the name array is regularly used as p(wide)char }
  66. FileRec(f).Name[high(FileRec(f).Name)]:=#0;
  67. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  68. End;
  69. Procedure Assign(out f:File;const p: PAnsiChar);
  70. Begin
  71. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  72. Assign(f,AnsiString(p));
  73. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  74. { no use in making this the one that does the work, since the name field is
  75. limited to 255 characters anyway }
  76. Assign(f,strpas(p));
  77. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  78. End;
  79. Procedure Assign(out f:File;const c: AnsiChar);
  80. Begin
  81. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  82. Assign(f,AnsiString(c));
  83. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  84. Assign(f,ShortString(c));
  85. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  86. End;
  87. Procedure Rewrite(var f:File;l:Longint);[IOCheck];
  88. {
  89. Create file f with recordsize of l
  90. }
  91. Begin
  92. If InOutRes <> 0 then
  93. exit;
  94. Case FileRec(f).mode Of
  95. fmInOut,fmInput,fmOutput : Close(f);
  96. fmClosed : ;
  97. else
  98. Begin
  99. InOutRes:=102;
  100. exit;
  101. End;
  102. End;
  103. If l=0 Then
  104. InOutRes:=2
  105. else
  106. Begin
  107. { Reopen with filemode 2, to be Tp compatible (PFV) }
  108. Do_Open(f,PFileTextRecChar(@FileRec(f).Name),$1002,false);
  109. FileRec(f).RecSize:=l;
  110. End;
  111. End;
  112. Procedure Reset(var f:File;l:Longint);[IOCheck];
  113. {
  114. Open file f with recordsize of l and filemode
  115. }
  116. Begin
  117. If InOutRes <> 0 then
  118. Exit;
  119. Case FileRec(f).mode Of
  120. fmInOut,fmInput,fmOutput : Close(f);
  121. fmClosed : ;
  122. else
  123. Begin
  124. InOutRes:=102;
  125. exit;
  126. End;
  127. End;
  128. If l=0 Then
  129. InOutRes:=2
  130. else
  131. Begin
  132. Do_Open(f,PFileTextRecChar(@FileRec(f).Name),Filemode,false);
  133. FileRec(f).RecSize:=l;
  134. End;
  135. End;
  136. Procedure Rewrite(Var f:File);[IOCheck];
  137. {
  138. Create file with (default) 128 byte records
  139. }
  140. Begin
  141. If InOutRes <> 0 then
  142. exit;
  143. Rewrite(f,128);
  144. End;
  145. Procedure Reset(Var f:File);[IOCheck];
  146. {
  147. Open file with (default) 128 byte records
  148. }
  149. Begin
  150. If InOutRes <> 0 then
  151. exit;
  152. Reset(f,128);
  153. End;
  154. Procedure BlockWrite(Var f:File;Const Buf;Count:Int64;var Result:Int64);[IOCheck];
  155. {
  156. Write Count records from Buf to file f, return written records in result
  157. }
  158. Begin
  159. Result:=0;
  160. If InOutRes <> 0 then
  161. exit;
  162. case FileRec(f).Mode of
  163. fmInOut,fmOutput :
  164. Result:=Do_Write(FileRec(f).Handle,@Buf,Count*FileRec(f).RecSize)
  165. div FileRec(f).RecSize;
  166. fmInPut: inOutRes := 105;
  167. else InOutRes:=103;
  168. end;
  169. End;
  170. Procedure BlockWrite(Var f:File;Const Buf;Count:Longint;var Result:Longint);[IOCheck];
  171. {
  172. Write Count records from Buf to file f, return written records in result
  173. }
  174. var
  175. l : Int64;
  176. Begin
  177. BlockWrite(f,Buf,Count,l);
  178. Result:=longint(l);
  179. End;
  180. Procedure BlockWrite(Var f:File;Const Buf;Count:Word;var Result:Word);[IOCheck];
  181. {
  182. Write Count records from Buf to file f, return written records in Result
  183. }
  184. var
  185. l : Int64;
  186. Begin
  187. BlockWrite(f,Buf,Count,l);
  188. Result:=word(l);
  189. End;
  190. Procedure BlockWrite(Var f:File;Const Buf;Count:Cardinal;var Result:Cardinal);[IOCheck];
  191. {
  192. Write Count records from Buf to file f, return written records in Result
  193. }
  194. var
  195. l : Int64;
  196. Begin
  197. BlockWrite(f,Buf,Count,l);
  198. Result:=l;
  199. End;
  200. Procedure BlockWrite(Var f:File;Const Buf;Count:Word;var Result:Integer);[IOCheck];
  201. {
  202. Write Count records from Buf to file f, return written records in Result
  203. }
  204. var
  205. l : Int64;
  206. Begin
  207. BlockWrite(f,Buf,Count,l);
  208. Result:=integer(l);
  209. End;
  210. Procedure BlockWrite(Var f:File;Const Buf;Count:Longint);[IOCheck];
  211. {
  212. Write Count records from Buf to file f, if none a Read and Count>0 then
  213. InOutRes is set
  214. }
  215. var
  216. Result : Int64;
  217. Begin
  218. BlockWrite(f,Buf,Count,Result);
  219. If (InOutRes=0) and (Result<Count) and (Count>0) Then
  220. InOutRes:=101;
  221. End;
  222. Procedure BlockRead(var f:File;var Buf;Count:Int64;var Result:Int64);[IOCheck];
  223. {
  224. Read Count records from file f ro Buf, return number of read records in
  225. Result
  226. }
  227. Begin
  228. Result:=0;
  229. If InOutRes <> 0 then
  230. exit;
  231. case FileRec(f).Mode of
  232. fmInOut,fmInput :
  233. Result:=Do_Read(FileRec(f).Handle,@Buf,count*FileRec(f).RecSize)
  234. div FileRec(f).RecSize;
  235. fmOutput: inOutRes := 104;
  236. else InOutRes:=103;
  237. end;
  238. End;
  239. Procedure BlockRead(var f:File;var Buf;Count:Longint;var Result:Longint);[IOCheck];
  240. {
  241. Read Count records from file f ro Buf, return number of read records in
  242. Result
  243. }
  244. var
  245. l : int64;
  246. Begin
  247. BlockRead(f,Buf,Count,l);
  248. Result:=longint(l);
  249. End;
  250. Procedure BlockRead(var f:File;var Buf;count:Word;var Result:Word);[IOCheck];
  251. {
  252. Read Count records from file f to Buf, return number of read records in
  253. Result
  254. }
  255. var
  256. l : int64;
  257. Begin
  258. BlockRead(f,Buf,Count,l);
  259. Result:=word(l);
  260. End;
  261. Procedure BlockRead(var f:File;var Buf;count:Cardinal;var Result:Cardinal);[IOCheck];
  262. {
  263. Read Count records from file f to Buf, return number of read records in
  264. Result
  265. }
  266. var
  267. l : int64;
  268. Begin
  269. BlockRead(f,Buf,Count,l);
  270. Result:=l;
  271. End;
  272. Procedure BlockRead(var f:File;var Buf;count:Word;var Result:Integer);[IOCheck];
  273. {
  274. Read Count records from file f to Buf, return number of read records in
  275. Result
  276. }
  277. var
  278. l : int64;
  279. Begin
  280. BlockRead(f,Buf,Count,l);
  281. Result:=integer(l);
  282. End;
  283. Procedure BlockRead(Var f:File;Var Buf;Count:Int64);[IOCheck];
  284. {
  285. Read Count records from file f to Buf, if none are read and Count>0 then
  286. InOutRes is set
  287. }
  288. var
  289. Result : int64;
  290. Begin
  291. BlockRead(f,Buf,Count,Result);
  292. If (InOutRes=0) and (Result<Count) and (Count>0) Then
  293. InOutRes:=100;
  294. End;
  295. Function FilePos(var f:File):Int64;[IOCheck];
  296. {
  297. Return current Position In file f in records
  298. }
  299. Begin
  300. FilePos:=0;
  301. If InOutRes <> 0 then
  302. exit;
  303. case FileRec(f).Mode of
  304. fmInOut,fmInput,fmOutput :
  305. FilePos:=Do_FilePos(FileRec(f).Handle) div FileRec(f).RecSize;
  306. else
  307. InOutRes:=103;
  308. end;
  309. End;
  310. Function FileSize(var f:File):Int64;[IOCheck];
  311. {
  312. Return the size of file f in records
  313. }
  314. Begin
  315. FileSize:=0;
  316. If InOutRes <> 0 then
  317. exit;
  318. case FileRec(f).Mode of
  319. fmInOut,fmInput,fmOutput :
  320. begin
  321. if (FileRec(f).RecSize>0) then
  322. FileSize:=Do_FileSize(FileRec(f).Handle) div FileRec(f).RecSize;
  323. end;
  324. else InOutRes:=103;
  325. end;
  326. End;
  327. Function Eof(var f:File):Boolean;[IOCheck];
  328. {
  329. Return True if we're at the end of the file f, else False is returned
  330. }
  331. Begin
  332. Eof:=false;
  333. If InOutRes <> 0 then
  334. exit;
  335. case FileRec(f).Mode of
  336. {Can't use do_ routines because we need record support}
  337. fmInOut,fmInput,fmOutput : Eof:=(FileSize(f)<=FilePos(f));
  338. else InOutRes:=103;
  339. end;
  340. End;
  341. Procedure Seek(var f:File;Pos:Int64);[IOCheck];
  342. {
  343. Goto record Pos in file f
  344. }
  345. Begin
  346. If InOutRes <> 0 then
  347. exit;
  348. case FileRec(f).Mode of
  349. fmInOut,fmInput,fmOutput :
  350. Do_Seek(FileRec(f).Handle,Pos*FileRec(f).RecSize);
  351. else InOutRes:=103;
  352. end;
  353. End;
  354. Procedure Truncate(Var f:File);[IOCheck];
  355. {
  356. Truncate/Cut file f at the current record Position
  357. }
  358. Begin
  359. If InOutRes <> 0 then
  360. exit;
  361. case FileRec(f).Mode of
  362. fmInOut,fmOutput :
  363. Do_Truncate(FileRec(f).Handle,FilePos(f)*FileRec(f).RecSize);
  364. else InOutRes:=103;
  365. end;
  366. End;
  367. Procedure Close(var f:File);[IOCheck];
  368. {
  369. Close file f
  370. }
  371. Begin
  372. If InOutRes <> 0 then
  373. exit;
  374. case FileRec(f).Mode of
  375. fmInOut,fmInput,fmOutput :
  376. begin
  377. Do_Close(FileRec(f).Handle);
  378. FileRec(f).mode:=fmClosed;
  379. end
  380. else InOutRes:=103;
  381. end;
  382. End;
  383. Procedure Erase(var f : File);[IOCheck];
  384. Begin
  385. If InOutRes <> 0 then
  386. exit;
  387. If FileRec(f).mode=fmClosed Then
  388. Do_Erase(PFileTextRecChar(@FileRec(f).Name),false);
  389. End;
  390. Procedure Rename(var f : File; const S : UnicodeString);[IOCheck];
  391. {$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  392. var
  393. fs: RawByteString;
  394. {$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  395. Begin
  396. If (InOutRes<>0) or
  397. (FileRec(f).mode<>fmClosed) then
  398. exit;
  399. {$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  400. { it's slightly faster to convert the unicodestring here to rawbytestring
  401. than doing it in do_rename(), because here we still know the length }
  402. fs:=ToSingleByteFileSystemEncodedFileName(s);
  403. Do_Rename(PFileTextRecChar(@FileRec(f).Name),PAnsiChar(fs),false,true);
  404. If InOutRes=0 then
  405. FileRec(f).Name:=fs
  406. {$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  407. Do_Rename(PFileTextRecChar(@FileRec(f).Name),PUnicodeChar(S),false,false);
  408. If InOutRes=0 then
  409. {$ifdef FPC_ANSI_TEXTFILEREC}
  410. FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(s);
  411. {$else FPC_ANSI_TEXTFILEREC}
  412. FileRec(f).Name:=s
  413. {$endif FPC_ANSI_TEXTFILEREC}
  414. {$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  415. End;
  416. Procedure Rename(var f : File;const s : RawByteString);[IOCheck];
  417. var
  418. {$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  419. fs: RawByteString;
  420. pdst: PAnsiChar;
  421. {$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  422. fs: UnicodeString;
  423. pdst: PUnicodeChar;
  424. {$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  425. dstchangeable: boolean;
  426. Begin
  427. If (InOutRes<>0) or
  428. (FileRec(f).mode<>fmClosed) then
  429. exit;
  430. {$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  431. dstchangeable:=false;
  432. pdst:=PAnsiChar(s);
  433. if StringCodePage(s)<>DefaultFileSystemCodePage then
  434. begin
  435. fs:=ToSingleByteFileSystemEncodedFileName(s);
  436. pdst:=PAnsiChar(fs);
  437. dstchangeable:=true;
  438. end
  439. else
  440. fs:=s;
  441. {$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  442. { it's slightly faster to convert the rawbytestring here to unicodestring
  443. than doing it in do_rename, because here we still know the length }
  444. fs:=unicodestring(s);
  445. pdst:=PUnicodeChar(fs);
  446. dstchangeable:=true;
  447. {$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  448. Do_Rename(PFileTextRecChar(@FileRec(f).Name),pdst,false,dstchangeable);
  449. If InOutRes=0 then
  450. {$if defined(FPC_ANSI_TEXTFILEREC) and not defined(FPCRTL_FILESYSTEM_SINGLE_BYTE_API)}
  451. FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(fs)
  452. {$else FPC_ANSI_TEXTFILEREC and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  453. FileRec(f).Name:=fs
  454. {$endif FPC_ANSI_TEXTFILEREC and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
  455. End;
  456. Procedure Rename(var f : File;const s : ShortString);[IOCheck];
  457. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  458. Begin
  459. Rename(f,AnsiString(s));
  460. End;
  461. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  462. var
  463. p : array[0..255] Of Char;
  464. Begin
  465. Move(s[1],p,Length(s));
  466. p[Length(s)]:=#0;
  467. Rename(f,Pchar(@p));
  468. End;
  469. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  470. Procedure Rename(var f:File;const p : PAnsiChar);[IOCheck];
  471. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  472. Begin
  473. Rename(f,AnsiString(p));
  474. End;
  475. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  476. var
  477. len: SizeInt
  478. Begin
  479. If InOutRes<>0 then
  480. exit;
  481. If FileRec(f).mode=fmClosed Then
  482. Begin
  483. Do_Rename(PFileTextRecChar(@FileRec(f).Name),p,false);
  484. { check error code of do_rename }
  485. If InOutRes=0 then
  486. begin
  487. len:=min(StrLen(p),high(FileRec(f).Name));
  488. Move(p^,FileRec(f).Name,len);
  489. FileRec(f).Name[len]:=#0;
  490. end;
  491. End;
  492. End;
  493. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  494. Procedure Rename(var f:File;const c : AnsiChar);[IOCheck];
  495. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  496. Begin
  497. Rename(f,AnsiString(c));
  498. End;
  499. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  500. var
  501. p : array[0..1] Of AnsiChar;
  502. Begin
  503. p[0]:=c;
  504. p[1]:=#0;
  505. Rename(f,PAnsiChar(@p));
  506. End;
  507. {$endif FPC_HAS_FEATURE_ANSISTRINGS}