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

📄 exbuffer.cpp

📁 Smartphone手机阅读软件
💻 CPP
字号:
// ExBuffer.cpp: implementation of the CExBuffer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ExBuffer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CExBuffer::CExBuffer()
{
	m_nStartLine = 0;
	m_byCurrentFontSize = 0;
	m_byCurrentFontType = 0;
	m_dwMaxLineWidth = 176;
	m_FullScreen = FALSE;
}

CExBuffer::~CExBuffer()
{
}

BOOL CExBuffer::FillLine(BYTE *szSource,DWORD &nLen)
{
	DWORD dwPrevRead = nLen;
	BYTE dwTheLineWidth = 0;
	DWORD dwPtr = 0;
	short dwLine = 0;
//	DWORD dwPrevSpacePos = 0;
	
	BYTE pcLineBuf[50];
	BYTE pcTmp[50];
	memset(pcLineBuf,0,sizeof(pcLineBuf));
   	
	short byMaxTmpLine = 0;//NUMS OF CHAR FOR MAX WIDTH LINE
	DWORD dwTmpPtr = 0;  //Only a long word exists in  a line

	while(dwPtr <dwPrevRead)
	{
		BYTE c = szSource[dwPtr++];
		if(c == 0x0D || c == 0x0A)
		{
			if((c == 0x0D)&&(szSource[dwPtr] == 0x0A))
				dwPtr ++;
			if(dwLine == 0) //EMPTY LINE 
				m_pcLine.Add(CString("\r\n"));	
			else
			{	//END OF A LINE
				pcLineBuf[dwLine] = '\0';
				m_pcLine.Add(CString(pcLineBuf));
				dwLine = 0;
				dwTheLineWidth = 0;
			}
			memset(pcLineBuf,0,sizeof(pcLineBuf));
		}
		else 
		{
			dwTheLineWidth += byFontWidth[m_byCurrentFontType * 3 + m_byCurrentFontSize][c];
			if(dwTheLineWidth <= m_dwMaxLineWidth)
			{
				if(c == VK_TAB) c = VK_SPACE;//TAB = 1 SPACE, SHOULD BE 8
		//		else if(c == VK_SPACE) dwPrevSpacePos = dwLine;
				pcLineBuf[dwLine ++] = c;
			}
			else
			{
		//		dwPtr -= dwLine - dwPrevSpacePos;
		//		pcLineBuf[dwPrevSpacePos + 1] = '\0';
	
				byMaxTmpLine = dwLine - 1;
				dwTmpPtr = dwPtr - 2;
				memset(pcTmp,0,sizeof(pcTmp));
				memcpy(pcTmp,pcLineBuf,byMaxTmpLine);
								
				while((--dwLine>=0)&&((pcLineBuf[dwLine] >= '0' && pcLineBuf[dwLine] <= '9') ||
					  (pcLineBuf[dwLine] >= 'a' && pcLineBuf[dwLine] <= 'z') ||
					  (pcLineBuf[dwLine] >= 'A' && pcLineBuf[dwLine] <= 'Z') ||
					   pcLineBuf[dwLine] == '_' || pcLineBuf[dwLine] == '*'  ||
					   pcLineBuf[dwLine] == '^' || pcLineBuf[dwLine] == '~' ))
					   --dwPtr;
				if(dwLine<0)
				{
					memset(pcLineBuf,0,sizeof(pcLineBuf));
					memcpy(pcLineBuf,pcTmp,byMaxTmpLine);
					dwPtr = dwTmpPtr;
					dwLine = byMaxTmpLine;
				}
				else
					--dwPtr;	
				
				pcLineBuf[dwLine + 1] = '\0';
				m_pcLine.Add(CString(pcLineBuf));
				memset(pcLineBuf,0,sizeof(pcLineBuf));
				dwTheLineWidth = 0;	
				dwLine = 0;
			}
		}
	}
	pcLineBuf[dwLine] = '\0';
	memset(szSource,0,sizeof(szSource));
	memcpy((LPVOID)szSource,pcLineBuf,dwLine+1);
    nLen = dwLine+1;
	return TRUE;

}

