home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / files / fileman / fm / fmview.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-08-23  |  12.4 KB  |  374 lines

  1. {
  2. --------------------------------------------------------------------------
  3.                        F i l e    I n f o r m a t i o n
  4.  
  5. * DESCRIPTION
  6. File used with FM.PAS.
  7.  
  8. * ASSOCIATED FILES
  9. FM.PAS
  10. FM.DOC
  11. FM.EXE
  12. FM.TPU
  13. FMFILE.PAS
  14. FMINPUT.PAS
  15. FMSCREEN.PAS
  16. FMUTEST.EXE
  17. FMUTEST.PAS
  18. FMVIEW.PAS
  19.  
  20. ==========================================================================
  21. }
  22. {$R-}   { Range checking off }                          { Unit:    FMView.PAS }
  23. {$S-}   { Stack checking off }                          { Program: FM.PAS     }
  24. {$I-}   { I/O checking off }                            { Author:  Jim Zwick  }
  25. {$B-}   { Boolean short-circuit evaluation on }         { Version: 1.0        }
  26. {$V+}   { Strict String type checking on }              { Date:    03-04-88   }
  27.  
  28. UNIT FMView;
  29.  
  30. INTERFACE
  31.  
  32. USES
  33.   Crt,
  34.   Dos,
  35.   FMScreen,
  36.   FMFile,
  37.   FMInput;
  38.  
  39.  
  40.   PROCEDURE View(Name : Str12);
  41.  
  42.  
  43. IMPLEMENTATION
  44.  
  45.   PROCEDURE View(Name : Str12);
  46.   CONST
  47.     NL = 24;
  48.     MoveChar : SET OF CHAR = [Home, Up, PgUp, Left, Right, EndKey, Down, PgDn];
  49.   TYPE
  50.     VPageLinesType = ARRAY[1..NL] OF STRING[90];
  51.     VPagePtr = ^VPageRec;
  52.     VPageRec = RECORD
  53.                  Key  : INTEGER;                                 { PageNumber }
  54.                  Pg   : VPageLinesType;
  55.                  Next : VPagePtr;
  56.                  Last : VPagePtr;
  57.                END;
  58.   VAR
  59.     CurrPage, FirstPg, LastPg : VPagePtr;
  60.     BufferStart               : INTEGER;
  61.     MaxPages, PagesInBuffer   : INTEGER;
  62.     TempPage, LastPageInFile  : INTEGER;
  63.     Line, Place               : BYTE;
  64.     Reply                     : CHAR;
  65.     BufferFull, EndOfFile     : BOOLEAN;
  66.     NewScr, BufPagesFull      : BOOLEAN;
  67.     TempStr                   : STRING[78];
  68.     Source                    : TEXT;
  69.  
  70.   { --------------------------------- }
  71.  
  72.   PROCEDURE InsertViewPage(VAR FirstPtr, LastPtr, NewPtr : VPagePtr);
  73.   VAR
  74.     SearchPtr : VPagePtr;                      { FirstPtr and LastPtr must be }
  75.     Found     : BOOLEAN;                       { initialized to NIL before    }
  76.   BEGIN                                        { calling this procedure the   }
  77.     SearchPtr := FirstPtr;                     { first time.  NewPtr must be  }
  78.     Found := FALSE;                            { allocated and initialized.   }
  79.     NewPtr^.Next := NIL;
  80.     NewPtr^.Last := NIL;
  81.     IF (SearchPtr = NIL) THEN
  82.       BEGIN
  83.         FirstPtr := NewPtr;
  84.         LastPtr := FirstPtr;
  85.       END
  86.     ELSE
  87.       BEGIN
  88.         WHILE (SearchPtr <> NIL) AND (NOT Found) DO
  89.           IF (SearchPtr^.Key < NewPtr^.Key) THEN SearchPtr := SearchPtr^.Next
  90.           ELSE Found := TRUE;
  91.         NewPtr^.Next := SearchPtr;
  92.         IF (SearchPtr = FirstPtr) THEN
  93.           BEGIN
  94.             FirstPtr := NewPtr;
  95.             SearchPtr^.Last := FirstPtr;
  96.           END
  97.         ELSE IF (SearchPtr = NIL) THEN
  98.           BEGIN
  99.             NewPtr^.Last := LastPtr;
  100.             LastPtr^.Next := NewPtr;
  101.             LastPtr := NewPtr;
  102.           END
  103.         ELSE
  104.           BEGIN
  105.             NewPtr^.Last := SearchPtr^.Last;
  106.             SearchPtr^.Last^.Next := NewPtr;
  107.             SearchPtr^.Last := NewPtr;
  108.           END;
  109.       END;
  110.   END;
  111.   { --------------------------------- }
  112.  
  113.   PROCEDURE DeleteViewPage(VAR FirstPtr, LastPtr : VPagePtr; OldKey : INTEGER);
  114.   VAR
  115.     DelPtr : VPagePtr;                              { FirstPtr and LastPtr  }
  116.   BEGIN                                             { must be initialized   }
  117.     IF (FirstPtr = NIL) THEN DelPtr := NIL          { to NIL before calling }
  118.     ELSE IF (OldKey = FirstPtr^.Key) THEN           { this procedure the    }
  119.       BEGIN                                         { first time.           }
  120.         DelPtr := FirstPtr;                         
  121.         FirstPtr := FirstPtr^.Next;
  122.         IF (FirstPtr <> NIL) THEN FirstPtr^.Last := NIL;
  123.         IF (FirstPtr = NIL) THEN LastPtr := NIL;
  124.       END
  125.     ELSE IF (OldKey = LastPtr^.Key) THEN
  126.       BEGIN
  127.         DelPtr := LastPtr;
  128.         LastPtr := LastPtr^.Last;
  129.         IF (LastPtr <> NIL) THEN LastPtr^.Next := NIL;
  130.       END
  131.     ELSE
  132.       BEGIN
  133.         DelPtr := FirstPtr;
  134.         WHILE (DelPtr <> NIL) AND (DelPtr^.Key <> OldKey) DO
  135.           DelPtr := DelPtr^.Next;
  136.         IF (DelPtr <> NIL) THEN        { DelPtr is NIL if OldKey is not found }
  137.           BEGIN
  138.             DelPtr^.Next^.Last := DelPtr^.Last;
  139.             DelPtr^.Last^.Next := DelPtr^.Next;
  140.           END;
  141.       END;
  142.     IF (DelPtr <> NIL) THEN DISPOSE(DelPtr);
  143.   END;
  144.   { --------------------------------- }
  145.  
  146.     PROCEDURE ReadPage(PageNum : INTEGER);
  147.     VAR
  148.       Line    : BYTE;
  149.       NewPage : VPageRec;
  150.       TempPtr : VPagePtr;
  151.     BEGIN
  152.       Line := 1;
  153.       WHILE (Line <= NL) DO
  154.         BEGIN
  155.           READLN(Source, Newpage.Pg[Line]);
  156.           Inc(Line);
  157.         END;
  158.       IF EOF(Source) THEN
  159.         BEGIN
  160.           EndOfFile := TRUE;
  161.           LastPageInFile := PageNum;
  162.         END;
  163.       NewPage.Key := PageNum;
  164.       NEW(TempPtr);
  165.       TempPtr^ := NewPage;
  166.       InsertViewPage(FirstPg, LastPg, TempPtr);
  167.       IF (NOT BufferFull) AND (CurrPage <> NIL) THEN
  168.         BEGIN
  169.           HIGHVIDEO;
  170.           GotoXY(1, 25);
  171.           WRITE(Name, '  Page: ', CurrPage^.Key, ' of ', PageNum, '    ');
  172.           LOWVIDEO;
  173.         END;
  174.     END;
  175.   { --------------------------------- }
  176.  
  177.     PROCEDURE WritePage(Position : BYTE);
  178.     VAR
  179.       Line    : BYTE;
  180.       WorkStr : STRING[80];
  181.     BEGIN
  182.       ClrScr;
  183.       HIGHVIDEO;
  184.       GotoXY(1, 25);
  185.       WRITE(Name, '  Page: ', CurrPage^.Key, ' of ', LastPageInFile);
  186.       GotoXY(54, 25);
  187.       WRITE(#26#24#25#27, ' <Home> <End> <Esc>');
  188.       LOWVIDEO;
  189.       Line := 1;
  190.       WHILE (Line <= NL) DO
  191.         BEGIN
  192.           WorkStr := COPY(CurrPage^.Pg[Line], Position,    { Truncate line to }
  193.             LENGTH(CurrPage^.Pg[Line]) - Position + 1);    { 80 characters    }
  194.           GotoXY(1, Line);
  195.           WRITE(WorkStr);
  196.           Inc(Line);
  197.         END;
  198.       NewScr := FALSE;
  199.     END;
  200.   { --------------------------------- }
  201.  
  202.     PROCEDURE FillBuffer(PageNum : INTEGER);
  203.     VAR
  204.       TempPage : INTEGER;
  205.       Line     : BYTE;
  206.     BEGIN
  207.       WHILE (FirstPg <> NIL) DO                                { Clear Buffer }
  208.         DeleteViewPage(FirstPg, LastPg, FirstPg^.Key);
  209.       PagesInBuffer := 0;
  210.  
  211.       IF (PageNum = LastPageInFile) THEN               { Position BufferStart }
  212.         BufferStart := LastPageInFile - MaxPages + 1   { for maximum pages    }
  213.       ELSE BufferStart := PageNum - MaxPages DIV 2;
  214.       IF ((BufferStart + MaxPages - 1) >= LastPageInFile) THEN
  215.         BufferStart := LastPageInFile - MaxPages + 1;
  216.       IF (BufferStart < 1) THEN BufferStart := 1;
  217.  
  218.       TempPage := 1;
  219.       RESET(Source);
  220.       ClrLn(1, 25);      WRITE('Reading Page');
  221.       WHILE (TempPage < BufferStart) DO                { Skip to Buffer Start }
  222.         BEGIN
  223.           FOR Line := 1 TO NL DO READLN(Source, TempStr);
  224.           GotoXY(14, 25);
  225.           WRITE(TempPage);
  226.           Inc(TempPage);
  227.         END;
  228.  
  229.       GotoXY(1, 25);                                            { Fill Buffer }
  230.       WRITE('Filling Buffer, Page ', TempPage);
  231.       WHILE (((BufferStart + PagesInBuffer - 1) <= LastPageInFile)
  232.       AND (PagesInBuffer <= MaxPages)) OR EOF(Source) DO
  233.         BEGIN
  234.           ReadPage(TempPage);
  235.           GotoXY(22, 25);
  236.           WRITE(TempPage);
  237.           IF (TempPage = PageNum) THEN
  238.             BEGIN
  239.               CurrPage := LastPg;
  240.               WritePage(1);
  241.               BufPagesFull := (PagesInBuffer = MaxPages) OR EOF(Source);
  242.               WHILE KEYPRESSED DO Reply := ReadKey;               { Clear Kbd }
  243.               EXIT;
  244.             END;
  245.           Inc(TempPage);
  246.           Inc(PagesInBuffer);
  247.         END;
  248.     END;
  249.   { --------------------------------- }
  250.  
  251.   BEGIN
  252.     WOpen(3);
  253.     ClrScr;
  254.     FileBufSize := 4096;                  { FileBufSize is kept relatively    }
  255.     GETMEM(FileBuffer, FileBufSize);      { small to maximize number of pages }
  256.     ASSIGN(Source, Name);
  257.     SetTextBuf(Source, FileBuffer^, FileBufSize);
  258.     GetFAttr(Source, Attribute);                        { Save file attribute }
  259.     SetFAttr(Source, Archive);
  260.     RESET(Source);
  261.     IF (IOResult = 0) THEN
  262.       BEGIN
  263.         FirstPg := NIL;
  264.         LastPg := NIL;
  265.         CurrPage := NIL;
  266.         NewScr := TRUE;
  267.         BufferFull := FALSE;
  268.         BufPagesFull := TRUE;
  269.         EndOfFile := FALSE;
  270.         LastPageInFile := 0;
  271.         MaxPages := 0;
  272.         SpaceStr := ' ';
  273.         CursorOn(FALSE);
  274.         Place := 1;
  275.         ReadPage(1);
  276.         CurrPage := FirstPg;
  277.         REPEAT
  278.           IF NewScr THEN WritePage(Place);
  279.           WHILE (NOT BufferFull) AND (NOT KeyPressed) AND (NOT EndOfFile) DO
  280.             BEGIN
  281.               ReadPage(LastPg^.Key + 1);
  282.               BufferFull := (MaxAvail < 10240);
  283.               IF BufferFull AND (NOT EndOfFile) THEN
  284.                 BEGIN
  285.                   BufferStart := 1;
  286.                   MaxPages := LastPg^.Key;
  287.                   LastPageInFile := MaxPages + 1;
  288.                   Line := 1;
  289.                   ClrLn(1, 25);
  290.                   WRITE('Reading Page ', LastPageInFile);
  291.                   WHILE NOT EOF(Source) DO
  292.                     BEGIN
  293.                       IF (Line > NL) THEN
  294.                         BEGIN
  295.                           Line := 1;
  296.                           GotoXY(14, 25);  WRITE(LastPageInFile);
  297.                           Inc(LastPageInFile);
  298.                         END;
  299.                       READLN(Source, TempStr);
  300.                       Inc(Line);
  301.                     END;
  302.                   WritePage(Place);
  303.                 END;
  304.             END;
  305.           IF BufferFull THEN
  306.             WHILE (NOT KEYPRESSED) AND (NOT BufPagesFull) DO
  307.               BEGIN
  308.                 ReadPage(LastPg^.Key + 1);
  309.                 Inc(PagesInBuffer);
  310.                 BufPagesFull := (PagesInBuffer + 1 = MaxPages) OR EOF(Source);
  311.               END;
  312.           Reply := GetKey(#0+#27, FALSE);
  313.           NewScr := (Reply IN MoveChar);
  314.           CASE Reply OF
  315.             Down, PgDn : IF NOT BufferFull THEN
  316.                   BEGIN
  317.                    IF (CurrPage^.Next <> NIL) THEN
  318.                      CurrPage := CurrPage^.Next;
  319.                   END
  320.                 ELSE
  321.                   BEGIN
  322.                     IF (CurrPage^.Key < LastPageInFile) THEN
  323.                       IF (CurrPage^.Next = NIL)
  324.                         THEN FillBuffer(CurrPage^.Key + 1)
  325.                       ELSE CurrPage := CurrPage^.Next;
  326.                   END;
  327.             Up, PgUp : IF NOT BufferFull THEN
  328.                          BEGIN
  329.                            IF (CurrPage^.Last <> NIL) THEN
  330.                              CurrPage := CurrPage^.Last;
  331.                          END
  332.                        ELSE
  333.                          BEGIN
  334.                            IF (CurrPage^.Key > 1) THEN
  335.                              IF (CurrPage^.Last = NIL)
  336.                                 THEN FillBuffer(CurrPage^.Key - 1)
  337.                              ELSE CurrPage := CurrPage^.Last;
  338.                          END;
  339.             Home : BEGIN
  340.                      Place := 1;
  341.                      IF NOT BufferFull THEN CurrPage := FirstPg
  342.                      ELSE
  343.                        BEGIN
  344.                          IF (BufferStart > 1) THEN FillBuffer(1)
  345.                          ELSE CurrPage := FirstPg;
  346.                        END;
  347.                    END;
  348.             EndKey : BEGIN
  349.                        Place := 1;
  350.                        IF NOT BufferFull THEN CurrPage := LastPg
  351.                        ELSE
  352.                          BEGIN
  353.                            IF (BufferStart + MaxPages - 1 < LastPageInFile)
  354.                              AND (BufPagesFull) THEN FillBuffer(LastPageInFile)
  355.                            ELSE CurrPage := LastPg;
  356.                          END;
  357.                      END;
  358.             Left : Place := 1;
  359.             Right : Place := 10;
  360.           END;
  361.         UNTIL (Reply = #27);
  362.       END;
  363.     CLOSE(Source);
  364.     IF (IOResult = 0) THEN SetFAttr(Source, Attribute);   { Restore attribute }
  365.     WHILE (FirstPg <> NIL) DO DeleteViewPage(FirstPg, LastPg, FirstPg^.Key);
  366.     FREEMEM(FileBuffer, FileBufSize);
  367.     WClose;
  368.     SpaceStr := '─';
  369.   END;
  370.   { ------------------------------------------------------------------------- }
  371.  
  372. END.
  373. 
  374.