home *** CD-ROM | disk | FTP | other *** search
- UNIT U_EGA_0a; {Last mod by JFH on 05/15/95}
-
- { EXAMPLE OF MAKING ASSESS OBJECTS (CLASSES) }
-
- { Pgm. 07/14/95 by John F Herbster, CIS:72714,3445, Houston, TX.
- for Rick Rogers (CIS:74323,3573). }
-
- {=====} INTERFACE {====================================================}
-
- { For example, AutoCADD text format DXF files use two-line records.
- The first line of each pair must contain an integer between 0 and
- 1071, called the "group code", and the second line will contain a
- value in text format, but representing a text string, floating
- point number (double), integer, and a couple of other formats that
- I will ignore here. The files can be a megabyte in size.
- We could build our program around a loop reading the lines and
- interpreting the lines; which is OK for a test or a one time use.
- But, for maintenance and because there are a lot of things that we
- can do to speed up the reading of the file we should split up the
- reading of the file into a neat unit or two.
- What the application program could really use is an object like
- the following. }
- Type tBasicDFXReaderCls = class
- Function NextGroupCode: integer; virtual; abstract;
- { rtns next group code or -2 for EOF or -1 for not a valid code.}
- Function ValStr: string; virtual; abstract;
- { rtns value as a string.}
- Function ValDbl: double; virtual; abstract;
- { rtns value as a double or a quiet NAN (quiet Not-A-Number).}
- Function ValInt: integer; virtual; abstract;
- { rtns value as an integer or a value of -$8000.}
- end;
-
- { Now lets define a quick and dirty real thing just for use in
- testing the rest of the application. }
- Type tSimpleDFXReaderCls = class (tBasicDFXReaderCls)
- Chan: text;
- LnNbr: longint;
- fLine: string;
- fCode: integer;
- EC: integer;
- Constructor Create (const aPath: string);
- Function NextGroupCode: integer; override;
- Function ValStr: string; override;
- Function ValDbl: double; override;
- Function ValInt: integer; override;
- Destructor Destroy; override;
- end;
-
- { Suppose the application works, but we find that the text IO is
- making it very slow. So let's define a reader object that can use
- block IO. }
- Const MaxSizeOfBuf = 4096;
- Type tCharArray = array [0..MaxSizeOfBuf-1] of char;
- Type tBlkIoDFXReaderCls = class (tBasicDFXReaderCls)
- Chan: file;
- SizeOfBuf,ii,NbrInBuf: word;
- EC,fCode: integer;
- pBuf: ^tCharArray;
- LnNbr: longint;
- fLine: string;
- Constructor Create (const aPath: string);
- Function NextGroupCode: integer; override;
- Function ValStr: string; override;
- Function ValDbl: double; override;
- Function ValInt: integer; override;
- Destructor Destroy; override;
- end;
-
- { Now I should have used a general text file reader object in the
- latter tBlkIoDxfReaderCls. Then the character scanning code could
- be kept separate in another unit and improved separately AND used
- in other projects without change. }
-
- {----- Some NAN (Not a Number) Stuff ------}
- Function NAN: single;
-
- {=====} IMPLEMENTATION {===============================================}
-
- {----- Implement a First (simple) Reader -----}
- Constructor tSimpleDFXReaderCls.Create (const aPath: string);
- Begin
- Inherited Create;
- AssignFile(Chan,aPath);
- Reset(Chan);
- End;
- Destructor tSimpleDFXReaderCls.Destroy;
- Begin
- Close(Chan);
- Inherited Destroy;
- End;
- Function tSimpleDFXReaderCls.NextGroupCode: integer;
- Begin
- If EOF(Chan)
- then Result:=-2
- else begin
- ReadLn(Chan,fLine); Inc(LnNbr);
- Val(fLine,Result,ec);
- if ec<>0
- then Result:=-1
- else if EOF(Chan)
- then Result:=-2
- else begin ReadLn(Chan,fLine); Inc(LnNbr) end;
- end;
- End;
- Function tSimpleDFXReaderCls.ValStr: string;
- Begin Result:=fLine End;
- Function tSimpleDFXReaderCls.ValDbl: double;
- Begin
- Val(fLine,Result,ec);
- If ec<>0 then Result:=Nan;
- End;
- Function tSimpleDFXReaderCls.ValInt: integer;
- Begin
- Val(fLine,Result,ec);
- If ec<>0 then Result:=-$8000;
- End;
-
- {----- Implement the reader using block IO -----}
- Constructor tBlkIoDFXReaderCls.Create (const aPath: string);
- Begin
- Inherited Create;
- AssignFile(Chan,aPath);
- Reset(Chan,1);
- SizeOfBuf:=MaxSizeOfBuf;
- GetMem(pBuf,SizeOfBuf);
- End;
- Destructor tBlkIoDFXReaderCls.Destroy;
- Begin
- Close(Chan);
- FreeMem(pBuf,SizeOfBuf);
- Inherited Destroy;
- End;
- Function tBlkIoDFXReaderCls.NextGroupCode: integer;
- function GotMore: boolean;
- begin
- BlockRead(Chan,pBuf^,SizeOfBuf,NbrInBuf); ec:=IoResult; ii:=0;
- If (ec=0) and (NbrInBuf=0) then ec:=-1; GotMore:=(ec=0);
- end{GotMore};
- function GotLine: boolean;
- const CR=^M; LF=^J; var c: char;
- begin
- byte(fLine[0]):=0;
- While (ii<NbrInBuf) or GotMore do begin
- c:=pBuf^[ii]; inc(ii);
- If (c<>CR) and (length(fLine)<255)
- then begin inc(fLine[0]); fLine[length(fLine)]:=c end
- else if c=CR
- then if (ii<NbrInBuf) or GotMore
- then begin if pBuf^[ii]=LF then inc(ii) end;
- end{while};
- GotLine:=(ec=0) and (c=CR);
- end{GotLine};
- Begin{NextGroupCode}
- If GotLine
- then Val(fLine,fCode,ec);
- If ec<>0
- then fCode:=-2
- else if not GotLine then fCode:=-2;
- Result:=fCode;
- End{NextGroupCode};
- Function tBlkIoDFXReaderCls.ValStr: string;
- Begin Result:=fLine End;
- Function tBlkIoDFXReaderCls.ValDbl: double;
- Begin
- Val(fLine,Result,ec); If ec<>0 then Result:=NAN;
- End;
- Function tBlkIoDFXReaderCls.ValInt: integer;
- Begin
- Val(fLine,Result,ec); If ec<>0 then Result:=-$8000;
- End;
-
- {----- Some NAN Stuff -------------------------------------------------}
-
- Function Nan: single;
- Const QuietNanTemplate: longint = $7FC00000 or $FFFF;
- Begin Result:=single(QuietNanTemplate) End;
-
- { Besides the "quiet" NANs, "signaling" NANs are possible, too, which
- will cause interrupts if they take part in calculations. Infinities
- (plus and minus) are likewise defined. The NANs and INFs can be
- tested for and the Borland RTL write text routines convert them to
- the text "NAN" and "INF". }
-
- {=====} END. {=========================================================}
-