www.pudn.com > GOS.rar > KFile.cpp


// KFile.cpp: implementation of the KFile class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "..\stdafx.h" 
#include "KFile.h" 
 
PDWORD KFile::m_pUsedBitmap=NULL; 
PBYTE KFile::m_pBuffer=NULL; 
int KFile::m_nBufferBlock=0; 
KArray KFile::m_arrFile; 
	////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
KFile::KFile() 
{ 
	m_nFile=-1; 
} 
 
KFile::~KFile() 
{ 
	Close(); 
} 
DWORD KFile::Verify(BOOL bWrite) 
{ 
	DWORD i,j,nCnt; 
	PDWORD pData; 
	pData=(DWORD*)m_pBuffer; 
	nCnt=FILE_BLOCKBYTES/sizeof(DWORD)-1; 
	j=-1; 
	for(i=0;i=0;i--) 
	{ 
		j=m_arrFile[i].strName.GetLength()+1; 
		if(m_arrFile[i].strName.Compare(szFile,-j)==0) 
		{ 
			break; 
		} 
	} 
	return i; 
} 
 
LPCTSTR KFile::FindFirst() 
{ 
	if(m_arrFile.GetSize()<1)return NULL; 
	Close(); 
	m_nFile=0; 
	m_nPostion=0; 
	return m_arrFile[0].strName; 
} 
 
