www.pudn.com > NetPaw.rar > NetPawDoc.cpp


// NetPawDoc.cpp :  CNetPawDoc 类的实现 
// 
 
#include "stdafx.h" 
#include "NetPaw.h" 
#include "mainfrm.h" 
#include "fileview.h" 
#include "downloadfile.h" 
#include "crc32.h" 
#include ".\netpawdoc.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 
 
 
// CNetPawDoc 
IMPLEMENT_DYNCREATE(CNetPawDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CNetPawDoc, CDocument) 
END_MESSAGE_MAP() 
 
 
// CNetPawDoc 构造/析构 
CNetPawDoc::CNetPawDoc() 
	: m_pCrc32(NULL) 
	, m_sProfName(_T("")) 
	, m_nMaxSpeed(0) 
{ 
	// TODO: 在此添加一次性构造代码 
} 
 
CNetPawDoc::~CNetPawDoc() 
{ 
	// save the current profile 
	SaveProfile(); 
 
	// clear download files 
	if( m_pCrc32 ) 
	{ 
		delete m_pCrc32; 
	} 
 
	// clear downloading item 
	CDownloadFile *pDlFile; 
	map::iterator itor; 
	for(itor = m_mapDownldFile.begin(); itor != m_mapDownldFile.end(); itor++) 
	{ 
		pDlFile = itor->second; 
		if( pDlFile ) 
		{ 
			delete pDlFile; 
		} 
	} 
	m_mapDownldFile.clear(); 
 
	// clear downloaded 
	DONEITEM_S *pstDoneIt; 
	list::iterator itor2; 
	for(itor2 = m_lstDownloaded.begin(); itor2 != m_lstDownloaded.end(); itor2++) 
	{ 
		pstDoneIt = *itor2; 
		if( pstDoneIt ) 
		{ 
			delete pstDoneIt; 
		} 
	} 
	m_lstDownloaded.clear(); 
} 
 
BOOL CNetPawDoc::OnNewDocument() 
{ 
	if (!CDocument::OnNewDocument()) 
		return FALSE; 
 
	// TODO: 在此添加重新初始化代码 
	// (SDI 文档将重用该文档) 
	if( !m_pCrc32 ) 
	{ 
		m_pCrc32 = new CCrc32(); 
		m_pCrc32->Init(); 
	} 
 
	// get profile pathname 
	CString sPathName; 
	GetModuleFileName(NULL, sPathName.GetBuffer(MAX_PATH), MAX_PATH); 
	sPathName.ReleaseBuffer(); 
 
	int nIndex = sPathName.ReverseFind('\\'); 
	if( nIndex != -1 ) 
	{ 
		sPathName = sPathName.Left(nIndex); 
	} 
	m_sProfName = sPathName + PROFILE_NPJ; 
 
	// load the profile 
	CFileFind finder; 
	BOOL bFound = finder.FindFile( m_sProfName ); 
	if( bFound ) 
	{ 
		LoadProfile(); 
	} 
 
	return TRUE; 
} 
 
// CNetPawDoc 序列化 
void CNetPawDoc::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		// TODO: 在此添加存储代码 
	} 
	else 
	{ 
		// TODO: 在此添加加载代码 
	} 
} 
 
// CNetPawDoc 诊断 
#ifdef _DEBUG 
void CNetPawDoc::AssertValid() const 
{ 
	CDocument::AssertValid(); 
} 
 
void CNetPawDoc::Dump(CDumpContext& dc) const 
{ 
	CDocument::Dump(dc); 
} 
#endif //_DEBUG 
 
 
// CNetPawDoc 命令 
 
LONGLONG CNetPawDoc::GetSelFileLen(void) 
{ 
	LONGLONG nLength = 0; 
 
	CDownloadFile *pDlFile = GetSelDownFile(); 
	if( pDlFile ) 
	{ 
		nLength = pDlFile->GetFileLength(); 
	} 
 
	return nLength; 
} 
 
