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

📄 partfile.cpp

📁 非常出名开源客户端下载的程序emule
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "StdAfx.h"
#include "partfile.h"
#include "emule.h"
#include "updownclient.h"
#include <math.h>
#include "ED2KLink.h"
#include "Preview.h"
#include "ini2.h"
#include "ArchiveRecovery.h"

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


// Barry - use this constant for both places
#define PROGRESS_HEIGHT 3

CBarShader CPartFile::s_LoadBar(PROGRESS_HEIGHT); // Barry - was 5
CBarShader CPartFile::s_ChunkBar(16); 

CPartFile::CPartFile()
{
	Init();
}

CPartFile::CPartFile(CSearchFile* searchresult)
{
	Init();
	memcpy(m_abyFileHash, searchresult->GetFileHash(), 16);
	for (int i = 0; i != searchresult->taglist.GetCount();i++){
		switch (searchresult->taglist[i]->tag->specialtag){
			case FT_FILENAME:{
				m_pszFileName = nstrdup(searchresult->taglist[i]->tag->stringvalue);
				break;
			}
			case FT_FILESIZE:{
				m_nFileSize = searchresult->taglist[i]->tag->intvalue;
				break;
			}
			default:
				CTag* newtag = new CTag(searchresult->taglist[i]->tag);
				taglist.Add(newtag);
		}
	}
	if(m_nFileSize < PARTSIZE )
		hashsetneeded = false;
	CreatePartFile();
}

CPartFile::CPartFile(CString edonkeylink)
{
	CED2KLink* pLink = 0;
	try {
		pLink = CED2KLink::CreateLinkFromUrl(edonkeylink);
		_ASSERT( pLink != 0 );
		CED2KFileLink* pFileLink = pLink->GetFileLink();
		if (pFileLink==0) 
			throw GetResString(IDS_ERR_NOTAFILELINK);
		InitializeFromLink(pFileLink);
	} catch (CString error) {
		OUTPUT_DEBUG_TRACE();
		char buffer[200];
		sprintf(buffer,GetResString(IDS_ERR_INVALIDLINK),error.GetBuffer());
		theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_LINKERROR), buffer);
		status = PS_ERROR;
	}
	delete pLink;
}

void
CPartFile::InitializeFromLink(CED2KFileLink* fileLink)
{
	Init();
	try{
		m_pszFileName = nstrdup( fileLink->GetName() );
		m_nFileSize = fileLink->GetSize();
		if(m_nFileSize < PARTSIZE )
			hashsetneeded = false;
		memcpy(m_abyFileHash, fileLink->GetHashKey(), sizeof(m_abyFileHash));
		if (!theApp.downloadqueue->IsFileExisting(m_abyFileHash))
			CreatePartFile();
		else
			status = PS_ERROR;
	}
	catch(CString error){
		OUTPUT_DEBUG_TRACE();
		char buffer[200];
		sprintf(buffer, GetResString(IDS_ERR_INVALIDLINK), error.GetBuffer());
		theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_LINKERROR), buffer);
		status = PS_ERROR;
	}
}

CPartFile::CPartFile(CED2KFileLink* fileLink)
{
	InitializeFromLink(fileLink);
}

void CPartFile::Init(){
	fullname = 0;
	newdate = true;
	lastsearchtime = 0;
	lastpurgetime = ::GetTickCount();
	paused = false;
	stopped= false;
	status = PS_EMPTY;
	transfered = 0;
	if(theApp.glob_prefs->GetNewAutoDown()){
		m_iDownPriority = PR_HIGH;
		m_bAutoDownPriority = true;
	}
	else{
		m_iDownPriority = PR_NORMAL;
		m_bAutoDownPriority = false;
	}
	srcarevisible = false;
	transferingsrc = 0;
	datarate = 0;
	hashsetneeded = true;
	count = 0;
	percentcompleted = 0;
	partmetfilename = 0;
	completedsize=0;
	m_bPreviewing = false;
	lastseencomplete = NULL;
	availablePartsCount=0;
	m_ClientSrcAnswered = 0;
	m_LastNoNeededCheck = 0;
	m_iRate = 0;
	m_strComment = "";
	m_nTotalBufferData = 0;
	m_nLastBufferFlushTime = 0;
	m_bPercentUpdated = false;
	m_bRecoveringArchive = false;
	m_iGainDueToCompression = 0;
	m_iLostDueToCorruption = 0;
	m_iTotalPacketsSavedDueToICH = 0;
	hasRating = false;
	hasComment = false;
	m_lastdatetimecheck=0;
	m_category=0;
}

CPartFile::~CPartFile(){
	// Barry - Ensure all buffered data is written
	FlushBuffer();

	if (fullname)
		delete[] fullname;
	if (partmetfilename)
		delete[] partmetfilename;
	m_SrcpartFrequency.RemoveAll();
	for (POSITION pos = gaplist.GetHeadPosition();pos != 0;gaplist.GetNext(pos))
		delete gaplist.GetAt(pos);
}

