home *** CD-ROM | disk | FTP | other *** search
- Unit TxtShare;
-
- {$F+}
-
- { This UNIT implements a TEXT file device driver to access TEXT files with a }
- { user specified access mode (see DOS Technical Reference for DOS function }
- { 3Dh). This can be accomplished for non-TEXT files by setting the standard }
- { global variable "FileMode" (part of the System unit) to the desired mode }
- { value, and then calling the appropriate open function. This is not supported }
- { for TEXT files in Turbo Pascal v4.0. }
-
- { To open a Text file with a user specified access mode, place a call to the }
- { procedure AssignText to associate a filename with the text file variable. }
- { Next, set the standard global variable FileMode with the desired DOS access }
- { mode. RESET, REWRITE, and APPEND will now use the access mode assinged to }
- { the FileMode variable when opening the file. }
-
- Interface
-
- Uses Dos;
-
- Var
- WriteTextEofChar : Boolean;
-
- Procedure AssignText(Var F : Text; FileName : String);
-
- Implementation
-
- {$R-,S-}
-
- Function ReadText(Var F : TextRec) : Word;
- Var
- Regs : Registers;
- Label
- Quit;
- Begin
- With F, Regs do begin
- AH := $3F; { DOS read from file or device function }
- BX := Handle; { BX = file handle }
- DS := Seg(BufPtr^); { DS:DX = buffer address }
- DX := Ofs(BufPtr^);
- CX := BufSize; { CX = number of bytes to be read }
- MsDos(Regs); { Read the file }
- If Flags AND fCarry <> 0 then { Any errors? }
- Goto Quit; { Yes. Return Error Code (in AX) }
- BufPos := 0; { Reset buffer ptr to 1st char. }
- BufEnd := AX; { AX = number of bytes actually read }
- AX := 0; { Success - Return 0 as function result }
- end {with};
- Quit:
- ReadText := Regs.AX; { AX contains function result }
- End {ReadText};
-
- Function WriteText(Var F : TextRec) : Word;
- Var
- Regs : Registers;
- Label
- Quit;
- Begin
- With F, Regs do begin
- AH := $40; { DOS write to file or device function }
- BX := Handle; { BX = file handle }
- DS := Seg(BufPtr^); { DS:DX = address of characters to be }
- DX := Ofs(BufPtr^); { written. }
- CX := BufPos; { CX = number of characters to write }
- MsDos(Regs); { Write bufPos characters to the file }
- If Flags AND fCarry <> 0 then { Any errors? }
- Goto Quit; { Yes. Return Error Code (in AX) }
- BufPos := 0; { Reset buffer ptr to 1st char. }
- BufEnd := 0; { Buffer is now empty }
- AX := 0; { Success - Return 0 as function result }
- end {with};
- Quit:
- WriteText := Regs.AX; { AX contains function result }
- End {WriteText};
-
- Function DoNothing(Var F : TextRec) : Word;
- Begin
- DoNothing := 0; { Do nothing. Always return success (0) }
- End {DoNothing};
-
- Function SeekEofText(Var F : TextRec) : Word;
- Var
- Regs : Registers;
- FilePos : LongInt;
- Label
- Quit;
- Begin
- With F, Regs do begin
- AH := $42; { DOS LSEEK function }
- AL := $02; { AL = method (EOF + offset) }
- BX := Handle; { BX = file handle }
- CX := $00; { CX:DX = offset }
- DX := $00;
- MsDos(Regs); { Move file ptr - DX:AX = new file pos. }
- If Flags AND fCarry <> 0 then { Any errors? }
- Goto Quit; { Yes. Return Error Code (in AX) }
-
- FilePos := (DX shl 16) + AX; { Calculate absolute file ptr position }
- If FilePos >= 128 then { Recalculate position to be able to }
- Dec(FilePos, 128) { read the last 128 bytes of the file ...}
- else { ... or, if file has fewer bytes, read }
- FilePos := 0; { the whole thing }
- AH := $42; { DOS LSEEK function }
- AL := $00; { AL = method (absolute) }
- BX := Handle; { BX = file handle }
- CX := FilePos shr 16; { CX:DX = offset }
- DX := (FilePos shl 16) shr 16;
- MsDos(Regs); { Move file ptr }
- If Flags AND fCarry <> 0 then { Any errors? }
- Goto Quit; { Yes. Return Error Code (in AX) }
-
- AX := ReadText(F); { Read last 128 bytes of the file }
- If AX <> 0 then { Any errors? }
- Goto Quit; { Yes. Return Error Code (in AX) }
-
- While (BufPos < BufEnd) and (Buffer[BufPos] <> #26) do
- BufPos := Succ(BufPos); { Look for an EOF character (ascii 26) }
-
- If BufPos < Bufend then begin { If found, truncate file at that point }
- FilePos := FilePos + BufPos;
- AH := $42; { Move file pointer to the EOF character }
- AL := $00;
- BX := Handle;
- CX := FilePos shr 16;
- DX := (FilePos shl 16) shr 16;
- MsDos(Regs);
- If Flags AND fCarry <> 0 then
- Goto Quit;
-
- BufPos := 0;
- AX := WriteText(F); { Write 0 bytes (ie. truncate the file) }
- If AX <> 0 then
- Goto Quit;
- end {if};
-
- AX := 0; { No errors, so return result = 0 }
-
- end {with};
- Quit:
- SeekEofText := Regs.AX;
- End {SeekEofText}; { AX contains function result }
-
- Function CloseText(Var F : TextRec) : Word;
- Var
- Regs : Registers;
- Label
- Quit;
- Begin
- With F, Regs do begin
- If (Mode = fmOutput) and { If opened with rewrite or append }
- WriteTextEofChar then begin { then write an EOF character before }
- Buffer[0] := #26; { closing the file (but only if the var }
- BufPtr := @Buffer; { WriteTextEofChar is TRUE). }
- BufPos := 1;
- AX := WriteText(F);
- If AX <> 0 then
- Goto Quit;
- end {if};
- AH := $3E; { DOS close a file handle function }
- BX := Handle; { BX = file handle }
- MsDos(Regs);
- If Flags AND fCarry = 0 then { No errors, so function result = 0 }
- AX := 0;
- BufPos := 0;
- BufEnd := 0;
- end {with};
- Quit:
- CloseText := Regs.AX; { AX contains function result }
- End {CloseText};
-
- Function OpenText(Var F : TextRec) : Word;
- Var
- Regs : Registers;
- Label
- Quit;
- Begin
- With F, Regs do begin
- If Mode = fmOutput then { If REWRITE, Create or Truncate to 0 }
- AH := $3C { DOS CREAT function }
- else { If RESET or APPEND, just open existing }
- AH := $3D; { DOS open a file function }
- AL := FileMode; { File access mode to use }
- CX := 0; { File Attribute (for CREAT func only) }
- DS := Seg(Name); { DS:DX = address of asciiz filename }
- DX := Ofs(Name);
- MsDos(Regs);
- If Flags AND fCarry <> 0 then { Any errors? }
- Goto Quit; { Yes. Return Error Code (in AX) }
- Handle := AX; { Set file handle }
- AX := 0; { AX will hold function result }
- CloseFunc := @CloseText; { Set close function }
- If Mode = fmInOut then begin { If opened with APPEND ... }
- AX := SeekEofText(F); { ... reposition to end of file }
- If AX = 0 then { If no error ... }
- Mode := fmOutput { Set Output Only mode }
- Else { Error in SeekEofText function }
- Goto Quit; { Return with error code (in AX) }
- end {if};
- If Mode = fmInput then begin { Opened with RESET }
- InOutFunc := @ReadText; { Set Input Function }
- FlushFunc := @DoNothing; { Set Flush Function }
- end {then}
- else begin { Opened with REWRITE }
- InOutFunc := @WriteText; { Set Output Function }
- FlushFunc := @DoNothing; { Set Flush Function }
- end {if};
- BufPos := 0; { Reset buffer ptr to 1st char. }
- BufEnd := 0; { Buffer is now empty }
- end {with};
- Quit:
- OpenText := Regs.AX; { AX contains function result }
- End {OpenText};
-
-
- Procedure AssignText(Var F : Text; FileName : String);
- Var
- I : Integer;
- Begin
- With TextRec(F) do begin { Initialize textrec record }
- Handle := $FFFF; { Set file handle to junk }
- Mode := fmClosed; { Indicate the file is not yet open }
- BufSize := SizeOf(Buffer); { Set size of default buffer (128) }
- BufPtr := @Buffer; { Set up pointer to default buffer }
- OpenFunc := @OpenText; { Set up pointer to OPEN function }
- For I := 1 to Length(FileName) do { Set up asciiz filename }
- Name[I-1] := FileName[I];
- Name[Length(FileName)] := Chr(0);
- End {with};
- End {AssignText};
-
- Begin
- { Initialize global variable to suppress writing ^Z at the end of any }
- { text file opened with Append or Rewrite. }
- WriteTextEofChar := FALSE;
- End {Unit TxtShare}.
-