BOOL CExBuffer::LoadTxtFile(LPCTSTR szTxtFileName)
{
	HANDLE m_pTargetFile = CreateFile(szTxtFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
	if(m_pTargetFile == INVALID_HANDLE_VALUE)
		return FALSE;

	DWORD dwNumBytesToGet = 32768;
	BYTE *szFileContent = new BYTE [dwNumBytesToGet + 1];
	ATLASSERT(szFileContent != NULL);
	memset(szFileContent ,0,sizeof(szFileContent ));
	
	DWORD dwNumBytesRead = 0;
	do
	{
		if (!ReadFile(m_pTargetFile, szFileContent+dwNumBytesRead, dwNumBytesToGet, &dwNumBytesRead, 0))
			return FALSE;
		if (dwNumBytesRead > 0)
		{
//			szFileContent[dwNumBytesRead] = '\0';
			FillLine(szFileContent,dwNumBytesRead);
			dwNumBytesToGet = 32768 - dwNumBytesRead;
		}
	}while(dwNumBytesRead >0);
	
	m_pcLine.Add(CString(szFileContent));

	delete [] szFileContent;

	if(m_pTargetFile != INVALID_HANDLE_VALUE)
		CloseHandle(m_pTargetFile);
	return TRUE;
}

BOOL CExBuffer::LoadHtmlFile(LPCTSTR szHtmlFileName)
{
	if(szHtmlFileName == NULL) return FALSE;
	CString szTxtFile("\\WINDOWS\\MYPRC.TMP");
	Html2Txt(szHtmlFileName,szTxtFile);
	
	m_pcLine.RemoveAll();
	
	BOOL bSuccess = LoadTxtFile(szTxtFile);

	DeleteFile(szTxtFile);
	
	return bSuccess;

}

BOOL CExBuffer::LoadPrcFile(LPCTSTR szFileName)
{
	BOOL bSuccess = FALSE;
	const DWORD dwNumBytesToGet = 6000;
	BYTE szFileContent[dwNumBytesToGet + 1];
	DWORD dwNumBytesRead;
	PRC_FILE_HEADER PRCHeader;
	memset(&PRCHeader,0,sizeof(PRC_FILE_HEADER));

	CString szTmpFile("\\WINDOWS\\MYPRC.TMP");
	HANDLE hTmpFile = CreateFile(szTmpFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
	if(hTmpFile == INVALID_HANDLE_VALUE)
		return FALSE;

	HANDLE m_pTargetFile = CreateFile(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
	if(m_pTargetFile == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hTmpFile);
		return FALSE;
	}

	//Read FILE header INFORMATION
	if(!ReadFile(m_pTargetFile, &PRCHeader, PRC_FILE_HEADER_LEN, &dwNumBytesRead, 0))
		return FALSE;

	DWORD dwOffSet;
	if(!ReadFile(m_pTargetFile, &dwOffSet, 4, &dwNumBytesRead, 0))
		return FALSE;
	
	dwOffSet = SwapLong(dwOffSet);
	SetFilePointer(m_pTargetFile,dwOffSet,NULL,FILE_BEGIN);
	if(!ReadFile(m_pTargetFile, &dwOffSet, 2, &dwNumBytesRead, 0))
		return FALSE;

	WORD bCompressed;
	bCompressed = SwapWord((WORD)dwOffSet);

	ATLASSERT((bCompressed == 1)||(bCompressed == 2)); //1: PLAIN TEXT 2: COMPRESSED
	bCompressed--;

	DWORD dwLen;
	dwLen = GetFileSize(m_pTargetFile,NULL);
	WORD nRecs;
	nRecs = SwapWord(PRCHeader.wRecords) - 1;

	DWORD dwRecLen;
	int i;
	for (i=0; i<nRecs; i++)
	{
		// read the record offset
		SetFilePointer(m_pTargetFile,0x56 + 8*i,NULL,FILE_BEGIN);
		if(!ReadFile(m_pTargetFile, &dwOffSet, 4, &dwNumBytesRead, 0))
			return FALSE;
		dwOffSet = SwapLong(dwOffSet);

		// read start of next record
		SetFilePointer(m_pTargetFile,0x5E + 8*i,NULL,FILE_BEGIN);
		if(!ReadFile(m_pTargetFile, &dwRecLen, 4, &dwNumBytesRead, 0))
			return FALSE;
		dwRecLen = SwapLong(dwRecLen);
	
		// for the last, use the file len
		if (i==nRecs-1) dwRecLen = dwLen;

		dwRecLen -= dwOffSet;
		
		SetFilePointer(m_pTargetFile,dwOffSet,NULL,FILE_BEGIN);
		if(!ReadFile(m_pTargetFile, szFileContent, dwRecLen, &dwNumBytesRead, 0))
			return FALSE;
		if(dwNumBytesRead>0)
		{
			szFileContent[dwNumBytesRead] = '\0';
		
			if(bCompressed)
				DeCode(szFileContent,dwNumBytesRead);
			DWORD dwRealSize;
			WriteFile(hTmpFile,szFileContent,dwNumBytesRead,&dwRealSize,NULL);
		//	FillLine(szFileContent,dwNumBytesRead);
		
		}
	}
	if(m_pTargetFile != INVALID_HANDLE_VALUE)
		CloseHandle(m_pTargetFile);
	if(hTmpFile != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hTmpFile);
		
		m_pcLine.RemoveAll(); 
		
		BOOL bSuccess = LoadTxtFile(szTmpFile);
		
		DeleteFile(szTmpFile);
		
		return bSuccess;
	}
	return FALSE;
}

BOOL CExBuffer::LoadFile(UINT nType, LPCTSTR szFileName)
{
	BOOL bLoadSuccess = FALSE;
	
	ASSERT((nType == FORMAT_TEXT)||
		(nType == FORMAT_HTML)||
		(nType == FORMAT_PRC));
    if((nType != FORMAT_TEXT)&&
		(nType != FORMAT_HTML)&&
		(nType != FORMAT_PRC ))
		return bLoadSuccess;
	
   	::SystemParametersInfo(SPI_GETWORKAREA, 0, &m_rectWnd, 0);
    m_dwMaxLineWidth = m_rectWnd.right - 10;
	
	HDC hDC = GetDC(NULL);
	TEXTMETRIC tm;
	memset(&tm,0,sizeof(tm));
	GetTextMetrics(hDC,&tm);
	ReleaseDC(NULL,hDC);
	
//	m_nMaxLinePerPage = (m_rectWnd.bottom - m_rectWnd.top)/(tm.tmHeight + tm.tmExternalLeading) ;
	if (!m_FullScreen)
		m_nMaxLinePerPage = 10 - m_byCurrentFontSize;
	else
		m_nMaxLinePerPage = 12 - m_byCurrentFontSize;

	m_pcLine.RemoveAll(); 
	
	if(nType == FORMAT_TEXT)
		bLoadSuccess = LoadTxtFile(szFileName);
	else if( nType == FORMAT_HTML)
		bLoadSuccess = LoadHtmlFile(szFileName);
	else
		bLoadSuccess = LoadPrcFile(szFileName);
	
	return bLoadSuccess;
}

BOOL CExBuffer::Html2Txt(CHAR *szBuffer)
{
	static int iStart=0;
	int  iPos,iPointer;
	int  iLen=strlen( szBuffer );
	int  nStartPos = 0;
	
	iPos=iPointer=0;
	while( iLen-->0 )
	{
		iPointer++;
		//Convert Specific Char in "<>"
		
		// BlockQuote
		if( ConvertChar( iLen, szBuffer, iPointer, "<BLOCKQUOTE>", 12 ) )
		{
			szBuffer[iPos++]='"';
			iPointer+=11;
			continue;
		}
		if( ConvertChar( iLen, szBuffer, iPointer, "</BLOCKQUOTE>", 13 ) )
		{
			szBuffer[iPos++]='"';
			iPointer+=12;
			continue;
		}
		
		// LineBreak
		if( ConvertChar( iLen, szBuffer, iPointer, "<BR>", 4 ) )
		{
			szBuffer[iPos++]=0x0d;
			iPointer+=3;
			continue;
		}
		// Citation
		if( ConvertChar( iLen, szBuffer, iPointer, "<CITE>", 6 ) )
		{
			szBuffer[iPos++]='"';
			iPointer+=5;
			continue;
		}
		if( ConvertChar( iLen, szBuffer, iPointer, "</CITE>", 7 ) )
		{
			szBuffer[iPos++]='"';
			iPointer+=6;
			continue;
		}
		
		// Tab
		if( ConvertChar( iLen, szBuffer, iPointer, "</TD>", 5 ) )
		{
			szBuffer[iPos++]=9;
			iPointer+=4;
			continue;
		}
		
		// HTML Command Skipper
		if( szBuffer[iPointer-1]=='<' )
		{
			nStartPos = iPointer-1;
			if( szBuffer[iPointer]!='\0' )
			{
				if( szBuffer[iPointer]>='a' && szBuffer[iPointer]<='z' ) 
					iStart=1;
				if( szBuffer[iPointer]>='A' && szBuffer[iPointer]<='Z' ) 
					iStart=1;
				if( szBuffer[iPointer]=='!')
					iStart=1;
				if( szBuffer[iPointer]=='/')
					iStart=1;
			}
		}
		
		if( szBuffer[iPointer-1]=='>')
		{
			if (iStart == 1 )
			{
				iStart=0;
				continue;
			}
		}
		if( iStart==0 )
		{
			if( szBuffer[iPointer-1]=='&' )
			{
				if( ConvertChar( iLen, szBuffer, iPointer, "&lt;"     , 4 ) ){ szBuffer[iPos++]='<'; iPointer+=3; continue; } //4
				if( ConvertChar( iLen, szBuffer, iPointer, "&gt;"     , 4 ) ){ szBuffer[iPos++]='>'; iPointer+=3; continue; } //4
				if( ConvertChar( iLen, szBuffer, iPointer, "&amp;"    , 5 ) ){ szBuffer[iPos++]='&'; iPointer+=4; continue; } //5
				if( ConvertChar( iLen, szBuffer, iPointer, "&quot;"   , 6 ) ){ szBuffer[iPos++]='"'; iPointer+=5; continue; } //6
				if( ConvertChar( iLen, szBuffer, iPointer, "&copy;"   , 6 ) ){ szBuffer[iPos++]='('; szBuffer[iPos++]='c';																				szBuffer[iPos++]=')'; iPointer+=5; continue; } //6
				if( ConvertChar( iLen, szBuffer, iPointer, "&trade;"  , 7 ) ){ szBuffer[iPos++]='t';
				szBuffer[iPos++]='m'; iPointer+=6; continue; } //7
				if( ConvertChar( iLen, szBuffer, iPointer, "&nbsp;"   , 6 ) ){ szBuffer[iPos++]=' '; iPointer+=5; continue; } //6
				
				// &#number
				if( szBuffer[iPointer]=='#' )
				{
					// May be a Number
					int nCount = 0;
					while( iLen-(nCount+1)>0              && // I have char?
						szBuffer[iPointer+1+nCount]>='0' && // Are number ?
						szBuffer[iPointer+1+nCount]<='9' )
					{
						nCount++;
					}
					
					// If I have number .. try to cenvert it
					if( nCount>0 )
					{
						int nDmm  = 0;
						int nChar = 0;
						int nMul  = 1;
						while( nDmm < nCount )
						{
							nChar += (szBuffer[iPointer+nCount-nDmm]-48)*nMul;
							printf( "%d\n", szBuffer[iPointer+nCount-nDmm]-48 );
							printf( "%d\n", nMul );
							nMul  *= 10;
							nDmm++;
						}
						if( nChar > 0 )
						{
							szBuffer[iPos++]=nChar;
							iPointer+=nDmm+1;
							continue;
						}
					}
				}
			}
			
			if( szBuffer[iPointer-1]==0x0d && szBuffer[iPointer]==0x0d )
			{
				iPointer++;
				continue;
			}				
			szBuffer[iPos++]=szBuffer[iPointer-1];
		}
   }
   
   szBuffer[iPos++]='\0';
   return TRUE;
}

BOOL CExBuffer::DeCode(BYTE *szSource, DWORD &nLen)
{
	ATLASSERT(szSource != NULL);
	
	BYTE *szTarget = NULL;
	szTarget = new BYTE[6000];
	if(szTarget == NULL)
		return FALSE;

	int i,j;
	for (j=i=0; j<(INT)nLen; )
	{
		unsigned int nChar;

		nChar = szSource[j++];
		
		if (nChar>0 && nChar<9)
			while(nChar--) szTarget[i++] = szSource[j++];
		else if (nChar<0x80)
			szTarget[i++] = nChar;
		else if (nChar>=0xC0)
			szTarget[i++] = ' ', szTarget[i++] = nChar ^ 0x80;
		else
		{
			int m,n;
			nChar <<= 8;
			nChar += szSource[j++];
			m = (nChar & 0x3FFF) >> 3;
			n = nChar & ((1<<3) - 1);
			n += 3;
			while (n--)
			{
				szTarget[i] = szTarget[i-m];
				i++;
			}
		}
	}
	nLen = i;
	memcpy((void*)szSource,(void*)szTarget,nLen);
	szSource[nLen] = '\0';

	delete[] szTarget;
	szTarget = NULL;
	return TRUE;
}

WORD CExBuffer::SwapWord(WORD wNumber)
{
	return (wNumber>>8) + (wNumber<<8);
}

DWORD CExBuffer::SwapLong(DWORD dwNumber)
{
	return  ((dwNumber>>24) & 0xFF) + (dwNumber<<24) + ((dwNumber>>8) & 0xFF00) + ((dwNumber<<8) & 0xFF0000);
}


BOOL CExBuffer::Html2Txt(LPCTSTR szHtmlFile, LPCTSTR szTxtFile)
{
	int BUFFER_LEN = 32768;
	CHAR szfrw[MAX_PATH];
	memset(szfrw, 0 , sizeof(szfrw));
	wcstombs(szfrw, szHtmlFile, sizeof(szfrw));
	FILE *fr = fopen(szfrw , "r");
	memset(szfrw, 0 , sizeof(szfrw));
	wcstombs(szfrw, szTxtFile, sizeof(szfrw));
	FILE *fw = fopen(szfrw , "w");
	if ((fw == NULL ) || (fr == NULL))
		return FALSE;
	char *RBuffer;
	RBuffer = (char *)malloc( BUFFER_LEN );
	while( fgets( RBuffer, BUFFER_LEN, fr ) != NULL )
	{
		Html2Txt( RBuffer );
		fputs( RBuffer, fw );
	}
	free( RBuffer );
	fclose(fr);
	fclose(fw);
	return TRUE;
}

VOID CExBuffer::SetFontCtrl(BYTE byFontType, BYTE byFontSize)
{
	m_byCurrentFontSize = byFontSize;
	m_byCurrentFontType = byFontType;
}

int CExBuffer::ConvertChar(int iLen, char *Buffer, int iPointer, char *Check, int iCheckLen)
{
	int iRet=0;
	if( iLen+1 >= iCheckLen ){
		iPointer--;
		while( *Check!='\0' ){
			if(  Buffer[iPointer]    ==*Check ||
				(Buffer[iPointer]|32)==*Check ){
				iPointer++;
				Check++;
			} else break;
		}
		iRet = (*Check==0 || *Check==13 || *Check==';' || *Check==' ');
	}	
	return iRet;
	
}

⌨️ 快捷键说明

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