File Operations
Turbo Pascal needs to create, read from and write to files. Few simple routins take care for this.
Procedure OpenFile (Var FileToOpen: File; FileName: PChar);
Var Error: Integer;
begin
Assign (FileToOpen, FileName);
{$I-}
Repeat
Reset (FileToOpen, 1);
Error := IOResult;
Case Error of
0: Exit;
2: FileError (FileName, FileNotFound);
4: If not CloseOneSourceFile then FileError (FileName, TooManyOpenFiles);
5: FileError (FileName, FileAccessDenied);
else FileError (FileName, InvalidFilename);
end;
until False;
{$I+}
end;
Procedure CreateFile (Var FileToCreate: File; FileName: PChar);
Var Error: Integer;
begin
Assign (FileToCreate, FileName);
{$I-}
Repeat
Rewrite (FileToCreate, 1);
Error := IOResult;
Case Error of
0: Exit;
2: FileError (FileName, FileNotFound);
4: If not CloseOneSourceFile then FileError (FileName, TooManyOpenFiles);
5: FileError (FileName, FileAccessDenied);
else FileError (FileName, InvalidFilename);
end;
until False;
{$I+}
end;
Procedure DeleteFile (FileName: PChar);
Var TempFile: File;
begin
Assign (TempFile, FileName);
{$I-}
Close (TempFile);
Erase (TempFile);
{$I+}
end;
If there are too many files open Turbo Pascal tries to close them one by one and repeat requested file operation before reporting an error.
Function CloseOneSourceFile: Boolean;
Var CurrentFileStructPtr, NextFileStructPtr: PFileStructure;
TempHandle: Word;
begin
CloseOneSourceFile := False;
If CurrentSourceFile = @EndOfFileStructure then Exit;
NextFileStructPtr := Ptr (Seg (FileStructure), CurrentSourceFile^.Name.Len + Ofs (CurrentSourceFile^.Name.Chr));
If Ofs (NextFileStructPtr^) = Ofs (EndOfFileStructure) then Exit;
Repeat
CurrentFileStructPtr := NextFileStructPtr;
NextFileStructPtr := Ptr (Seg (FileStructure), CurrentFileStructPtr^.Name.Len + Ofs (CurrentFileStructPtr^.Name.Chr));
If Ofs (NextFileStructPtr^) = Ofs (EndOfFileStructure) then Break;
until NextFileStructPtr^.Handle = 0;
TempHandle := CurrentFileStructPtr^.Handle;
CurrentFileStructPtr^.Handle := 0;
If TempHandle <> 0 then
Asm
MOV BX, TempHandle
MOV AH, $3E
INT $21
CLD
end;
CloseOneSourceFile := True;
end;
Turbo Pascal always reads all files as binary ones. It processes them on the lowest level.
Function ReadFile (Var FileToRead: File): Pointer;
Var FSize: Longint;
BytesRead: Word;
begin
FSize := FileSize (FileToRead) - FilePos (FileToRead);
If FSize > 16 * LongInt (HeapEndRec.Seg - HeapPtrRec.Seg) then Error (OutOfMemory);
ReadFile := HeapPtr;
Repeat
BlockRead (FileToRead, HeapPtr^, $FFF0, BytesRead);
FSize := FSize - BytesRead;
HeapPtrRec.Seg := HeapPtrRec.Seg + (BytesRead + $000F) shr 4;
until FSize = 0;
end;