Category : Pascal Source Code
Archive   : RLINE.ZIP
Filename : RLINE.PAS

 
Output of file : RLINE.PAS contained in archive : RLINE.ZIP
{$R-,V-,I-,S-}
Unit RLINE;

{ -USES Nothing- }

(*********************************************************************
Fast disk file text reading operations.

Address comments, complaints, suggestions on CompuServe to
Don Strenczewilk [72617,132]


This unit contains some fast reading routines designed to work with
standard ASCII disk files:

FOpen Open a file
FRead Read the next character
FReadLn Read the next string
FFilePos Return the current position in the file
FSeek Seek to any position
FClose Close a file

The RLINE unit uses about 600 bytes of your programs code space,
and 0 data.

**********************************************************************)
Interface
(*********************************************************************)

(*
A special record of type RFrec is internally maintained by the RLINE Unit
that contains information about the file handle, the buffer address, current
position in the file, size of the buffer, and current location in buffer:
*)

TYPE
{ Generic type which allows access to segment and offset of pointer }
SegOfsPtr = RECORD
CASE Boolean OF
True : (Pntr : Pointer);
False : (Ofst, Sgmnt : Word);
END;

RFrec =
RECORD
Handle : Word; { File handle }
BufPtr : SegOfsPtr; { BufOfs, BufSeg}
Bpo, { Current buffer position }
BSize, { Buffer size in bytes }
BLeft, { Bytes left in buffer to scan }
NBufs : Word; { Number of buffers read. = 0 if none. }
TotBytesInBuf : Word; { Total bytes that were read into current buffer.}
END;

(*
All you need to know to use the RLINE routines is that you must declare a
variable of type RFrec somewhere.
*)

{---------------------------------------------------------------------
Function FOpen

A file must first be successfully opened with a call to FOpen, before any of
the other routines are used.

A buffer must be declared to be passed to the FOpen function. There are no
restrictions on the location of the buffer, so it can be a global or local
variable, or allocated with New() or GetMem().
}


FUNCTION FOpen(VAR RF : RFrec; { a RFrec variable. }
Fn : STRING; { Name of file to open. }
DBSize : Word; { Size of buffer. 512 bytes minimum. }
VAR BufP) { Disk buffer to use. }
: Word;

{
If successful:
Returns 0.

If failed:
Returns DOS error code if a DOS error occured,
or error 12 (Invalid File Access Code) if the buffer size is 0.

TRAPS:
If using a buffer allocated with New() or GetMem(), be sure to use the caret
after it for the BufP parameter. Ie. IF FOpen(RF, Fn, BSize, BufP^)...

Never call FOpen twice with the same RFrec variable without closing the old
one first.

EXAMPLE:
VAR
RF : RFrec;
Buffer : Array[1..2048] of Char;
Error : Word;
BEGIN
Error := FOpen(RF, 'HELLO.PAS', Sizeof(Buffer), Buffer);
If Error = 0
THEN Writeln('Success')
ELSE Writeln('Error: ', i);
...

--------------------------------------------------------------------------
Procedure FClose - When done with the file, it must be closed with a call to
FClose:
}

PROCEDURE FClose(VAR RF : RFrec);

{
Closes previously opened RFrec.
Returns nothing.

This procedure attempts to identify whether the file has been previously
opened before it attempts to ask DOS to close it. It does not attempt to
close the file if:
a) RF.BSize = 0. Function FOpen sets RF.BSize to 0 if DOS open failed.
or
b) RF.Handle < 5, in which case it would be a standard DOS handle, which
shouln't be closed.

TRAP: A problem that could occur with this scheme would be if (the file was
never even attempted to be opened by FOpen) AND (the handle = the handle of
a file that is currently opened somewhere else in the program).

----------------------------------------------------------------------
Function FReadLn

FReadLn - Reads a string of characters up to the next ^M, or ^Z , or
the physical end of file, whichever comes first.

The maximum length of the string returned to caller is 255 characters. If
more than 255 characters are passed in the file before ^M or , the
remaining characters are irretreivable.
}
FUNCTION FReadLn(VAR RF : RFrec; { Previously opened RFrec variable }
VAR S : STRING) { String variable to read next line to. }
: Word;
{
On success:
Returns 0.
S = next string read from file RF.Handle.
On failure:
returns either DOS error code,
or $FFFF if End of File

Works like a Turbo Readln(F, S); except:
(1) It works only with disk files.
(2) Only reads strings. ie. not integers, words, or any other type.
(3) It is much faster.
(4) Doesn't stop when a ^Z is encountered before end of file. If a ^Z
is encountered AT the end of file, it is stripped. Any ^Z's encountered
before the physical end of the file are passed on to the string.

----------------------------------------------------------------------
Function FRead - Reads the next character from the file:
}
FUNCTION FRead(VAR RF : RFrec; { Previously opened RFrec variable }
VAR Ch : Char) { String variable to read next line to. }
: Word;
{
Works the same as FReadLn but returns one character instead of a string.
All characters are passed on to Ch except if a ^Z is at end of file.

If successful:
Returns 0. Ch = next character in the file.

If failed:
Returns either DOS error code,
or $FFFF if End of File

----------------------------------------------------------------------
Function FFilePos - Returns current file position for use with FSeek.
}
FUNCTION FFilePos(VAR RF : RFrec) : LongInt;
{
Returns current file position. RF must have been previously opened.
If FFilePos is called before FOpen is called successfully, the results will
be meaningless.

----------------------------------------------------------------------
Function FSeek - Seeks to position FPo in previously opened RF.
}
FUNCTION FSeek(VAR RF : RFrec;
FPo : LongInt) : Word;
{
If successful, Returns 0
If failed, returns DOS error code.

To Reset the file, call RFSeek with FPo := 0. Ie. FSeek(RF,0);

On a normal ^M^J ascii file, FFilePos will most often return the position of
the ^J after a call to FReadLn. Because FReadLn strips leading ^J's, this
shouldn't be a problem. But, bear that in mind if using the FFilePos
results for your own untyped file routines.
}

(****************************************************************************)
Implementation
(****************************************************************************)

{=================================================================}
{$L RLINE.OBJ} { EXTERNAL DECLARATIONS }
{ All PROCs are FAR }

FUNCTION FOpen(VAR RF : RFrec;
Fn : STRING;
DBSize : Word;
VAR BufP) : Word; EXTERNAL;

FUNCTION FReadLn(VAR RF : RFrec;
VAR S : STRING) : Word; EXTERNAL;

FUNCTION FRead(VAR RF : RFrec;
VAR Ch : Char) : Word; EXTERNAL;

FUNCTION FSeek(VAR RF : RFrec; FPo : LongInt) : Word; EXTERNAL;

PROCEDURE FClose(VAR RF : RFrec); EXTERNAL;
{=================================================================}

FUNCTION FFilePos(VAR RF : RFrec) : LongInt;
BEGIN
{ RF.NBufs is equal to 1 when there has been at least 1 buffer read. }
WITH RF DO
IF NBufs = 0 { If current buffer number = 0, nothing's been read. }
THEN FFilePos := 0
ELSE FFilePos := (LongInt(NBufs-1)*BSize)+(Bpo-BufPtr.Ofst);
END;

END.


  3 Responses to “Category : Pascal Source Code
Archive   : RLINE.ZIP
Filename : RLINE.PAS

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/