CDownloadFile* CNetPawDoc::GetSelDownFile(void) 
{ 
	map::iterator itor; 
	CDownloadFile* pDlFile = NULL; 
	CString sFileName; 
 
	// get frame wnd 
	CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); 
	ASSERT( pFrame ); 
 
	// get file view 
	CFileView *pView = pFrame->GetRightPane(); 
	if( pView ) 
	{ 
		pView->GetSelectedFileName(sFileName); 
 
		// find pointer in the map 
		if( (itor = m_mapDownldFile.find(sFileName)) != m_mapDownldFile.end() ) 
		{ 
			pDlFile = itor->second; 
		} 
	} 
 
	return pDlFile; 
} 
 
void CNetPawDoc::DeleteDlFile(CDownloadFile* pDlFile) 
{ 
	if( !pDlFile ) 
	{ 
		return; 
	} 
 
	// get file name from object name 
	CString sFileName = pDlFile->GetFileName(); 
 
	// delete the object from the map 
	m_mapDownldFile.erase(sFileName); 
	delete pDlFile; 
 
	// notify views change 
	UpdateAllViews(NULL, UPDATE_ALL); // update all 
} 
 
DONEITEM_S* CNetPawDoc::GetSelDownloaded(void) 
{ 
	DONEITEM_S *pDoneIt = NULL, *pTmpIt; 
 
	// get frame wnd 
	CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); 
	ASSERT( pFrame ); 
 
	// get file view 
	CFileView *pView = pFrame->GetRightPane(); 
	if( pView ) 
	{ 
		CString sFileName; 
		pView->GetSelectedFileName(sFileName); 
 
		list::iterator itor; 
		for( itor = m_lstDownloaded.begin(); itor != m_lstDownloaded.end(); itor++ ) 
		{ 
			pTmpIt = *itor; 
			if( pTmpIt && ( sFileName.CompareNoCase( pTmpIt->szFileName ) == 0 ) ) 
			{ 
				pDoneIt = pTmpIt; 
			} 
		} 
	} 
 
	return pDoneIt; 
} 
 
void CNetPawDoc::DeleteDownlded(DONEITEM_S* pDoneIt) 
{ 
	m_lstDownloaded.remove(pDoneIt); 
	delete pDoneIt; 
 
	// notify views change 
	UpdateAllViews(NULL, UPDATE_ALL); // update all 
} 
 
CDownloadFile* CNetPawDoc::NewDownldFile(DLFILEITEM_S *pstDlFileIt) 
{ 
	// allocate download file objects 
	CDownloadFile *pDlFile = new CDownloadFile( pstDlFileIt ); 
	if( !pDlFile ) 
	{ 
		AfxMessageBox("创建对象错误\n"); 
		return NULL; 
	} 
 
	// start download 
	if( !pDlFile->ParseFileName() ) 
	{ 
		delete pDlFile; 
		AfxMessageBox("无法解析URL\n"); 
		return NULL; 
	} 
 
	// successfully connected, add the file into map 
	CString sFileName = pDlFile->GetFileName(); 
	m_mapDownldFile.insert( pair (sFileName, pDlFile) ); 
 
	return pDlFile; 
} 
 
void CNetPawDoc::SaveProfile(void) 
{ 
	CFile *pFile = new CFile(); 
 
	try 
	{ 
		if( !pFile->Open( m_sProfName, CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive ) ) 
		{ 
			throw 0; 
		} 
 
		// save all class items 
		SaveDownldFile(pFile); 
		SaveDownldedFile(pFile); 
		SaveFavorites(pFile); 
	} 
	catch(CFileException *pEx) 
	{ 
		pEx->ReportError(); 
		pEx->Delete(); 
	} 
	catch(...) 
	{ 
	} 
 
	// should close before write CRC 
	delete pFile; 
 
	// write the CRC32 in header 
	WriteCrc32(m_sProfName); 
} 
 
