home *** CD-ROM | disk | FTP | other *** search
- { Turbo Pascal File Viewer Object }
- PROGRAM Finder;
-
- USES Dos, Crt;
-
- CONST
- PrintSet: SET OF $20..$7E = [$20..$7E];
- ExtenSet: SET OF $80..$FE = [$80..$FE];
- NoPrnSet: SET OF $09..$0D = [$09, $0A, $0D];
-
- TYPE
- CharType = (Unknown, Ascii, Hex);
- DataBlock = ARRAY[1..256] OF Byte;
- Viewer = OBJECT
- XOrg, YOrg,
- LineLen, LineCnt, BlockCount:Integer;
- FileName:STRING;
- FileType:CharType;
- PROCEDURE FileOpen(Fn:STRING;
- X1,Y1,X2,Y2:Integer);
- FUNCTION TestBlock(FileBlock:DataBlock;
- Count:Integer):CharType;
- PROCEDURE ListHex(FileBlock:DataBlock;
- Count, Ofs:Integer);
- PROCEDURE ListAscii(FileBlock:DataBlock;
- Count:Integer);
- END;
-
- Finder = OBJECT(Viewer)
- PROCEDURE Search(Fn, SearchStr:STRING;
- X1, Y1, X2, Y2:Integer);
- END;
-
- PROCEDURE Finder.Search;
- VAR
- VF:FILE;
- Result1, Result2:Word;
- BlkOfs, i, j, SearchLen:Integer;
- SearchArray:ARRAY[1..128] OF Byte;
- EndFlag, BlkDone, SearchResult:boolean;
- FileBlock1, FileBlock2, ResultArray:DataBlock;
- BEGIN
- BlockCount := 0;
- XOrg := X1;
- YOrg := Y1;
- LineLen := X2;
- LineCnt := Y2;
- FileType := Unknown;
- SearchLen := Ord(SearchStr[0]);
- FOR i := 1 TO SearchLen DO
- SearchArray[i] := Ord(SearchStr[i]);
- FOR i := 1 TO SizeOf(ResultArray) DO
- ResultArray[i] := $00;
-
- Assign(VF, Fn);
- {$I-} Reset(VF, 1); {$I+}
- IF IOResult = 0 THEN
- BEGIN
- EndFlag := FALSE;
- BlkDone := FALSE;
- SearchResult := FALSE;
- BlockRead(VF, FileBlock2,
- SizeOf(FileBlock2),Result2);
- EndFlag := Result2 <> SizeOf(FileBlock2);
- REPEAT
- FileBlock1 := FileBlock2;
- Result1 := Result2;
- FileBlock2 := ResultArray;
- IF NOT EndFlag THEN
- BEGIN
- BlockRead(VF, FileBlock2,
- SizeOf(FileBlock2), Result2);
- Inc(BlockCount);
- EndFlag := Result2 <> SizeOf(FileBlock2);
- END ELSE BlkDone := TRUE;
- FOR i := 1 TO Result1 DO
- BEGIN
- IF SearchArray[1] = FileBlock1[i] THEN
- BEGIN
- BlkOfs := i-1;
- SearchResult := TRUE;
- FOR j := 1 TO SearchLen DO
- BEGIN
- IF i+j-1 <= Result1 THEN
- BEGIN
- IF SearchArray[j] =
- FileBlock1[i+j-1] THEN
- ResultArray[j] :=
- FileBlock1[i+j-1]
- ELSE
- BEGIN
- SearchResult := FALSE;
- j := SearchLen;
- END;
- END
- ELSE
- IF SearchArray[j] =
- FileBlock2[i+j-257] THEN
- ResultArray[j] :=
- FileBlock2[i+j-257]
- ELSE
- BEGIN
- SearchResult := FALSE;
- j := SearchLen;
- END;
- END;
- IF SearchResult THEN
- BEGIN
- FOR j := SearchLen+1 TO
- SizeOf(ResultArray) DO
- IF i+j-1 <= Result1 THEN
- ResultArray[j] :=
- FileBlock1[i+j-1]
- ELSE
- ResultArray[j] :=
- FileBlock2[i+j-257];
- i := Result1;
- END;
- END;
- END;
- UNTIL BlkDone OR SearchResult;
- IF SearchResult THEN
- BEGIN
- Write('Search string found ');
- WriteLn('in file block ', BlockCount);
- Write(' beginning at byte offset ');
- WriteLn(BlkOfs, ' ...');
- WriteLn;
- IF FileType = Unknown THEN
- FileType := TestBlock(ResultArray,
- SizeOf(ResultArray));
- CASE FileType OF
- Hex:ListHex(ResultArray,
- SizeOf(ResultArray), BlkOfs);
- Ascii:ListAscii(ResultArray,
- SizeOf(ResultArray));
- END;
- END
- ELSE
- BEGIN
- Write('"', SearchStr, '" not found in ');
- WriteLn(Fn);
- END;
- Close(VF);
- Window(1, 1, 80, 25);
- END
- ELSE
- WriteLn(Fn, ' invalid file name!');
- END;
-
- PROCEDURE Viewer.FileOpen;
- VAR
- VF:FILE; Ch:Char;
- Result, CrtX, CrtY:Word;
- EndFlag:boolean;
- FileBlock:DataBlock;
- BEGIN
- BlockCount := 0;
- XOrg := X1;
- YOrg := Y1;
- LineLen := X2;
- LineCnt := Y2;
- FileType := Unknown;
- Assign(VF, Fn);
- {$I-} Reset(VF, 1); {$I+}
- IF IOResult = 0 THEN
- BEGIN
- Window(X1, Y1, X1+X2-1, Y1+Y2-1);
- WriteLn;
- EndFlag := FALSE;
- REPEAT
- BlockRead(VF, FileBlock,
- SizeOf(FileBlock), Result);
- Inc(BlockCount);
- EndFlag := Result <>
- SizeOf(FileBlock);
- IF FileType = Unknown THEN
- FileType := TestBlock(FileBlock,
- Result);
- CASE FileType OF
- Hex:ListHex(FileBlock, Result, 0);
- Ascii:ListAscii(FileBlock, Result);
- END;
- IF NOT EndFlag THEN
- BEGIN
- CrtX := WhereX; CrtY := WhereY;
- IF WhereY = LineCnt THEN
- BEGIN
- WriteLn;
- Dec(CrtY);
- END;
- GotoXY(1, 1); clreol;
- Write(' Viewing: ', Fn);
- GotoXY(1, LineCnt); clreol;
- Write(' Press (+) to continue,');
- Write(' (Enter) to exit: ');
- Ch := ReadKey;
- EndFlag := Ch <> '+';
- GotoXY(1, LineCnt); clreol;
- GotoXY(CrtX, CrtY);
- END;
- UNTIL EndFlag;
- Close(VF);
- sound(440); delay(100);
- sound(220); delay(100); nosound;
- Window(1, 1, 80, 25);
- END
- ELSE
- WriteLn(Fn, ' invalid file name!');
- END;
-
- FUNCTION Viewer.TestBlock;
- VAR
- i:Integer;
- BEGIN
- FileType := Ascii;
- FOR i := 1 TO Count DO
- IF NOT FileBlock[i] IN
- NoPrnSet+PrintSet THEN
- FileType := Hex;
- TestBlock := FileType;
- END;
-
- PROCEDURE Viewer.ListHex;
- CONST
- HexStr: STRING[16] = '0123456789ABCDEF';
- VAR
- i, j, k:Integer;
- BEGIN
- k := 1;
- REPEAT
- Write(' ');
- j := (BlockCount-1) * SizeOf(FileBlock)
- + (k - 1) + Ofs;
- FOR i := 3 DOWNTO 0 DO
- Write(HexStr[j SHR (i*4) AND $0F+1]);
- Write(': ');
- FOR i := 1 TO 16 DO
- BEGIN
- IF k <= Count THEN
- Write(HexStr[FileBlock[k] SHR 4+1],
- HexStr[ FileBlock[k] AND $0F+1 ],' ')
- ELSE Write(' ');
- Inc(k);
- IF(i DIV 4 = i / 4) THEN Write(' ');
- END;
- FOR i := k-16 TO k-1 DO
- IF i <= Count THEN
- IF FileBlock[i] IN PrintSet+ExtenSet
- THEN Write(Chr(FileBlock[i]))
- ELSE Write('.');
- WriteLn;
- UNTIL k >= Count;
- END;
-
- PROCEDURE Viewer.ListAscii;
- VAR
- i:Integer;
- BEGIN
- FOR i := 1 TO Count DO
- BEGIN
- Write(Chr(FileBlock[i]));
- IF WhereX > LineLen THEN WriteLn;
- IF WhereY >= LineCnt THEN
- BEGIN
- WriteLn;
- GotoXY(1, LineCnt-1);
- END;
- END;
- END;
-
- {=============== end Viewer object ==============}
-
- VAR
- FileFind:Finder;
- BEGIN
- ClrScr;
- {Call FileFind.Search with file to search,
- search string, and display Window}
- FileFind.Search('C:\COMMAND.COM',
- 'DIR',
- 10, 10, 70, 22);
- GotoXY(1, 25);clreol;
- Write('Press any key to continue: ');
- WHILE NOT KeyPressed DO;
- END.
-