(* BSD 2-Clause License Copyright (c) 2020, Anton Krotov All rights reserved. *) MODULE File; IMPORT SYSTEM, Libdl, API; CONST OPEN_R* = "rb"; OPEN_W* = "wb"; OPEN_RW* = "r+b"; SEEK_BEG* = 0; SEEK_CUR* = 1; SEEK_END* = 2; VAR fwrite, fread : PROCEDURE [linux] (buffer, bytes, blocks, file: INTEGER): INTEGER; fseek : PROCEDURE [linux] (file, offset, origin: INTEGER): INTEGER; ftell : PROCEDURE [linux] (file: INTEGER): INTEGER; fopen : PROCEDURE [linux] (fname, fmode: INTEGER): INTEGER; fclose : PROCEDURE [linux] (file: INTEGER): INTEGER; remove : PROCEDURE [linux] (fname: INTEGER): INTEGER; PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER); VAR sym: INTEGER; BEGIN sym := Libdl.sym(lib, name); ASSERT(sym # 0); SYSTEM.PUT(VarAdr, sym) END GetSym; PROCEDURE init; VAR libc: INTEGER; BEGIN libc := Libdl.open("libc.so.6", Libdl.LAZY); ASSERT(libc # 0); GetSym(libc, "fread", SYSTEM.ADR(fread)); GetSym(libc, "fwrite", SYSTEM.ADR(fwrite)); GetSym(libc, "fseek", SYSTEM.ADR(fseek)); GetSym(libc, "ftell", SYSTEM.ADR(ftell)); GetSym(libc, "fopen", SYSTEM.ADR(fopen)); GetSym(libc, "fclose", SYSTEM.ADR(fclose)); GetSym(libc, "remove", SYSTEM.ADR(remove)); END init; PROCEDURE Delete* (FName: ARRAY OF CHAR): BOOLEAN; RETURN remove(SYSTEM.ADR(FName[0])) = 0 END Delete; PROCEDURE Close* (F: INTEGER); BEGIN F := fclose(F) END Close; PROCEDURE Open* (FName, Mode: ARRAY OF CHAR): INTEGER; RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.ADR(Mode[0])) END Open; PROCEDURE Create* (FName: ARRAY OF CHAR): INTEGER; RETURN Open(FName, OPEN_W) END Create; PROCEDURE Seek* (F, Offset, Origin: INTEGER): INTEGER; VAR res: INTEGER; BEGIN IF fseek(F, Offset, Origin) = 0 THEN res := ftell(F) ELSE res := -1 END RETURN res END Seek; PROCEDURE Write* (F, Buffer, Count: INTEGER): INTEGER; RETURN fwrite(Buffer, 1, Count, F) END Write; PROCEDURE Read* (F, Buffer, Count: INTEGER): INTEGER; RETURN fread(Buffer, 1, Count, F) END Read; PROCEDURE Load* (FName: ARRAY OF CHAR; VAR Size: INTEGER): INTEGER; VAR res, n, F: INTEGER; BEGIN res := 0; F := Open(FName, OPEN_R); IF F > 0 THEN Size := Seek(F, 0, SEEK_END); n := Seek(F, 0, SEEK_BEG); res := API._NEW(Size); IF (res = 0) OR (Read(F, res, Size) # Size) THEN IF res # 0 THEN res := API._DISPOSE(res); Size := 0 END END; Close(F) END RETURN res END Load; BEGIN init END File.