void CPartFile::CreatePartFile(){
	// use lowest free partfilenumber for free file (InterCeptor)
	int i = 0; 
	CString filename; 
	do 
	{ 
		i++; 
		filename.Format("%s\\%03i.part", theApp.glob_prefs->GetTempDir(), i); 
	}while(PathFileExists(filename)); 
	partmetfilename = new char[15]; 
	sprintf(partmetfilename,"%03i.part.met",i); 

	directory = nstrdup(theApp.glob_prefs->GetIncomingDir());

	fullname = new char[strlen(theApp.glob_prefs->GetTempDir())+strlen(partmetfilename)+MAX_PATH];
	sprintf(fullname,"%s\\%s",theApp.glob_prefs->GetTempDir(),partmetfilename);
	char* buffer = nstrdup(partmetfilename);
	buffer[strlen(buffer)-4] = 0;
	CTag* partnametag = new CTag(FT_PARTFILENAME,buffer);
	delete[] buffer;
	taglist.Add(partnametag);
	
	Gap_Struct* gap = new Gap_Struct;
	gap->start = 0;
	gap->end = m_nFileSize-1;
	gaplist.AddTail(gap);

	char* partfull = nstrdup(fullname);
	partfull[strlen(partfull)-4] = 0;
	
	if (!m_hpartfile.Open(partfull,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyWrite|CFile::osSequentialScan)){
	//if (!m_hpartfile.Open(partfull,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyWrite|CFile::osSequentialScan|CFile::osWriteThrough)){
		theApp.emuledlg->AddLogLine(false,GetResString(IDS_ERR_CREATEPARTFILE));
		status = PS_ERROR;
	}
	delete[] partfull;

	m_SrcpartFrequency.SetSize(GetPartCount());
	for (uint32 i = 0; i != GetPartCount();i++)
		m_SrcpartFrequency.Add(0);
	paused = false;
	SavePartFile();
}

