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

📄 filemap.c

📁 这一款新闻类业务的源码
💻 C
字号:
/*===========================================================================
包明辉 CFileMap , 读文件缓冲 , 分为3块缓冲区。
主要方法:boolean	CFileMap_GetData(CFileMap* pMap , uint32 nIndex , uint32 nSize , boolean* bEnd)
FILE: FileMap.c
===========================================================================*/
#include "FileMap.h"
//////////////////////////////////////////////////////////////////////////
//构造
CFileMap* CFileMap_New(IFileMgr* pFileMgr , const char* pszFileName , PFNRBBNOTIFY pReCall , void* pvUser , AEEApplet* pThis)
{
	CFileMap*	pRet = NULL;
	FileInfo	tagFinfo;
	//////////////////////////////////////////////////////////////////////////
	//验证参数
	if(NULL == pFileMgr || NULL == pszFileName || NULL == pReCall || NULL == pvUser || NULL == pThis)
		goto ferr;
	//////////////////////////////////////////////////////////////////////////
	//分配对象结构
	pRet = MALLOC(sizeof(CFileMap));
	if(NULL == pRet)
		goto ferr;
	MEMSET(pRet , 0 , sizeof(CFileMap));
	//////////////////////////////////////////////////////////////////////////
	//建立要读的文件
	pRet->m_pFile = IFILEMGR_OpenFile(pFileMgr , pszFileName , _OFM_READ);
	if(NULL == pRet->m_pFile)
		goto ferr;
	MEMSET(&tagFinfo , 0 , sizeof(FileInfo));
	if(SUCCESS != IFILE_GetInfo(pRet->m_pFile , &tagFinfo))
		goto ferr;
	//////////////////////////////////////////////////////////////////////////
	//预读文件
	pRet->m_pThis = pThis;
	pRet->m_tagNotifyPar.m_pvUser = pvUser;
	pRet->m_pReCall = pReCall;
	pRet->m_nTotalSize = tagFinfo.dwSize;
	if(pRet->m_nTotalSize <= (3 * BUFFERSIZE))					//判断是否需要分3块缓冲
	{
		pRet->m_bIsBu = FALSE;
		pRet->m_nTotalPage = 0;
		pRet->m_nLstPgSize = 0;
		pRet->m_tagNotifyPar.m_nMaxDataSize = pRet->m_nTotalSize - 1;
		pRet->m_tagNotifyPar.m_pDataBeg = (void*)pRet->m_Buffer[0];
		pRet->m_tagNotifyPar.m_pDataEnd = (void*)pRet->m_Buffer[0];
		MEMSET(pRet->m_Buffer[0] , 0 , BUFFERSIZE + BUFFERSIZE + BUFFERSIZE);
		FileRead(pRet , 0 , pRet->m_nTotalSize);
	}
	else
	{	pRet->m_bIsBu = TRUE;
		pRet->m_nTotalPage = tagFinfo.dwSize / BUFFERSIZE;		//一共叶数字
		pRet->m_nLstPgSize = tagFinfo.dwSize % BUFFERSIZE;		//最后一叶大小
		pRet->m_tagNotifyPar.m_nMaxDataSize = BUFFERSIZE + BUFFERSIZE - 1;
		pRet->m_tagNotifyPar.m_pDataBeg = pRet->m_Buffer[1];
		pRet->m_tagNotifyPar.m_pDataEnd = pRet->m_Buffer[1]; 
		FileRead(pRet , 1 , 2 * BUFFERSIZE);
	}
	//至此文件信息获得完毕,计算需要的数据
	//////////////////////////////////////////////////////////////////////////
	//返回值错误
	return pRet;
ferr:
	FILEMAP_FREE(pRet);
	return NULL;
}
//////////////////////////////////////////////////////////////////////////
//释放资源
void CFileMap_Release(CFileMap** ppFileMap)
{
	if(ppFileMap && *ppFileMap)
	{
		if((*ppFileMap)->m_pFile)
			IFILE_Release((*ppFileMap)->m_pFile);
		(*ppFileMap)->m_pFile = NULL;
		FREEIF(*ppFileMap);
		*ppFileMap = NULL;
	}
}
//////////////////////////////////////////////////////////////////////////
//获得数据
boolean	CFileMap_GetData(CFileMap* pMap , uint32 nIndex , uint32 nSize , boolean* bEnd)
{
	boolean	bRet = TRUE;
	uint32	nNowBegin = 0;			//读文件的开始部分
	uint32	nNowEnd = 0;			//读文件结素部分
	//////////////////////////////////////////////////////////////////////////
	//简单检查必要参数
	if(NULL == pMap || NULL == bEnd)
		return FALSE;
	*bEnd = FALSE;
	//////////////////////////////////////////////////////////////////////////
	//确定读文件的开始位置
	nNowBegin = (NOW_READ == nIndex) ? pMap->m_nIndex : nIndex;
	if(nNowBegin >= pMap->m_nTotalSize)	return FALSE;
	//////////////////////////////////////////////////////////////////////////
	//进行缓冲计算 
	if(pMap->m_bIsBu)									
	{
	//////////////////////////////////////////////////////////////////////////
	//分块缓冲 
		uint32  nReadSize = 0;							//读文件的大小
		int32	nNowPage = 0;							//当前页
		int32	nGotPage = 0;							//要跳转的页
		int32	nThiPage = 0;							//跳转开始页
		uint32	nPageIndex = 0;							//当前叶内偏移
		uint32	nPageEndIndex = 0;						//移动结束叶内偏移
		uint32	nMaxLengh = 0;							//跳转的最大长度如果超过这个长度说明缓冲区不够大
		nPageIndex = nNowBegin % BUFFERSIZE;			//求得当前开始读文件地方的叶内偏移
		nMaxLengh = ((BUFFERSIZE + BUFFERSIZE) - nPageIndex - 1);//求的能读文件的最大长度
		if(nSize > nMaxLengh) return FALSE;				//缓冲区不够用直接返回失败
		nNowEnd = (NOW_READ == nSize) ? nMaxLengh : MIN((nNowBegin + nSize) , pMap->m_nTotalSize);
		nPageEndIndex = nNowEnd % BUFFERSIZE; 
		nNowPage = (int32)(pMap->m_nIndex / BUFFERSIZE);//求得当前页
		nGotPage = (int32)(nNowEnd / BUFFERSIZE);		//求得要跳转的页
		nThiPage = (int32)(nNowBegin / BUFFERSIZE);		//求得跳转开始页
		pMap->m_nIndex = nNowEnd;
		pMap->m_tagNotifyPar.m_nMaxDataSize = (nGotPage + 1) < pMap->m_nTotalPage ? ((2 * BUFFERSIZE) - nPageEndIndex - 1) : (pMap->m_nTotalSize - nNowEnd);
		switch(nGotPage - nThiPage)
		{
		case 0:
			pMap->m_tagNotifyPar.m_pDataBeg = pMap->m_Buffer[ANOW_PAGE] + nPageIndex;
			pMap->m_tagNotifyPar.m_pDataEnd = pMap->m_Buffer[ANOW_PAGE] + nPageEndIndex;
			break;
		case 1:
			pMap->m_tagNotifyPar.m_pDataBeg = pMap->m_Buffer[PERV_PAGE] + nPageIndex;
			pMap->m_tagNotifyPar.m_pDataEnd = pMap->m_Buffer[ANOW_PAGE] + nPageEndIndex;
			break;
		default:
			pMap->m_tagNotifyPar.m_nMaxDataSize = 0;
			pMap->m_tagNotifyPar.m_pDataEnd = NULL;
			pMap->m_tagNotifyPar.m_pDataBeg = NULL;		//到这里出现错误
			return FALSE;
		}
	//////////////////////////////////////////////////////////////////////////		
		switch(nGotPage - nNowPage) 
		{
		case 0:
			bRet = ReCall(pMap , FILEMAP_REDA);
			break;
		case 1:
			MEMCPY(pMap->m_Buffer[PERV_PAGE] , pMap->m_Buffer[ANOW_PAGE] , BUFFERSIZE);
			MEMCPY(pMap->m_Buffer[ANOW_PAGE] , pMap->m_Buffer[NEXT_PAGE] , BUFFERSIZE);
			switch(nGotPage - pMap->m_nTotalPage) 
			{
			case 0:
				bRet =  ReCall(pMap , FILEMAP_REDA);
				break;
			default:
				if(EFAILED != MoveFilePoint(pMap , nGotPage + 1))
				{
					nReadSize = (nGotPage + 1) >= pMap->m_nTotalPage ? pMap->m_nLstPgSize : BUFFERSIZE; 
					MEMSET(pMap->m_Buffer[NEXT_PAGE] , 0 , BUFFERSIZE);
					FileRead(pMap , 2 , nReadSize);
				}
				else
					bRet = FALSE;
			}
			break;
		case 2:
			MEMCPY(pMap->m_Buffer[PERV_PAGE] , pMap->m_Buffer[NEXT_PAGE] , BUFFERSIZE);
			if(EFAILED != MoveFilePoint(pMap , nGotPage)) 
			{
				nReadSize = (nGotPage + 1) >= pMap->m_nTotalPage ? (BUFFERSIZE + pMap->m_nLstPgSize) : (BUFFERSIZE + BUFFERSIZE);
				FileRead(pMap , 1 , nReadSize);
			}
			else
				bRet = FALSE;
			break;
		case -1:
			MEMCPY(pMap->m_Buffer[NEXT_PAGE] , pMap->m_Buffer[ANOW_PAGE] , BUFFERSIZE);
			MEMCPY(pMap->m_Buffer[ANOW_PAGE] , pMap->m_Buffer[PERV_PAGE] , BUFFERSIZE);
			switch(nGotPage) 
			{
			case 0:
				bRet = ReCall(pMap , FILEMAP_REDA);
				break;
			default:
				if(EFAILED != MoveFilePoint(pMap , nGotPage - 1)) 
					FileRead(pMap , 0 , BUFFERSIZE);
				else
					bRet = FALSE;
			}	
			break;
		case -2:
			{
				MEMCPY(pMap->m_Buffer[NEXT_PAGE] , pMap->m_Buffer[PERV_PAGE] , BUFFERSIZE);
				if(EFAILED != MoveFilePoint(pMap , nGotPage - 1)) 
					FileRead(pMap , 0 , BUFFERSIZE + BUFFERSIZE);
				else
					bRet = FALSE;
			}
			break;
		default:
			MEMSET(pMap->m_Buffer[0] , 0 , BUFFERSIZE + BUFFERSIZE + BUFFERSIZE);
			if(0 < nGotPage)
			{
				if(EFAILED != MoveFilePoint(pMap , nGotPage - 1))
				{
					switch(pMap->m_nTotalPage - nGotPage) 
					{
					case 0:
						nReadSize = BUFFERSIZE + pMap->m_nLstPgSize;
						break;
					case 1:
						nReadSize = BUFFERSIZE + BUFFERSIZE + pMap->m_nLstPgSize;
						break;
					default:
						nReadSize = BUFFERSIZE + BUFFERSIZE + BUFFERSIZE;
						break;
					}
					FileRead(pMap , 0 , nReadSize);
				}
				else
					bRet = FALSE;
			}
			else
			{
				if(EFAILED != MoveFilePoint(pMap , 0))
					FileRead(pMap , 1 , BUFFERSIZE + BUFFERSIZE);
				else
					bRet = FALSE;
			}
		}//End 		switch(nGotPage - nNowPage) 
	}
	else
	{
		nNowEnd = (NOW_READ == nSize) ? pMap->m_nTotalSize : MIN((nNowBegin + nSize) , pMap->m_nTotalSize);
		pMap->m_nIndex = nNowEnd;
		pMap->m_tagNotifyPar.m_nMaxDataSize = pMap->m_nTotalSize - nNowEnd;
		pMap->m_tagNotifyPar.m_pDataBeg = pMap->m_Buffer[0] + nNowBegin;
		pMap->m_tagNotifyPar.m_pDataEnd = pMap->m_Buffer[0] + nNowEnd;
		if(FALSE == ReCall(pMap , FILEMAP_REDA))
			return FALSE;
	}	
	if(pMap->m_nIndex == 309500)
		pMap->m_nIndex = pMap->m_nIndex;
	if((pMap->m_nIndex + 1) >= pMap->m_nTotalSize)
		*bEnd = TRUE;
	return bRet;
}
uint32 MoveFilePoint(CFileMap* pMap , int32 nGotoPage)
{
	int32 nFileIndex;	//当前位置
	nFileIndex = IFILE_Seek(pMap->m_pFile , _SEEK_CURRENT , 0);
	return IFILE_Seek(pMap->m_pFile , _SEEK_CURRENT , (nGotoPage * BUFFERSIZE) - nFileIndex);//1位偏移
}
//////////////////////////////////////////////////////////////////////////
//获得文件大小
uint32 CFileMap_GetFileSize(CFileMap* pMap)
{
	if(NULL == pMap)
		return 0;
	return  pMap->m_nTotalSize;
}
//////////////////////////////////////////////////////////////////////////
//过得当前读文件的位置
uint32 CFileMap_GetFileIndex(CFileMap* pMap)
{
	if(NULL == pMap)
		return 0;
	return pMap->m_nIndex;
}
//////////////////////////////////////////////////////////////////////////
//读文件回调
void FileReadStep(CFileMap*	pMap)	//必须保证回调用
{
	int32 nRead = 0;
	nRead = IFILE_Read(pMap->m_pFile , pMap->m_Buffer[pMap->m_nBlockIdx] + pMap->m_nReadIdx , MIN(READSIZE , pMap->m_nReadSize - pMap->m_nReadIdx));
	switch(nRead) 
	{
	case 0:							//出现了错误
		if(pMap->m_nReadIdx < pMap->m_nReadSize)
		{
			if(FALSE == ReCall(pMap , FILEMAP_IERR))
				ISHELL_CloseApplet(pMap->m_pThis->m_pIShell , TRUE);
		}
		else
		{
			if(FALSE == ReCall(pMap , FILEMAP_REDA))
				ISHELL_CloseApplet(pMap->m_pThis->m_pIShell , TRUE);
		}
		return;
	default:
		pMap->m_nReadIdx += nRead;
		if(pMap->m_nReadIdx >= pMap->m_nReadSize)
		{	
			if(FALSE == ReCall(pMap , FILEMAP_REDA))
				ISHELL_CloseApplet(pMap->m_pThis->m_pIShell , TRUE);
			return;
		}	
	}
	IFILE_Readable(pMap->m_pFile, (PFNNOTIFY)FileReadStep, (void*)pMap);
}
boolean	FileRead(CFileMap* pMap ,					
				 byte	   nBufferBlock ,			
				 uint32	   nBufferCount)
{
	pMap->m_nBlockIdx = nBufferBlock;//要写的内存块
	pMap->m_nReadSize = nBufferCount;//要读的文件大小字节
	pMap->m_nReadIdx = 0;			 //读文件的位置
	FileReadStep(pMap);
	return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//包装的回调函数
boolean	ReCall(CFileMap* pMap , FileMapNotifyCode code)
{
	pMap->m_tagNotifyPar.m_code = code;
	if(SUCCESS == ISHELL_SetTimer(pMap->m_pThis->m_pIShell , 0 , (PFNNOTIFY)pMap->m_pReCall , (void*)&pMap->m_tagNotifyPar))
		return TRUE;
	else
		return FALSE;
}

⌨️ 快捷键说明

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