|
|
/*** List.c
* */
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include "list.h"
#include "..\he\hexedit.h"
BOOL IsValidKey (PINPUT_RECORD pRecord); void DumpFileInHex (void);
static char Name[] = "Ken Reneris. List Ver 1.0.";
struct Block *vpHead = NULL; /* Current first block */ struct Block *vpTail = NULL; /* Current last block */ struct Block *vpCur = NULL; /* Current block for display 1st line */ /* (used by read ahead to sense) */ struct Block *vpBCache = NULL; /* 'free' blocks which can cache reads */ struct Block *vpBOther = NULL; /* (above) + for other files */ struct Block *vpBFree = NULL; /* free blocks. not valid for caching reads */
int vCntBlks; /* No of blocks currently is use by cur file*/
int vAllocBlks = 0; /* No of blocks currently alloced */ int vMaxBlks = MINBLKS; /* Max blocks allowed to alloc */ long vThreshold = MINTHRES*BLOCKSIZE; /* Min bytes before read ahead */
HANDLE vSemBrief = 0L; /* To serialize access to Linked list info */ HANDLE vSemReader = 0L; /* To wakeup reader thread when threshold */ HANDLE vSemMoreData = 0L; /* Blocker for Disp thread if ahead of read */ HANDLE vSemSync = 0L; /* Used to syncronize to sync to the reader */
USHORT vReadPriNormal; /* Normal priority for reader thread */ unsigned vReadPriBoost; /* Boosted priority for reader thread */ char vReaderFlag; /* Insructions to reader */
HANDLE vFhandle = 0; /* Current file handle */ long vCurOffset; /* Current offset in file */ char vpFname [40]; /* Current files name */ struct Flist *vpFlCur =NULL; /* Current file */ USHORT vFType; /* Current files handle type */ WIN32_FIND_DATA vFInfo; /* Current files info */ char vDate [30]; /* Printable dat of current file */
char vSearchString [50]; /* Searching for this string */ char vStatCode; /* Codes for search */ long vHighTop = -1L; /* Current topline of hightlighting */ int vHighLen; /* Current bottom line of hightlighting */ char vHLTop = 0; /* Last top line displayed as highlighted */ char vHLBot = 0; /* Last bottom line displayed as highlighed */ char vLastBar; /* Last line for thumb mark */ int vMouHandle; /* Mouse handle (for Mou Apis) */
HANDLE vhConsoleOutput; // Handle to the console
char *vpOrigScreen; /* Orinal screen contents */ int vOrigSize; /* # of bytes in orignal screen */ USHORT vVioOrigRow = 0; /* Save orignal screen stuff. */ USHORT vVioOrigCol = 0;
int vSetBlks = 0; /* Used to set INI value */ long vSetThres = 0L; /* Used to set INI value */ int vSetLines; /* Used to set INI value */ int vSetWidth; /* Used to set INI value */ CONSOLE_SCREEN_BUFFER_INFO vConsoleCurScrBufferInfo; CONSOLE_SCREEN_BUFFER_INFO vConsoleOrigScrBufferInfo;
/* Screen controling... used to be static in ldisp.c */ char vcntScrLock = 0; /* Locked screen count */ char vSpLockFlag = 0; /* Special locked flag */ HANDLE vSemLock = 0; /* To access vcntScrLock */
char vUpdate; int vLines = 23; /* CRTs no of lines */ int vWidth = 80; /* CRTs width */ int vCurLine; /* When processing lines on CRT */ Uchar vWrap = 254; /* # of chars to wrap at */ Uchar vIndent = 0; /* # of chars dispaly is indented */ Uchar vDisTab = 8; /* # of chars per tab stop */ Uchar vIniFlag = 0; /* Various ini bits */
Uchar vrgLen [MAXLINES]; /* Last len of data on each line */ Uchar vrgNewLen[MAXLINES]; /* Temp moved to DS for speed */ char *vScrBuf; /* Ram to build screen into */ ULONG vSizeScrBuf; int vOffTop; /* Offset into data for top line */ unsigned vScrMass = 0; /* # of bytes for last screen (used for %) */ struct Block *vpBlockTop; /* Block for start of screen (dis.asm) overw*/ struct Block *vpCalcBlock; /* Block for start of screen */ long vTopLine = 0L; /* Top line on the display */
#define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
#define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
#define HIWHITE_ON_BLUE (BACKGROUND_BLUE | FOREGROUND_WHITE | FOREGROUND_INTENSITY)
WORD vAttrTitle = HIWHITE_ON_BLUE; WORD vAttrList = BACKGROUND_BLUE | FOREGROUND_WHITE; WORD vAttrHigh = BACKGROUND_WHITE | FOREGROUND_BLUE; WORD vAttrKey = HIWHITE_ON_BLUE; WORD vAttrCmd = BACKGROUND_BLUE | FOREGROUND_WHITE; WORD vAttrBar = BACKGROUND_BLUE | FOREGROUND_WHITE;
WORD vSaveAttrTitle = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; WORD vSaveAttrList = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; WORD vSaveAttrHigh = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; WORD vSaveAttrKey = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; WORD vSaveAttrCmd = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; WORD vSaveAttrBar = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
char vChar; /* Scratch area */ char *vpReaderStack; /* Readers stack */
long vDirOffset; /* Direct offset to seek to */ /* table */ long vLastLine; /* Absolute last line */ long vNLine; /* Next line to process into line table */ long *vprgLineTable [MAXTPAGE]; /* Number of pages for line table */
HANDLE vStdOut; HANDLE vStdIn;
char MEMERR[]= "Malloc failed. Out of memory?";
void __cdecl main ( int argc, char **argv ) { void usage (void); char *pt; DWORD dwMode;
if (argc < 2) usage ();
while (--argc) { ++argv; if (*argv[0] != '-' && *argv[0] != '/') { AddFileToList (*argv); continue; } pt = (*argv) + 2; if (*pt == ':') pt++;
switch ((*argv)[1]) { case 'g': // Goto line #
case 'G': if (!atol (pt)) usage ();
vIniFlag |= I_GOTO; vHighTop = atol (pt); vHighLen = 0; break;
case 's': // Search for string
case 'S': vIniFlag |= I_SEARCH; strncpy (vSearchString, pt, 40); vSearchString[39] = 0; vStatCode |= S_NEXT | S_NOCASE; InitSearchReMap (); break;
default: usage (); } }
if ((vIniFlag & I_GOTO) && (vIniFlag & I_SEARCH)) usage ();
if (!vpFlCur) usage ();
while (vpFlCur->prev) vpFlCur = vpFlCur->prev; strcpy (vpFname, vpFlCur->rootname);
vSemBrief = CreateEvent( NULL, MANUAL_RESET, SIGNALED,NULL ); vSemReader = CreateEvent( NULL, MANUAL_RESET, SIGNALED,NULL ); vSemMoreData = CreateEvent( NULL, MANUAL_RESET, SIGNALED,NULL ); vSemSync = CreateEvent( NULL, MANUAL_RESET, SIGNALED,NULL ); vSemLock = CreateEvent( NULL, MANUAL_RESET, SIGNALED,NULL );
if( !(vSemBrief && vSemReader &&vSemMoreData && vSemSync && vSemLock) ) { printf("Couldn't create events \n"); ExitProcess (0); // Have to put an error message here
}
vhConsoleOutput = CreateConsoleScreenBuffer(GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CONSOLE_TEXTMODE_BUFFER, NULL );
if( vhConsoleOutput == (HANDLE)(-1) ) { printf( "Couldn't create handle to console output \n" ); ExitProcess (0); }
vStdIn = GetStdHandle( STD_INPUT_HANDLE ); GetConsoleMode( vStdIn, &dwMode ); SetConsoleMode( vStdIn, dwMode | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT ); vStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
init_list (); vUpdate = U_NMODE;
if (vIniFlag & I_SEARCH) FindString ();
if (vIniFlag & I_GOTO) GoToMark ();
main_loop (); }
void usage ( void ) { puts ("list [-s:string] [-g:line#] filename, ..."); CleanUp(); ExitProcess(0);
}
/*** main_loop
* */ void main_loop () { int i; int ccnt = 0; char SkipCnt=0; WORD RepeatCnt=0; INPUT_RECORD InpBuffer; DWORD cEvents; BOOL bSuccess; BOOL bKeyDown = FALSE;
for (; ;) { if (RepeatCnt <= 1) { if (vUpdate != U_NONE) { if (SkipCnt++ > 5) { SkipCnt = 0; SetUpdate (U_NONE); } else {
cEvents = 0; bSuccess = PeekConsoleInput( vStdIn, &InpBuffer, 1, &cEvents );
if (!bSuccess || cEvents == 0) { PerformUpdate (); continue; } } }
// there's either a charactor available from peek, or vUpdate is U_NONE
bSuccess = ReadConsoleInput( vStdIn, &InpBuffer, 1, &cEvents );
if (InpBuffer.EventType != KEY_EVENT) {
// TCHAR s[1024];
switch (InpBuffer.EventType) { #if 0
case WINDOW_BUFFER_SIZE_EVENT:
sprintf (s, "WindowSz X=%d, Y=%d", InpBuffer.Event.WindowBufferSizeEvent.dwSize.X, InpBuffer.Event.WindowBufferSizeEvent.dwSize.Y ); DisLn (20, (Uchar)(vLines+1), s); break; #endif
case MOUSE_EVENT:
#if 0
sprintf (s, "Mouse (%d,%d), state %x, event %x", InpBuffer.Event.MouseEvent.dwMousePosition.X, InpBuffer.Event.MouseEvent.dwMousePosition.Y, InpBuffer.Event.MouseEvent.dwButtonState, InpBuffer.Event.MouseEvent.dwEventFlags ); #endif
if (InpBuffer.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED) { // HiWord of ButtonState is signed int, in increments of 120 (WHEEL_DELTA).
// Map each 'detent' to a 4 line scroll in the console window.
// Rolling away from the user should scroll up (dLines should be negative).
// Since rolling away generates a positive dwButtonState, the negative sign
// makes rolling away scroll up, and rolling towards you scroll down.
SHORT dLines = -(SHORT)(HIWORD(InpBuffer.Event.MouseEvent.dwButtonState)) / (WHEEL_DELTA / 4);
vTopLine += dLines;
// make sure to stay between line 0 and vLastLine
if (vTopLine+vLines > vLastLine) vTopLine = vLastLine-vLines; if (vTopLine < 0) vTopLine = 0;
SetUpdateM (U_ALL); }
// DisLn (20, (Uchar)(vLines+1), s);
break;
default: #if 0
sprintf (s, "Unkown event %d", InpBuffer.EventType); DisLn (20, (Uchar)(vLines+1), s); #endif
break; }
continue; }
if (!InpBuffer.Event.KeyEvent.bKeyDown) continue; // don't move on upstrokes
if (!IsValidKey( &InpBuffer )) continue;
RepeatCnt = InpBuffer.Event.KeyEvent.wRepeatCount; if (RepeatCnt > 20) RepeatCnt = 20; } else RepeatCnt--;
// First check for a known scan code
switch (InpBuffer.Event.KeyEvent.wVirtualKeyCode) { case 0x21: /* PgUp */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift up
SHIFT_PRESSED ) { HPgUp (); } else if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ctrl up
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) { if (NextFile (-1, NULL)) { vStatCode |= S_UPDATE; SetUpdate (U_ALL); }
} else { if (vTopLine != 0L) { vTopLine -= vLines-1; if (vTopLine < 0L) vTopLine = 0L; SetUpdateM (U_ALL); } } continue; case 0x26: /* Up */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl up
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | SHIFT_PRESSED ) ) { HUp (); } else { // Up
if (vTopLine != 0L) { vTopLine--; SetUpdateM (U_ALL); } } continue; case 0x22: /* PgDn */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift down
SHIFT_PRESSED ) { HPgDn (); } else if (InpBuffer.Event.KeyEvent.dwControlKeyState & // next file
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) { if (NextFile (+1, NULL)) { vStatCode |= S_UPDATE; SetUpdate (U_ALL); }
} else { // PgDn
if (vTopLine+vLines < vLastLine) { vTopLine += vLines-1; if (vTopLine+vLines > vLastLine) vTopLine = vLastLine - vLines; SetUpdateM (U_ALL); } } continue; case 0x28: /* Down */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl down
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | SHIFT_PRESSED ) ) { HDn (); } else { // Down
if (vTopLine+vLines < vLastLine) { vTopLine++; SetUpdateM (U_ALL); } } continue; case 0x25: /* Left */ if (vIndent == 0) continue; vIndent = (Uchar)(vIndent < vDisTab ? 0 : vIndent - vDisTab); SetUpdateM (U_ALL); continue; case 0x27: /* Right */ if (vIndent >= (Uchar)(254-vWidth)) continue; vIndent += vDisTab; SetUpdateM (U_ALL); continue; case 0x24: /* HOME */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl home
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | SHIFT_PRESSED ) ) { HSUp (); } else { if (vTopLine != 0L) { QuickHome (); SetUpdate (U_ALL); } } continue; case 0x23: /* END */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // shift or ctrl end
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | SHIFT_PRESSED ) ) { HSDn (); } else { if (vTopLine+vLines < vLastLine) { QuickEnd (); SetUpdate (U_ALL); } } continue;
case 0x72: /* F3 */ FindString (); SetUpdate (U_ALL); continue; case 0x73: /* F4 */ vStatCode = (char)((vStatCode^S_MFILE) | S_UPDATE); vDate[ST_SEARCH] = (char)(vStatCode & S_MFILE ? '*' : ' '); SetUpdate (U_HEAD); continue;
case 69: if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ALT-E
( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) { i = vLines <= 41 ? 25 : 43; if (set_mode (i, 0, 0)) SetUpdate (U_NMODE); } continue; case 86: // ALT-V
if (InpBuffer.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) { i = vLines >= 48 ? 25 : 60; if (set_mode (i, 0, 0)) { SetUpdate (U_NMODE); continue; } if (i == 60) if (set_mode (50, 0, 0)) SetUpdate (U_NMODE); } continue; case 0x70: /* F1 */ ShowHelp (); SetUpdate (U_NMODE); continue; case 24: /* Offset */ if (!(vIniFlag & I_SLIME)) continue; SlimeTOF (); SetUpdate (U_ALL); continue; case 0x77: // F8
case 0x1b: // ESC
case 0x51: // Q or q
CleanUp(); ExitProcess(0);
}
// Now check for a known char code...
switch (InpBuffer.Event.KeyEvent.uChar.AsciiChar) { case '?': ShowHelp (); SetUpdate (U_NMODE); continue; case '/': vStatCode = (char)((vStatCode & ~S_NOCASE) | S_NEXT); GetSearchString (); FindString (); continue; case '\\': vStatCode |= S_NEXT | S_NOCASE; GetSearchString (); FindString (); continue; case 'n': vStatCode = (char)((vStatCode & ~S_PREV) | S_NEXT); FindString (); continue; case 'N': vStatCode = (char)((vStatCode & ~S_NEXT) | S_PREV); FindString (); continue; case 'c': case 'C': /* Clear marked line */ UpdateHighClear (); continue; case 'j': case 'J': /* Jump to marked line */ GoToMark (); continue; case 'g': case 'G': /* Goto line # */ GoToLine (); SetUpdate (U_ALL); continue; case 'm': /* Mark line or Mono */ case 'M': if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ALT-M
( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) { i = set_mode (vSetLines, vSetWidth, 1); if (!i) i = set_mode (0, 0, 1); if (!i) i = set_mode (25, 80, 1); if (i) SetUpdate (U_NMODE); } else { MarkSpot (); } continue; case 'p': /* Paste buffer to file */ case 'P': FileHighLighted (); continue; case 'f': /* get a new file */ case 'F': if (GetNewFile ()) if (NextFile (+1, NULL)) SetUpdate (U_ALL);
continue; case 'h': /* hexedit */ case 'H': DumpFileInHex(); SetUpdate (U_NMODE); continue; case 'w': /* WRAP */ case 'W': ToggleWrap (); SetUpdate (U_ALL); continue; case 'l': /* REFRESH */ case 'L': /* REFRESH */ if (InpBuffer.Event.KeyEvent.dwControlKeyState & // ctrl L
( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) { SetUpdate (U_NMODE); } continue; case '\r': /* ENTER*/ SetUpdate (U_HEAD); continue;
default: continue; }
} /* Forever loop */ }
void SetUpdate( int i ) { while (vUpdate>(char)i) PerformUpdate (); vUpdate=(char)i; }
void PerformUpdate ( ) { if (vUpdate == U_NONE) return;
if (vSpLockFlag == 0) { vSpLockFlag = 1; ScrLock (1); }
switch (vUpdate) { case U_NMODE: ClearScr (); DisLn (0, 0, vpFname); DrawBar (); break; case U_ALL: Update_display (); break; case U_HEAD: Update_head (); break; case U_CLEAR: SpScrUnLock (); break; } vUpdate --; }
NTSTATUS fncRead(HANDLE, DWORD, DWORD, char *, ULONG *); NTSTATUS fncWrite(HANDLE, DWORD, DWORD, char *, ULONG *);
void DumpFileInHex( void ) { struct HexEditParm ei; ULONG CurLine;
SyncReader ();
memset ((char *) &ei, 0, sizeof (ei)); ei.handle = CreateFile( vpFlCur->fname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if (ei.handle == INVALID_HANDLE_VALUE) { ei.handle = CreateFile( vpFlCur->fname, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); }
if (ei.handle == INVALID_HANDLE_VALUE) { SetEvent (vSemReader); return ; }
//
// Save current settings for possible restore
//
vpFlCur->Wrap = vWrap; vpFlCur->HighTop = vHighTop; vpFlCur->HighLen = vHighLen; vpFlCur->TopLine = vTopLine; vpFlCur->Loffset = GetLoffset(); vpFlCur->LastLine = vLastLine; vpFlCur->NLine = vNLine;
memcpy (vpFlCur->prgLineTable, vprgLineTable, sizeof (long *) * MAXTPAGE);
vFInfo.nFileSizeLow = 0; setattr2 (0, 0, vWidth, (char)vAttrTitle);
//
// Setup for HexEdit call
//
if (vHighTop >= 0) { // If highlighted area,
CurLine = vHighTop; // use that for the HexEdit
if (vHighLen < 0) // location
CurLine += vHighLen; } else { CurLine = vTopLine; }
ei.ename = vpFname; ei.ioalign = 1; ei.flag = FHE_VERIFYONCE; ei.read = fncRead; ei.write = fncWrite; ei.start = vprgLineTable[CurLine/PLINES][CurLine%PLINES]; ei.totlen = SetFilePointer (ei.handle, 0, NULL, FILE_END); ei.Console = vhConsoleOutput; // our console handle
ei.AttrNorm = vAttrList; ei.AttrHigh = vAttrTitle; ei.AttrReverse = vAttrHigh; HexEdit (&ei);
CloseHandle (ei.handle);
//
// HexEdit is done, let reader and return to listing
//
vReaderFlag = F_NEXT; // re-open current file
// (in case it was editted)
SetEvent (vSemReader); WaitForSingleObject(vSemMoreData, WAITFOREVER); ResetEvent(vSemMoreData); QuickRestore (); /* Get to the old location */ }
int NextFile ( int dir, struct Flist *pNewFile) { struct Flist *vpFLCur; long *pLine;
vpFLCur = vpFlCur; if (pNewFile == NULL) { if (dir < 0) { if (vpFlCur->prev == NULL) { beep (); return (0); } vpFlCur = vpFlCur->prev;
} else if (dir > 0) {
if (vpFlCur->next == NULL) { beep (); return (0); } vpFlCur = vpFlCur->next; } } else vpFlCur = pNewFile;
SyncReader ();
/*
* Remove current file from list, if open error * occured and we are moving off of it. */ if (vFInfo.nFileSizeLow == -1L && vpFLCur != vpFlCur) { if (vpFLCur->prev) vpFLCur->prev->next = vpFLCur->next; if (vpFLCur->next) vpFLCur->next->prev = vpFLCur->prev;
FreePages (vpFLCur);
free ((char*) vpFLCur->fname); free ((char*) vpFLCur->rootname); free ((char*) vpFLCur);
} else {
/*
* Else, save current status for possible restore */ vpFLCur->Wrap = vWrap; vpFLCur->HighTop = vHighTop; vpFLCur->HighLen = vHighLen; vpFLCur->TopLine = vTopLine; vpFLCur->Loffset = GetLoffset(); vpFLCur->LastLine = vLastLine; vpFLCur->NLine = vNLine;
memcpy (vpFLCur->prgLineTable, vprgLineTable, sizeof (long *) * MAXTPAGE);
if (vLastLine == NOLASTLINE) { pLine = vprgLineTable [vNLine/PLINES] + vNLine % PLINES; } }
vFInfo.nFileSizeLow = 0; setattr2 (0, 0, vWidth, (char)vAttrTitle);
vHighTop = -1L; UpdateHighClear ();
vHighTop = vpFlCur->HighTop; vHighLen = vpFlCur->HighLen;
strcpy (vpFname, vpFlCur->rootname); DisLn (0, 0, vpFname);
vReaderFlag = F_NEXT;
SetEvent (vSemReader); WaitForSingleObject(vSemMoreData, WAITFOREVER); ResetEvent(vSemMoreData);
if (pNewFile == NULL) QuickRestore (); /* Get to the old location */
return (1); }
void ToggleWrap( ) { SyncReader ();
vWrap = (Uchar)(vWrap == (Uchar)(vWidth - 1) ? 254 : vWidth - 1); vpFlCur->FileTime.dwLowDateTime = (unsigned)-1; /* Cause info to be invalid */ vpFlCur->FileTime.dwHighDateTime = (unsigned)-1; /* Cause info to be invalid */ FreePages (vpFlCur); NextFile (0, NULL); }
/*** QuickHome - Deciede which HOME method is better.
* * Roll que backwards or reset it. * */
void QuickHome () {
vTopLine = 0L; /* Line we're after */ if (vpHead->offset >= BLOCKSIZE * 5) /* Reset is fastest */ QuickRestore ();
/* Else Read backwards */ vpCur = vpHead; }
void QuickEnd () { vTopLine = 1L;
while (vLastLine == NOLASTLINE) { if (_abort()) { vTopLine = vNLine - 1; return ; } fancy_percent (); vpBlockTop = vpCur = vpTail; vReaderFlag = F_DOWN;
ResetEvent (vSemMoreData); SetEvent (vSemReader); WaitForSingleObject(vSemMoreData, WAITFOREVER); ResetEvent(vSemMoreData); } vTopLine = vLastLine - vLines; if (vTopLine < 0L) vTopLine = 0L; QuickRestore (); }
void QuickRestore () { long l; long indx1 = vTopLine/PLINES; long indx2 = vTopLine%PLINES;
SyncReader ();
if(indx1 < MAXTPAGE) { l = vprgLineTable[indx1][indx2]; } else { puts("Sorry, This file is too big for LIST to handle. MAXTPAGE limit exceeded\n"); CleanUp(); ExitProcess(0); }
if ((l >= vpHead->offset) && (l <= vpTail->offset + BLOCKSIZE)) { vReaderFlag = F_CHECK; /* Jump location is alread in */ /* memory. */ SetEvent (vSemReader); return ; }
/* Command read for direct placement */ vDirOffset = (long) l - l % ((long)BLOCKSIZE); vReaderFlag = F_DIRECT; SetEvent (vSemReader); WaitForSingleObject(vSemMoreData, WAITFOREVER); ResetEvent(vSemMoreData); }
/*** InfoRead - return on/off depending if screen area is in memory
* * Also sets some external value to prepair for the screens printing * * Should be modified to be smarter about one line movements. * */ int InfoReady( void ) { struct Block *pBlock; LONG *pLine; long foffset, boffset; int index, i, j;
/*
* Check that first line has been calced */ if (vTopLine >= vNLine) { if (vTopLine+vLines > vLastLine) /* BUGFIX. TopLine can */ vTopLine = vLastLine - vLines; /* get past EOF. */
vReaderFlag = F_DOWN; return (0); }
pLine = vprgLineTable [(int)vTopLine / PLINES]; index = (int)(vTopLine % PLINES); foffset = *(pLine+=index);
/*
* Check that last line has been calced */ if (vTopLine + (i = vLines) > vLastLine) { i = (int)(vLastLine - vTopLine + 1); for (j=i; j < vLines; j++) /* Clear ending len */ vrgNewLen[j] = 0; }
if (vTopLine + i > vNLine) { vReaderFlag = F_DOWN; return (0); }
/*
* Put this loop in assembler.. For more speed * boffset = calc_lens (foffset, i, pLine, index); */
boffset = foffset; for (j=0; j < i; j++) { /* Calc new line len*/ pLine++; if (++index >= PLINES) { index = 0; pLine = vprgLineTable [vTopLine / PLINES + 1]; } boffset += (long)((vrgNewLen[j] = (Uchar)(*pLine - boffset))); } vScrMass = (unsigned)(boffset - foffset);
/*
* Check for both ends of display in memory */ pBlock = vpCur;
if (pBlock->offset <= foffset) { while (pBlock->offset + BLOCKSIZE <= foffset) if ( (pBlock = pBlock->next) == NULL) { vReaderFlag = F_DOWN; return (0); } vOffTop = (int)(foffset - pBlock->offset); vpBlockTop = vpCalcBlock = pBlock;
while (pBlock->offset + BLOCKSIZE <= boffset) if ( (pBlock = pBlock->next) == NULL) { vReaderFlag = F_DOWN; return (0); } if (vpCur != pBlock) { vpCur = pBlock; vReaderFlag = F_CHECK; SetEvent (vSemReader); } return (1); } else { while (pBlock->offset > foffset) if ( (pBlock = pBlock->prev) == NULL) { vReaderFlag = F_UP; return (0); } vOffTop = (int)(foffset - pBlock->offset); vpBlockTop = vpCalcBlock = pBlock;
while (pBlock->offset + BLOCKSIZE <= boffset) if ( (pBlock = pBlock->next) == NULL) { vReaderFlag = F_DOWN; return (0); } if (vpCur != pBlock) { vpCur = pBlock; vReaderFlag = F_CHECK; SetEvent (vSemReader); } return (1); } }
|