bool CPartFile::LoadPartFile(char* in_directory,char* in_filename)
{
	CMap<uint16, uint16, Gap_Struct*, Gap_Struct*> gap_map; // Slugfiller
	transfered = 0;
	partmetfilename = nstrdup(in_filename);
	directory = nstrdup(in_directory);
	char* buffer = new char[strlen(directory)+strlen(partmetfilename)+2];
	sprintf(buffer, "%s\\%s", directory, partmetfilename);
	fullname = buffer;
	CSafeFile metFile;
	try{
		// readfile data form part.met file
		if (!metFile.Open(fullname, CFile::modeRead)){
			theApp.emuledlg->AddLogLine(false, GetResString(IDS_ERR_OPENMET), partmetfilename, m_pszFileName);
			return false;
		}
		uint8 version;
		metFile.Read(&version,1);
		if (version != PARTFILE_VERSION){
			if (metFile.m_hFile != INVALID_HANDLE_VALUE) 
				metFile.Close();
			theApp.emuledlg->AddLogLine(false, GetResString(IDS_ERR_BADMETVERSION), partmetfilename, m_pszFileName);
			return false;
		}
		LoadDateFromFile(&metFile);
		LoadHashsetFromFile(&metFile, false);

		uint32 tagcount;
		metFile.Read(&tagcount, 4);

		for (uint32 j = 0; j != tagcount; j++){
			CTag* newtag = new CTag(&metFile);
			switch(newtag->tag->specialtag){
				case FT_FILENAME:{
					if(newtag->tag->stringvalue == NULL) {
						theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_METCORRUPT), partmetfilename, m_pszFileName);
						delete newtag;
						return false;
					}
					m_pszFileName = nstrdup(newtag->tag->stringvalue);
					delete newtag;
					break;
				}
				case FT_LASTSEENCOMPLETE: {
					lastseencomplete = newtag->tag->intvalue;
					delete newtag;
					break;
				}
				case FT_FILESIZE:{
					m_nFileSize = newtag->tag->intvalue;
					delete newtag;
					break;
				}
				case FT_TRANSFERED:{
					transfered = newtag->tag->intvalue;
					delete newtag;
					break;
				}
				case FT_CATEGORY:{
					m_category = newtag->tag->intvalue;
					delete newtag;
					break;
				}
				case FT_DLPRIORITY:{
					m_iDownPriority = newtag->tag->intvalue;
					delete newtag;
					if( m_iDownPriority == PR_AUTO ){
						m_iDownPriority = PR_HIGH;
						SetAutoDownPriority(true);
					}
					else
						SetAutoDownPriority(false);
					break;
				}
				case FT_STATUS:{
					paused = newtag->tag->intvalue;
					stopped=paused;
					delete newtag;
					break;
				}
				case FT_ULPRIORITY:{
					SetUpPriority(newtag->tag->intvalue, false);
					delete newtag;
					if( GetUpPriority() == PR_AUTO ){
						SetUpPriority(PR_HIGH, false);
						SetAutoUpPriority(true);
					}
					else
						SetAutoUpPriority(false);
					break;
				}
				default:{
					// Start Changes by Slugfiller for better exception handling
					if ((!newtag->tag->specialtag) &&
						(newtag->tag->tagname[0] == FT_GAPSTART ||
							newtag->tag->tagname[0] == FT_GAPEND)){
						Gap_Struct* gap;
						uint16 gapkey = atoi(&newtag->tag->tagname[1]);
						if (!gap_map.Lookup(gapkey, gap))
						{
							gap = new Gap_Struct;
							gap_map.SetAt(gapkey, gap);
							gap->start = -1;
							gap->end = -1;
						}
						if (newtag->tag->tagname[0] == FT_GAPSTART)
							gap->start = newtag->tag->intvalue;
						if (newtag->tag->tagname[0] == FT_GAPEND)
							gap->end = newtag->tag->intvalue-1;
						delete newtag;
					// End Changes by Slugfiller for better exception handling
					}
					else
						taglist.Add(newtag);
				}
					
			}

		}
		if (metFile.m_hFile != INVALID_HANDLE_VALUE) 
			metFile.Close();
	}
	catch(CFileException* error){
		OUTPUT_DEBUG_TRACE();
		if (error->m_cause == CFileException::endOfFile)
			theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_METCORRUPT), partmetfilename, m_pszFileName);
		else{
			char buffer[150];
			error->GetErrorMessage(buffer,150);
			theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_FILEERROR), partmetfilename, m_pszFileName, error);
		}
		error->Delete();
		return false;
	}

	// Now to flush the map into the list (Slugfiller)
	for (POSITION pos = gap_map.GetStartPosition(); pos != NULL; ){
		Gap_Struct* gap;
		uint16 gapkey;
		gap_map.GetNextAssoc(pos, gapkey, gap);
		if (gap->start >= 0 && gap->end >=0 && gap->start <= gap->end)
			gaplist.AddTail(gap); // All tags accounted for
		else
			delete gap; // Some of the tags were missing
	}

	//check if this is a backup
	if(stricmp(strrchr(fullname, '.'), ".backup") == 0) {
		char *shorten = strrchr(fullname, '.');
		*shorten = 0;
		fullname = (char*)realloc(fullname, strlen(fullname) + 1);
	}

	// open permanent handle
	char* searchpath = nstrdup(fullname);
	searchpath[strlen(fullname)-4] = 0;
	if (!m_hpartfile.Open(searchpath, CFile::modeReadWrite|CFile::shareDenyWrite|CFile::osSequentialScan)){
	//if (!m_hpartfile.Open(searchpath, CFile::modeReadWrite|CFile::shareDenyWrite|CFile::osSequentialScan|CFile::osWriteThrough)){		
		theApp.emuledlg->AddLogLine(false, GetResString(IDS_ERR_FILEOPEN), fullname, m_pszFileName);
		delete[] searchpath;
		return false;
	}
	delete[] searchpath;
			

	m_SrcpartFrequency.SetSize(GetPartCount());
	for (uint32 i = 0; i != GetPartCount();i++)
		m_SrcpartFrequency.Add(0);
	status = PS_EMPTY;
	// check hashcount, filesatus etc
	if (hashlist.GetCount() < GetPartCount() && GetFileSize() >= PARTSIZE){
		hashsetneeded = true;
		return true;
	}
	else {
		hashsetneeded = false;
		for (int i = 0; i != hashlist.GetSize(); i++){
			if (IsComplete(i*PARTSIZE,((i+1)*PARTSIZE)-1)){
				status = PS_READY;
			}
		}
	}

	if (gaplist.IsEmpty()){	// is this file complete already?
		CompleteFile(false);
		return true;
	}

	// check date of .part file - if its wrong, rehash file
	CFileStatus filestatus;
	m_hpartfile.GetStatus(filestatus); // this; "...returns m_attribute without high-order flags" indicates a known MFC bug, wonder how many unknown there are... :)
	if (date != mktime(filestatus.m_mtime.GetLocalTm())){
		theApp.emuledlg->AddLogLine(false, GetResString(IDS_ERR_REHASH), buffer, m_pszFileName);
		// rehash
		status = PS_WAITINGFORHASH;
		CAddFileThread* addfilethread = (CAddFileThread*) AfxBeginThread(RUNTIME_CLASS(CAddFileThread), THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);
		addfilethread->SetValues(0, directory, m_hpartfile.GetFileName().GetBuffer(), this);

⌨️ 快捷键说明

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