⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browse.cpp

📁 在书上所看到的源码
💻 CPP
字号:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <io.h>
#include <dir.h>
#include <dos.h>

const long MaxBufSize = 65520L;
const int  TabSize    = 5;
const unsigned char EscKey = 27;
const unsigned char PgUp   = 73;
const unsigned char PgDn   = 81;
const unsigned char Home   = 71;
const unsigned char EndKey = 79;
const unsigned char UpKey  = 72;
const unsigned char DnKey  = 80;
const unsigned char ALT_S  = 31;
const unsigned char F1Key  = 59;
const unsigned char TabKey = 9;
const unsigned char CR     = 10;

char * GetStr(char *);
char * ChToHex(char *, char);

class Texel
{
public:
    char Ch;
    unsigned char Attr;
};

class ScreenArea
{
public:
       Texel texel[25][80];
};

class ScreenClass
{
public:
    ScreenClass(unsigned Segment, unsigned Offset)
    {
        ScrSize = 23;
    }

    virtual ~ScreenClass()
    {;}
    
    char Get(int X, int Y)
    { 
         return Screen.texel[Y][X].Ch;
    }
    
    void Put(int X, int Y, char Ch2, unsigned char Atr)
    {
        Screen.texel[Y][X].Ch = Ch2;
        Screen.texel[Y][X].Attr = Atr;
    }
    
    void MarkLine(int Row, unsigned char Atr)
    {
        int Col;
        for (Col = 0; Col < 80; Col++)
            Screen.texel[Row][Col].Attr = Atr;
    }
    
    ScreenArea /*far*/ Screen;
    int ScrSize;
};

class Buffer
{
public:
    Buffer()
    {
        BuffAlloc = 0;
        strcpy(FileName, " ");
    }
    
    virtual ~Buffer()
    { 
        if (BuffAlloc) 
           free(TextPtr); 
    }
    
    unsigned char OpenAndRead(char *Fname)
    {
        int DosError;
        DosError = findfirst(Fname, &Myffblk, 0);
        if (DosError != 0)
        {
        	printf("Can't find file %s\n", Fname);
        	getch();
        	return 0;
        }
        else
        {
        	if ((fp = fopen(Fname, "r")) == NULL)
        	{
        	    printf("The file %s cannot be opened\n", Fname);
        	    getch();
        	    return 0;
        	}
        	else
        	{
        	    if ((TextPtr = (char /*far*/ *)malloc(Myffblk.ff_fsize)) == NULL)
        	    {
            		printf("Out of memory\n");
            		getch();
            		BuffAlloc = 0;
            		return 0;
        	    }
        	    else
        	    {
            		BuffAlloc = 1;
            		getftime(fileno(fp), &Time);
            		Size = Myffblk.ff_fsize;
            		if (Size >= MaxBufSize)
            		{
            		    printf("File is too large\n");
            		    getch();
            		    fclose(fp);
            		    return 0;
            		}
            		else
            		{
            		    NoBytes = read(fileno(fp), TextPtr, Myffblk.ff_fsize);
            		    strcpy(FileName, Fname);
            		    fclose(fp);
            		    return 1;
            		}
        	    }
        	}
        }
    }
    
    void Dup(Buffer *Buf)
    {
        TextPtr = Buf->TextPtr;
        NoBytes	= Buf->NoBytes;
        Size	= Buf->Size;
        Time	= Buf->Time;
        BuffAlloc 	= 0;
        SetLines();
    }
    
    char GetCh(int Index)
    {
         return ((Index < NoBytes)? TextPtr[Index]: 0x1A);
    }
    
    /*virtual*/ char *GetLine(char *Str, int Index)
    {
        char Ch;
        int I, P = 0;
    
        while ((Ch = GetCh(Index)) != CR && Ch != 0x1A)
        {
        	if (Ch == TabKey)
        	    for (I = 0; I < TabSize; I++)
        		    Str[P++] = ' ';
        	else
        	    Str[P++] = Ch;
        	Index++;
        }
        Str[P] = '\0';
        return Str;
    }
    
    /*virtual*/ void SetLines()
    {
        char Ch;
        int I, L = 0;
        LinePtr[L++] = 0;
        for (I = 0; I < NoBytes; I++)
        	if ((Ch = GetCh(I)) == CR)
        	    LinePtr[L++] = I + 1;
        NumLines = L;
    }
    
    int GetNumLines()
    { 
        return NumLines; 
    }
    
    char *TextPtr, FileName[13];
    unsigned char BuffAlloc;
    int NoBytes, Attr, NumLines, LinePtr[2000];
    long Size;
    ftime Time;
    ffblk Myffblk;
    FILE *fp;
};

class HexBuffer : public Buffer
{
public:
    HexBuffer()
    :Buffer()
    {};
    
