(* Copyright 2016, 2018, 2021 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . *) MODULE File; IMPORT sys := SYSTEM, KOSAPI; CONST SEEK_BEG* = 0; SEEK_CUR* = 1; SEEK_END* = 2; TYPE FNAME* = ARRAY 520 OF CHAR; FS* = POINTER TO rFS; rFS* = RECORD subfunc*, pos*, hpos*, bytes*, buffer*: INTEGER; name*: FNAME END; FD* = POINTER TO rFD; rFD* = RECORD attr*: INTEGER; ntyp*: CHAR; reserved: ARRAY 3 OF CHAR; time_create*, date_create*, time_access*, date_access*, time_modif*, date_modif*, size*, hsize*: INTEGER; name*: FNAME END; PROCEDURE [stdcall] f_68_27 (file_name: INTEGER; VAR size: INTEGER): INTEGER; BEGIN sys.CODE( 053H, (* push ebx *) 06AH, 044H, (* push 68 *) 058H, (* pop eax *) 06AH, 01BH, (* push 27 *) 05BH, (* pop ebx *) 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 8] *) 0CDH, 040H, (* int 64 *) 08BH, 04DH, 00CH, (* mov ecx, dword [ebp + 12] *) 089H, 011H, (* mov dword [ecx], edx *) 05BH, (* pop ebx *) 0C9H, (* leave *) 0C2H, 008H, 000H (* ret 8 *) ) RETURN 0 END f_68_27; PROCEDURE Load* (FName: ARRAY OF CHAR; VAR size: INTEGER): INTEGER; RETURN f_68_27(sys.ADR(FName[0]), size) END Load; PROCEDURE GetFileInfo* (FName: ARRAY OF CHAR; VAR Info: rFD): BOOLEAN; VAR res2: INTEGER; fs: rFS; BEGIN fs.subfunc := 5; fs.pos := 0; fs.hpos := 0; fs.bytes := 0; fs.buffer := sys.ADR(Info); COPY(FName, fs.name) RETURN KOSAPI.sysfunc22(70, sys.ADR(fs), res2) = 0 END GetFileInfo; PROCEDURE FileSize* (FName: ARRAY OF CHAR): INTEGER; VAR Info: rFD; res: INTEGER; BEGIN IF GetFileInfo(FName, Info) THEN res := Info.size ELSE res := -1 END RETURN res END FileSize; PROCEDURE Exists* (FName: ARRAY OF CHAR): BOOLEAN; VAR fd: rFD; BEGIN RETURN GetFileInfo(FName, fd) & ~(4 IN BITS(fd.attr)) END Exists; PROCEDURE Close* (VAR F: FS); BEGIN IF F # NIL THEN DISPOSE(F) END END Close; PROCEDURE Open* (FName: ARRAY OF CHAR): FS; VAR F: FS; BEGIN IF Exists(FName) THEN NEW(F); IF F # NIL THEN F.subfunc := 0; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(FName, F.name) END ELSE F := NIL END RETURN F END Open; PROCEDURE Delete* (FName: ARRAY OF CHAR): BOOLEAN; VAR F: FS; res, res2: INTEGER; BEGIN IF Exists(FName) THEN NEW(F); IF F # NIL THEN F.subfunc := 8; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(FName, F.name); res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); DISPOSE(F) ELSE res := -1 END ELSE res := -1 END RETURN res = 0 END Delete; PROCEDURE Seek* (F: FS; Offset, Origin: INTEGER): INTEGER; VAR res: INTEGER; fd: rFD; BEGIN IF (F # NIL) & GetFileInfo(F.name, fd) & (BITS(fd.attr) * {4} = {}) THEN CASE Origin OF |SEEK_BEG: F.pos := Offset |SEEK_CUR: F.pos := F.pos + Offset |SEEK_END: F.pos := fd.size + Offset ELSE END; res := F.pos ELSE res := -1 END RETURN res END Seek; PROCEDURE Read* (F: FS; Buffer, Count: INTEGER): INTEGER; VAR res, res2: INTEGER; BEGIN IF F # NIL THEN F.subfunc := 0; F.bytes := Count; F.buffer := Buffer; res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); IF res2 > 0 THEN F.pos := F.pos + res2 END ELSE res2 := 0 END RETURN res2 END Read; PROCEDURE Write* (F: FS; Buffer, Count: INTEGER): INTEGER; VAR res, res2: INTEGER; BEGIN IF F # NIL THEN F.subfunc := 3; F.bytes := Count; F.buffer := Buffer; res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); IF res2 > 0 THEN F.pos := F.pos + res2 END ELSE res2 := 0 END RETURN res2 END Write; PROCEDURE Create* (FName: ARRAY OF CHAR): FS; VAR F: FS; res2: INTEGER; BEGIN NEW(F); IF F # NIL THEN F.subfunc := 2; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(FName, F.name); IF KOSAPI.sysfunc22(70, sys.ADR(F^), res2) # 0 THEN DISPOSE(F) END END RETURN F END Create; PROCEDURE Copy* (From, To: ARRAY OF CHAR): BOOLEAN; VAR buf, size: INTEGER; outFile: FS; res: BOOLEAN; BEGIN res := FALSE; size := FileSize(From); IF size > 0 THEN buf := Load(From, size) ELSE buf := -1; size := 0 END; IF buf # 0 THEN outFile := Create(To); IF outFile # NIL THEN IF size # 0 THEN res := Write(outFile, buf, size) = size END; Close(outFile) END; IF size # 0 THEN buf := KOSAPI.free(buf) END END RETURN res END Copy; PROCEDURE DirExists* (FName: ARRAY OF CHAR): BOOLEAN; VAR fd: rFD; BEGIN RETURN GetFileInfo(FName, fd) & (4 IN BITS(fd.attr)) END DirExists; PROCEDURE CreateDir* (DirName: ARRAY OF CHAR): BOOLEAN; VAR F: FS; res, res2: INTEGER; BEGIN NEW(F); IF F # NIL THEN F.subfunc := 9; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(DirName, F.name); res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); DISPOSE(F) ELSE res := -1 END RETURN res = 0 END CreateDir; PROCEDURE DeleteDir* (DirName: ARRAY OF CHAR): BOOLEAN; VAR F: FS; res, res2: INTEGER; BEGIN IF DirExists(DirName) THEN NEW(F); IF F # NIL THEN F.subfunc := 8; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(DirName, F.name); res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); DISPOSE(F) ELSE res := -1 END ELSE res := -1 END RETURN res = 0 END DeleteDir; END File.