void CNetPawDoc::SaveDownldFile(CFile *pFile) 
{ 
	// write an empty header 
	FILEHDR_S stFileHdr; 
	ZeroMemory(&stFileHdr, sizeof(FILEHDR_S)); 
	pFile->Write( &stFileHdr, sizeof(FILEHDR_S) ); 
 
	// write download file header 
	FOLDERCLASS_S stClass; 
	stClass.dwSeperator = 0x0A0D0A0D; 
	stClass.wClass = FOLDER_DOWNLDING; 
	stClass.wItems = (WORD)m_mapDownldFile.size(); 
	pFile->Write(&stClass, sizeof(FOLDERCLASS_S)); 
 
	// write download file items 
	map::iterator itor; 
	CDownloadFile *pDlFile; 
	for( itor = m_mapDownldFile.begin(); itor != m_mapDownldFile.end(); itor++ ) 
	{ 
		pDlFile = itor->second; 
		if( pDlFile ) 
		{ 
			pDlFile->SaveDlFileData(pFile); 
		} 
	} 
} 
 
void CNetPawDoc::SaveDownldedFile(CFile *pFile) 
{ 
	// write download file header 
	FOLDERCLASS_S stClass; 
	stClass.dwSeperator = 0x0A0D0A0D; 
	stClass.wClass = FOLDER_DOWNLDED; 
	stClass.wItems = (WORD)m_lstDownloaded.size(); 
	pFile->Write(&stClass, sizeof(FOLDERCLASS_S)); 
 
	// write download file items 
	list::iterator itor; 
	DONEITEM_S *pDoneItem; 
	for( itor = m_lstDownloaded.begin(); itor != m_lstDownloaded.end(); itor++ ) 
	{ 
		pDoneItem = *itor; 
		if( pDoneItem ) 
		{ 
			pFile->Write(pDoneItem, sizeof(DONEITEM_S)); 
		} 
	} 
} 
 
void CNetPawDoc::SaveFavorites(CFile *pFile) 
{ 
} 
 
void CNetPawDoc::WriteCrc32(LPCTSTR szFileName) 
{ 
	// calculate the CRC32 value, header not included 
	DWORD dwCrc32; 
	m_pCrc32->FileCrc32Assembly(szFileName, dwCrc32, sizeof(FILEHDR_S)); 
 
	CFile tmpFile; 
	if( !tmpFile.Open(szFileName, CFile::modeReadWrite | CFile::modeNoTruncate) ) 
	{ 
		AfxMessageBox("Open download profile failed."); 
		return; 
	} 
 
	// fill the file header and write 
	FILEHDR_S stFileHdr; 
	stFileHdr.wMagicWord = 0x504E; 
	stFileHdr.wReserved = 0; 
	stFileHdr.dwCrc = dwCrc32; 
 
	tmpFile.Write( &stFileHdr, sizeof(FILEHDR_S) ); 
} 
 