LPCTSTR KFile::FindNext() 
{ 
	if(m_nFile>-1) 
	{ 
		if(m_nFile-1?LPCTSTR(m_arrFile[m_nFile].strName):NULL; 
} 
 
BOOL KFile::Delete() 
{ 
	int i=m_nFile; 
	SetLength(0); 
	Close(); 
	delete[] m_arrFile[i].pBlock; 
	m_arrFile.RemoveAt(i); 
	return TRUE; 
} 
 
BOOL KFile::MoveTo(LPCTSTR szNewName) 
{ 
	int i=GetFileIndex(szNewName); 
	if(i<0) 
	{ 
		m_arrFile[m_nFile].strName=szNewName; 
	} 
	return i>-1; 
} 
 
BOOL KFile::CopyTo(LPCTSTR szNewName,BOOL bOverWrite) 
{ 
	int i=GetFileIndex(szNewName); 
 
	if(i<0) 
	{ 
		FILE f; 
		f.strName=szNewName; 
		f.nSize=0; 
		f.nDate=0; 
		f.pBlock=new USHORT[8]; 
		i=m_arrFile.Add(f); 
	} 
	else if(bOverWrite) 
	{ 
		m_arrFile[i].strName=szNewName; 
	} 
	else i=-1; 
	 
	if(i>-1) 
	{ 
		int nBlock,nOffset,nBytes; 
		int nCount=m_nFile,nPos=0; 
 
		m_nFile=i; 
		SetLength(m_arrFile[nCount].nSize); 
		m_nFile=nCount; 
 
		if(m_nBufferBlock<0) 
		{ 
			FILE_WRITEBLOCK(m_pBuffer,-m_nBufferBlock); 
		} 
		nCount=m_arrFile[m_nFile].nSize; 
		while(nCount>0) 
		{ 
			nBlock=nPos/FILE_BLOCKBYTES; 
			nOffset=nPos%FILE_BLOCKBYTES; 
			nBytes=FILE_BLOCKBYTES-nOffset; 
 
			m_nBufferBlock=m_arrFile[m_nFile].pBlock[nBlock]; 
			FILE_READBLOCK(m_pBuffer,m_nBufferBlock); 
			FILE_WRITEBLOCK(m_pBuffer,m_arrFile[i].pBlock[nBlock]); 
 
			nCount-=nBytes; 
			nPos+=nBytes; 
		} 
	} 
	return i>-1; 
} 
 
BOOL KFile::Open(LPCTSTR szFile,int nFlags) 
{ 
	m_nFile=GetFileIndex(szFile); 
	if(m_nFile==-1  && (nFlags & modeCreate)) 
	{ 
		FILE f; 
		f.strName=szFile; 
		f.nSize=0; 
		f.nDate=0; 
		f.pBlock=new USHORT[8]; 
		m_nFile=m_arrFile.Add(f); 
	} 
	m_nPostion=0; 
	return m_nFile>-1; 
} 
 
void KFile::Close() 
{ 
	m_nFile=-1; 
} 
 
void KFile::ReadWriteBuffer(PBYTE& pBuf, int& nCount) 
{ 
	int nBlock,nOffset,nBytes; 
	nBlock=nCount; 
	nBlock=ABS(nBlock); 
	nOffset=m_nPostion%FILE_BLOCKBYTES; 
	nBytes=FILE_BLOCKBYTES-nOffset; 
	nBytes=min(nBytes,nBlock); 
	nBlock=m_nPostion/FILE_BLOCKBYTES; 
	nBlock=m_arrFile[m_nFile].pBlock[nBlock]; 
	if(ABS(m_nBufferBlock)!=nBlock) 
	{ 
		if(m_nBufferBlock<0) 
		{ 
			FILE_WRITEBLOCK(m_pBuffer,-m_nBufferBlock); 
		} 
		m_nBufferBlock=nBlock; 
		FILE_READBLOCK(m_pBuffer,m_nBufferBlock); 
	} 
	if(nCount>0) //读 
	{ 
		CopyMemory(pBuf,m_pBuffer+nOffset,nBytes); 
		nCount-=nBytes; 
	} 
	else if(nCount<0) //写 
	{ 
		CopyMemory(m_pBuffer+nOffset,pBuf,nBytes); 
		m_nBufferBlock=-nBlock; 
		nCount+=nBytes; 
	} 
	pBuf+=nBytes; 
	m_nPostion+=nBytes; 
} 
 
int KFile::Write(LPCVOID pBuf, int nCount) 
{ 
	int nBytes; 
	PBYTE pData=PBYTE(pBuf); 
	nBytes=m_nPostion+nCount; 
	if(nBytes>m_arrFile[m_nFile].nSize)SetLength(nBytes); 
	nBytes=nCount; 
	nCount=-nCount; 
	while(nCount<0) 
	{ 
		ReadWriteBuffer(pData,nCount); 
	} 
	return nBytes; 
} 
 
int KFile::Read(PVOID pBuf, int nCount) 
{ 
	int nBytes; 
	PBYTE pData=PBYTE(pBuf); 
	nBytes=m_arrFile[m_nFile].nSize-m_nPostion; 
	nBytes=nCount=min(nBytes,nCount); 
	while(nCount>0) 
	{ 
		ReadWriteBuffer(pData,nCount); 
	} 
	return nBytes; 
} 
 
void KFile::WriteString(LPCTSTR lpsz) 
{ 
	LPCTSTR s=lpsz; 
	while(*s)  
	{ 
		switch(*s) 
		{ 
		case '\r': 
			if(*(s+1)=='\n')break; 
		case '\n': 
			Write(lpsz,s-lpsz); 
			Write("\r\n",2); 
			lpsz=s+1; 
			break; 
		} 
		s++; 
	} 
	Write(lpsz,s-lpsz); 
	Write("\r\n",2); 
} 
 
int KFile::ReadString(LPTSTR lpsz, int nMax) 
{ 
	int nCount; 
	PBYTE pStart,pData=PBYTE(lpsz); 
 
	nMax--; 
	nCount=m_arrFile[m_nFile].nSize-m_nPostion; 
	nCount=min(nMax,nCount); 
	if(nCount==0)return 0; 
	do 
	{ 
		pStart=pData; 
		ReadWriteBuffer(pData,nCount); 
		nMax=pData-pStart; 
		while(pStart0); 
	if(nMax) 
	{ 
		nCount=1;ReadWriteBuffer(pData,nCount); 
		if(!nCount) 
		{ 
			pData--; 
			if(*pData!='\r')m_nPostion-=1; 
		} 
		 
	} 
	if(*pData=='\r') 
	{ 
		nCount=1;ReadWriteBuffer(pData,nCount); 
		if(!nCount) 
		{ 
			pData--; 
			if(*pData!='\n')m_nPostion-=1; 
		} 
	} 
	*pData=0; 
	return LPTSTR(pData)-lpsz; 
} 
 
int KFile::ReadString(KString &String) 
{ 
	int nBuf,nLen; 
	LPTSTR pData; 
 
	nBuf=String.GetLength(); 
	nBuf=max(64,nBuf); 
	pData=String.GetBuffer(nBuf); 
	nLen=ReadString(pData,nBuf+1); 
	if(nLen==nBuf) 
	{ 
		for(;;) 
		{ 
			String.ReleaseBuffer(nBuf); 
			pData=String.GetBuffer(nBuf<<1)+nBuf; 
			nLen=ReadString(pData,nBuf+1); 
			if(nLen!=nBuf)break; 
			nBuf<<=1; 
		} 
		nLen+=nBuf; 
	} 
	String.ReleaseBuffer(nLen); 
	return nLen; 
} 
 
int KFile::Seek(int nOffset, int nFrom) 
{ 
	switch(nFrom) 
	{ 
	case end: 
		nOffset=m_arrFile[m_nFile].nSize-nOffset; 
		break; 
	case current: 
		nOffset+=m_nPostion; 
		break; 
	} 
	if(nOffset<=m_arrFile[m_nFile].nSize)m_nPostion=nOffset; 
	else nOffset=-1; 
	return nOffset; 
} 
 
int KFile::SetLength(int nNewLength) 
{ 
	int i,j,nCnt,nNewCnt,nBits; 
 
	//调整索引数组的大小 
	nCnt=m_arrFile[m_nFile].nSize/FILE_BLOCKBYTES; 
	if(m_arrFile[m_nFile].nSize%FILE_BLOCKBYTES)nCnt++; 
	nNewCnt=nNewLength/FILE_BLOCKBYTES; 
	if(nNewLength%FILE_BLOCKBYTES)nNewCnt++; 
	 
	if((nCnt&~7)+8 < (nNewCnt&~7)+8) 
	{ 
		PUSHORT pBlock=m_arrFile[m_nFile].pBlock; 
		m_arrFile[m_nFile].pBlock=new USHORT[(nNewCnt&~7)+8]; 
		CopyMemory(m_arrFile[m_nFile].pBlock,pBlock,nCnt*sizeof(USHORT)); 
		delete[] pBlock; 
	} 
	nBits=sizeof(DWORD)*8; 
	if(nNewCnt>nCnt) 
	{ 
		//分配块 
		j=1; 
		for(i=nCnt;i