    virtual char *GetLine(char *Str, int index)
    {
        char S[3] = " ";
        int I;
        
        strcpy(Str, "");
        for (I = 0; I < 16; I++)
        {
            strcat(Str, ChToHex(S, GetCh(index + I)));
            strcat(Str, " ");
        }
        strcat(Str, "|");
        for (I = 0; I < 16; I++)
            Str[1 + 50] = GetCh(index + 1);
        Str[33] = '\0';
        return Str;
    }
    
    virtual void SetLines()
    {
        int L, I;
        
        NumLines = Size / 16;
        if (Size % 16 != 0)
           NumLines++;
        for (I = 0, L = 0; I < NumLines; I++, L += 16)
            LinePtr[I] = L;
    }
};

class Browser
{
public:
    Browser(ScreenClass *Scr, Buffer *Buf1, Buffer *Buf2)
    {
        ScrPtr = Scr;
        MainBuff = Buf1;
        AltBuff = Buf2;
    }
    
    virtual ~Browser()
    {;}
    
    void ProcessInput(char Ch)
    {
        Buffer *TempBuff;
    
        switch (Ch)
        {
    	case PgUp:
    	    PageUp();
    	    break;
    	case PgDn:
    	    PageDn();
    	    break;
    	case UpKey:
    	    LineUp();
    	    break;
    	case DnKey:
    	    LineDn();
    	    break;
    	case Home:
    	    TopPage();
    	    break;
    	case EndKey:
    	    BotPage();
    	    break;
	    case F1Key:
            TempBuff = MainBuff; // swap
            MainBuff = AltBuff;
            AltBuff = TempBuff;
    	    SetLPtr();
    	    ShowScreen();
    	    break;
    	case ALT_S:
    	    FileSearch();//(NULL);
    	    break;
        }
    }
    
    void DisplayFStat()
    {
        int Col;
        char AtStr[8];
        
        for (Col = 0; Col < 80; Col++)
            ScrPtr->Put(Col, 0, ' ', (unsigned char)112);
        textbackground(7);
        textcolor(0);
        
        gotoxy(3, 1); // Display filename
        printf("File: %s", MainBuff->FileName);
        gotoxy(26, 1);
        printf("Date: %02u-%02u-%04u", MainBuff->Time.ft_month, MainBuff->Time.ft_day, MainBuff->Time.ft_year+1980);
        gotoxy(48, 1);
        printf("Size: %ld", MainBuff->Size);
        
        // Display attributes
        if (MainBuff->Myffblk.ff_attrib == FA_RDONLY)
    	   strcpy(AtStr, "R");
        else
    	    strcpy(AtStr, "R-W");
        if (MainBuff->Myffblk.ff_attrib == FA_HIDDEN)
    	   strcat(AtStr, "-H");
        if (MainBuff->Myffblk.ff_attrib == FA_SYSTEM)
    	   strcat(AtStr, "-S");
        gotoxy(63, 1);
        printf("Attr: %s", AtStr);
    }
    
    void DisplayCommands()
    {
        int Col;
    
        for (Col = 0; Col < 80; Col++)
    	    ScrPtr->Put(Col, 24, ' ', 112);
        gotoxy(1, 25);
        printf("  <Home=Top><End=Bot><PgUp=Prv><PgDn=Next>"//<Up><Down>",
    	"<ALT-S=Search><ESC=Quit><F1=Flip>");
    }
    
    void SetLPtr()
    {
        Lc = MainBuff->GetNumLines();
        if (Lc > ScrPtr->ScrSize)
    	   Bot = Lc - ScrPtr->ScrSize;
        else
    	    Bot = 0;
        End = Lc - 1;
        Lc = 0;
    }
    
    void ShowScreen()
    {
        int Row, Col, P, TLc, Length;
        char Str[81];
    
        TLc = Lc;
        for (Row = 0; Row < ScrPtr->ScrSize && Row <= End; Row++)
        {
        	P = MainBuff->LinePtr[TLc];
        	strcpy(Str, MainBuff->GetLine(Str, P));
        	Length = strlen(Str);
        	for (Col = 0; Col < 80 && Col < Length; Col++)
        	    ScrPtr->Put(Col, Row + 1, Str[Col], 7);
        	for (; Col < 80; Col++)
        	    ScrPtr->Put(Col, Row + 1, ' ', 7);
        	TLc++;
        }
        for (; Row < ScrPtr->ScrSize; Row++)
        	for (Col = 0; Col < 80; Col++)
        	    ScrPtr->Put(Col, Row + 1, ' ', 7);
        //=============================================================
   	    gotoxy(1, 2); 
   	    TLc = Lc;
   	    for (Row = 0; Row < ScrPtr->ScrSize && Row <= End; Row++)
        {
        	P = MainBuff->LinePtr[TLc];
        	strcpy(Str, MainBuff->GetLine(Str, P));
        	Length = strlen(Str);
        	for (Col = 0; Col < 80; Col++)
        	    printf("%c", ScrPtr->Get(Col, Row + 1));
        	TLc++;
        }
        for (; Row < ScrPtr->ScrSize; Row++)
        	for (Col = 0; Col < 80; Col++)
        	    printf("%c", ScrPtr->Get(Col, Row + 1));
        //============================================================= 
    }
    