BOOL CNetPawDoc::CheckCRC32(LPCTSTR szFileName) 
{ 
	CFile tmpFile; 
	if( !tmpFile.Open(szFileName, CFile::modeRead | CFile::shareDenyWrite) ) 
	{ 
		return FALSE; 
	} 
 
	// get the crc32 in the file header 
	FILEHDR_S stFileHdr; 
	tmpFile.Read( &stFileHdr, sizeof(FILEHDR_S) ); 
	if( stFileHdr.wMagicWord != 0x504E ) 
	{ 
		return FALSE; 
	} 
	tmpFile.Close(); 
 
	// check the CRC32 value, header not included 
	DWORD dwCrc32; 
	m_pCrc32->FileCrc32Assembly(szFileName, dwCrc32, sizeof(FILEHDR_S)); 
	if( dwCrc32 != stFileHdr.dwCrc ) 
	{ 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
void CNetPawDoc::LoadProfile(void) 
{ 
	BOOL bValidPfile = TRUE; 
 
	// check crc of the existed file 
	if( !CheckCRC32(m_sProfName) ) 
	{ 
		DeleteFile(m_sProfName); 
 
		AfxMessageBox("Corrupted download profile is deleted\n"); 
		return; 
	} 
 
	// open the profile 
	CFile *pFile = new CFile(); 
	try 
	{ 
		if( !pFile->Open( m_sProfName, CFile::modeRead | CFile::shareDenyWrite ) ) 
		{ 
			throw 0; 
		} 
 
		// load all class items 
		LoadDownldFile(pFile); 
		LoadDownldedFile(pFile); 
		LoadFavorites(pFile); 
	} 
	catch(CFileException *pEx) 
	{ 
		pEx->ReportError(); 
		pEx->Delete(); 
	} 
	catch(...) 
	{ 
	} 
 
	delete pFile; 
} 
 
void CNetPawDoc::LoadDownldFile(CFile *pFile) 
{ 
	// skip the file header 
	pFile->Seek( sizeof(FILEHDR_S), CFile::begin ); 
 
	// read download items head 
	FOLDERCLASS_S stClass; 
	if( pFile->Read(&stClass, sizeof(FOLDERCLASS_S)) <= 0 ) 
	{ 
		return; 
	} 
	ASSERT(stClass.wClass == FOLDER_DOWNLDING); 
 
	// read items 
	DLFILEITEM_S stDlFile; 
	SEGMENT_S stBlock; 
	CDownloadFile* pDlFile; 
	for( int i = 0; i < stClass.wItems; i++ ) 
	{ 
		// get download file information 
		if( pFile->Read(&stDlFile, sizeof(DLFILEITEM_S)) <= 0 ) 
		{ 
			continue; 
		} 
 
		// do some valid check for the data 
		if( stDlFile.wBlocksToDo == 0 || stDlFile.wBlocksToDo > MAX_CONNECTIONS ) 
		{ 
			continue; 
		} 
 
		// create download file object 
		pDlFile = NewDownldFile( &stDlFile ); 
 
		// get download range of each socket 
		for( int j = 0; j < stDlFile.wBlocksToDo; j++ ) 
		{ 
			if( pFile->Read( &stBlock, sizeof(SEGMENT_S) ) <= 0 ) 
			{ 
				continue; 
			} 
 
			// do some valid check for the data 
			if( stBlock.nDataFrom > stBlock.nDataTo || stBlock.nDataTo >= stDlFile.nFileLength ) 
			{ 
				continue; 
			} 
 
			// create socket 
			pDlFile->NewSocket( &stBlock ); 
		} 
	} 
} 
 
void CNetPawDoc::LoadDownldedFile(CFile *pFile) 
{ 
	// read download items head 
	FOLDERCLASS_S stClass; 
	if( pFile->Read(&stClass, sizeof(FOLDERCLASS_S)) <= 0 ) 
	{ 
		return; 
	} 
	ASSERT(stClass.wClass == FOLDER_DOWNLDED); 
 
	DONEITEM_S *pstDoneIt; 
	for( int i = 0; i < stClass.wItems; i++ ) 
	{ 
		// get download file information 
		pstDoneIt = new DONEITEM_S; 
		if( pFile->Read(pstDoneIt, sizeof(DONEITEM_S)) <= 0 ) 
		{ 
			delete pstDoneIt; 
			continue; 
		} 
 
		m_lstDownloaded.push_back(pstDoneIt); 
	} 
} 
 
void CNetPawDoc::LoadFavorites(CFile *pFile) 
{ 
} 
 
void CNetPawDoc::NotifyFileDone(CDownloadFile* pDlFile) 
{ 
	// add to the downloaded class 
	PERFITEM_S stPerfIT; 
	pDlFile->GetPerfData(&stPerfIT); 
 
	// fill the done item structure 
	DONEITEM_S *pDoneItem = new DONEITEM_S; 
	pDoneItem->nFileLen = stPerfIT.nFileLength; 
	pDoneItem->fMeanSpeed = stPerfIT.fMeanSpeed; 
	pDoneItem->dUsedTime = stPerfIT.dUsedTime; 
	StrCopy( pDoneItem->szFileName, stPerfIT.szFileName, MAX_PATH/2 ); 
	StrCopy( pDoneItem->szWebInfo, pDlFile->m_sWebInfo, MAX_PATH/2 ); 
 
	m_lstDownloaded.push_back(pDoneItem); 
 
	// rename the file 
	CString sFileName, sOldName; 
	CNetPawApp *pApp = (CNetPawApp *)AfxGetApp(); 
	if( pApp ) 
	{ 
		sFileName = pApp->m_sSavePath + '\\' + pDlFile->GetFileName(); 
		sOldName = sFileName + _T(".npf"); 
	} 
 
	MoveFile(sOldName, sFileName); 
 
	// delete the pDlFile from the downloading class 
	DeleteDlFile(pDlFile); 
}