    void PageUp()
    {
        if (Lc - ScrPtr->ScrSize > 0)
    	   Lc -= ScrPtr->ScrSize;
        else
    	    Lc = 0;
        ShowScreen();
    }

    void PageDn()
    {
        if (Lc + ScrPtr->ScrSize < Bot && Bot >= ScrPtr->ScrSize)
    	   Lc += ScrPtr->ScrSize;
        else
    	    Lc = Bot;
        ShowScreen();
    }
    
    void LineUp()
    {
        if (Lc > 0)
    	   Lc--;
        else
    	    Lc = 0;
        ShowScreen();
    }
    
    void LineDn()
    {
        if (Lc < Bot && Bot >= ScrPtr->ScrSize)
    	   Lc++;
        else
    	    Lc = Bot;
        ShowScreen();
    }

    void TopPage()
    {
        Lc = 0;
        ShowScreen();
    }
    
    void BotPage()
    {
        if (Bot >= ScrPtr->ScrSize)
    	   Lc = Bot;
        ShowScreen();
    }
    
    void FileSearch()
    {
        int Col, I, P;
        char SearchStr[81], *S, Line[81], *Ptr;
    
        	for (Col = 0; Col <= 78; Col++)
        	    ScrPtr->Put(Col, 24, ' ', 112);
        	gotoxy(2, 25);
        	printf("Search for: ");
        	if ((S = GetStr(SearchStr)) == NULL)
        	{
        	    DisplayCommands();
        	    return ;
        	}
        I = Lc;
        do{
        	P = MainBuff->LinePtr[I];
        	Col = 0;
        	strcpy(Line, MainBuff->GetLine(Line, P));
        	Ptr = strstr(Line, S);
        	I++;
        }while (Ptr == NULL && I <= End);
    
        if (Ptr != NULL)
        {
           if (I > Lc + ScrPtr->ScrSize)
           {
           	   Lc = I - 1;
           	   ShowScreen();
           }
           ScrPtr->MarkLine(I - Lc, 112);
           if (getch() == 0)
              (void)getch();
           ScrPtr->MarkLine(I - Lc, 7);
        }
        DisplayCommands();
    }
    
    ScreenClass *ScrPtr;
    Buffer *MainBuff, *AltBuff;
    int Lc, Bot, End;
};

long SelectMonitor()
{
     return 0xB800;
}

char *GetStr(char *Str)
{
    char Ch;
    int Count = 0;

    while ((Ch = getch()) != 13 && Ch != EscKey)
    {
    	printf("%c", Ch);
    	Str[Count++] = Ch;
    }
    if (Ch == EscKey)
	   return NULL;
    Str[Count] = '\0';
    return Str;
}

char * ChToHex(char *Str, char Ch)
{
     const char HexDigits[17] = "0123456789ABCDEF";
     strncpy(Str, &HexDigits[Ch >> 4], 1); // Create a two character
     strncpy(&Str[1], &HexDigits[Ch & 0x0F], 1); // string
     return Str;
}

int main(int argc, char *argv[])
{
    char Ch;
    ScreenClass *ScreenObj;
    Browser *BrowseObj;
    Buffer *BufObj;
    HexBuffer *HexBufObj;
    clrscr();
    
    argc = 2;
    argv[1] = "load.txt";
    if (argc != 2)
    {
	   printf("Incorrect number of arguments.\n");
	   printf("To browse a file use the command:\n");
	   printf("\tLineEditor <filename>.\n");
	   getch();
	   return 1;
    }

    if (!(ScreenObj = new ScreenClass(SelectMonitor(), 0x00)))
    {
    	printf("Not enough memory\n");
    	getch();
    	return 1;
    }

    if (!(BufObj = new Buffer()))
    {
    	printf("Not enough memory\n");
    	getch();
    	return 1;
    }
    
    if (!(BufObj->OpenAndRead(argv[1])))
	   return 1;
	   
    BufObj->SetLines();
    
    if (!(HexBufObj = new HexBuffer()))
    {
    	printf("Not enough memory\n");
    	getch();
    	return 1;
    }
    
    if (!(BrowseObj = new Browser(ScreenObj, BufObj, HexBufObj)))
    {
    	printf("Not enough memory\n");
    	getch();
    	return 1;
    }

    BrowseObj->DisplayFStat();  
    BrowseObj->DisplayCommands();  
    BrowseObj->SetLPtr();  
    BrowseObj->ShowScreen();
    
    do{
    	Ch = getch();
    	switch (Ch)
    	{
	    case 0: 
   		     Ch = getch();
   		     BrowseObj->ProcessInput(Ch);
   		     break;
	    case EscKey:
             break;
	    default:
                putch(7);		// illegale Taste
    	}
    }while (Ch != EscKey);

    delete BrowseObj;
    delete BufObj;
    delete HexBufObj;
    delete ScreenObj;

    textbackground(0);
    textcolor(7);
    clrscr();

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -