📄 knownfile.cpp
字号:
// parts of this file are based on work from pan One (http://home-3.tiscali.nl/~meost/pms/)
//this file is part of eMule
//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 "knownfile.h"
#include "opcodes.h"
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "emule.h"
#include "ini2.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
void CFileStatistic::AddRequest(){
requested++;
alltimerequested++;
theApp.knownfiles->requested++;
theApp.sharedfiles->UpdateFile(fileParent);
}
void CFileStatistic::AddAccepted(){
accepted++;
alltimeaccepted++;
theApp.knownfiles->accepted++;
theApp.sharedfiles->UpdateFile(fileParent);
}
void CFileStatistic::AddTransferred(uint64 bytes){
transferred += bytes;
alltimetransferred += bytes;
theApp.knownfiles->transferred += bytes;
theApp.sharedfiles->UpdateFile(fileParent);
}
CKnownFile::CKnownFile()
{
m_iFileType = 2;
directory = NULL;
m_pszFileName = NULL;
m_nFileSize = 0;
date = 0;
if(theApp.glob_prefs->GetNewAutoUp()){
m_iUpPriority = PR_HIGH;
m_bAutoUpPriority = true;
}
else{
m_iUpPriority = PR_NORMAL;
m_bAutoUpPriority = false;
}
m_iQueuedCount = 0;
m_iPermissions = PERM_ALL;
statistic.fileParent = this;
m_bCommentLoaded = false;
m_iRate = 0;
m_strComment = "";
m_iPartCount = 0;
}
CKnownFile::~CKnownFile(){
for (int i = 0; i != hashlist.GetSize(); i++)
if (hashlist[i])
delete[] hashlist[i];
for (int i = 0; i != taglist.GetSize(); i++)
safe_delete(taglist[i]);
// if (filename) // done by CAbstractFile destructor
// delete[] filename;
if (directory)
delete[] directory;
m_AvailPartFrequency.RemoveAll();
}
CBarShader CKnownFile::s_ShareStatusBar(16);
void CKnownFile::DrawShareStatusBar(CDC* dc, RECT* rect, bool onlygreyrect, bool bFlat){
COLORREF crProgress;
COLORREF crHave;
COLORREF crPending;
COLORREF crMissing = RGB(255, 0, 0);
if(bFlat) {
crProgress = RGB(0, 150, 0);
crHave = RGB(0, 0, 0);
crPending = RGB(255,208,0);
} else {
crProgress = RGB(0, 224, 0);
crHave = RGB(104, 104, 104);
crPending = RGB(255, 208, 0);
}
s_ShareStatusBar.SetFileSize(this->GetFileSize());
s_ShareStatusBar.SetHeight(rect->bottom - rect->top);
s_ShareStatusBar.SetWidth(rect->right - rect->left);
s_ShareStatusBar.Fill(crMissing);
COLORREF color;
if (!onlygreyrect && !m_AvailPartFrequency.IsEmpty()) {
for (int i = 0;i != GetPartCount();i++)
if(m_AvailPartFrequency[i] > 0 ){
color = RGB(0, (210-(22*(m_AvailPartFrequency[i]-1)) < 0)? 0:210-(22*(m_AvailPartFrequency[i]-1)), 255);
s_ShareStatusBar.FillRange(PARTSIZE*(i),PARTSIZE*(i+1),color);
}
}
s_ShareStatusBar.Draw(dc, rect->left, rect->top, bFlat);
}
void CKnownFile::NewAvailPartsInfo(){
// Cache part count
uint16 partcount = GetPartCount();
if(m_AvailPartFrequency.GetSize() < partcount)
m_AvailPartFrequency.SetSize(partcount);
// Reset part counters
for(int i = 0; i < partcount; i++){
m_AvailPartFrequency[i] = 0;
}
CUpDownClient* cur_src;
if(this->IsPartFile())
cur_src = NULL;
for (POSITION pos = m_ClientUploadList.GetHeadPosition(); pos != 0; ){
cur_src = m_ClientUploadList.GetNext(pos);
for (int i = 0; i != partcount; i++){
if (cur_src->IsUpPartAvailable(i))
m_AvailPartFrequency[i] +=1;
}
}
theApp.emuledlg->sharedfileswnd.sharedfilesctrl.UpdateFile(this);
}
void CKnownFile::AddUploadingClient(CUpDownClient* client){
POSITION pos = m_ClientUploadList.Find(client); // to be sure
if(pos == NULL){
m_ClientUploadList.AddTail(client);
}
}
void CKnownFile::RemoveUploadingClient(CUpDownClient* client){
POSITION pos = m_ClientUploadList.Find(client); // to be sure
if(pos != NULL){
m_ClientUploadList.RemoveAt(pos);
}
}
void CKnownFile::SetPath(char* path){
if (directory)
delete[] directory;
directory = nstrdup(path);
}
bool CKnownFile::CreateFromFile(char* in_directory, char* in_filename)
{
// TODO Errorhandling
//first create the filehashset
// open file
directory = nstrdup(in_directory);
char* namebuffer = new char[strlen(in_directory)+strlen(in_filename)+2];
sprintf(namebuffer, "%s\\%s", in_directory, in_filename);
FILE* file = fopen(namebuffer, "rbS");
delete namebuffer;
if (!file)
return false;
// set filesize + name
m_pszFileName = nstrdup(in_filename);
m_nFileSize =_filelength(file->_file);
m_AvailPartFrequency.SetSize(GetPartCount());
for (uint32 i = 0; i != GetPartCount();i++)
m_AvailPartFrequency.Add(0);
// create hashset
uint32 togo = m_nFileSize;
for (uint16 hashcount = 0; togo >= PARTSIZE; ) {
uchar* newhash = new uchar[16];
CreateHashFromFile(file, PARTSIZE, newhash);
hashlist.Add(newhash);
togo -= PARTSIZE;
hashcount++;
}
uchar* lasthash = new uchar[16];
memset(lasthash, 0, 16);
CreateHashFromFile(file, togo, lasthash);
if (!hashcount){
memcpy(m_abyFileHash, lasthash, 16);
delete[] lasthash; // i_a: memleak
}
else {
hashlist.Add(lasthash);
uchar* buffer = new uchar[hashlist.GetCount()*16];
for (int i = 0; i != hashlist.GetCount(); i++)
memcpy(buffer+(i*16), hashlist[i], 16);
CreateHashFromString(buffer, hashlist.GetCount()*16, m_abyFileHash);
delete[] buffer;
}
// TODO: Add filetags
// set lastwrite date
struct _stat fileinfo;
_fstat(file->_file, &fileinfo);
date = fileinfo.st_mtime;
//finished
fclose(file);
return true;
}
// needed for memfiles. its probably better to switch everything to CFile...
bool CKnownFile::LoadHashsetFromFile(CFile* file, bool checkhash){
uchar checkid[16];
file->Read(&checkid, 16);
uint16 parts;
file->Read(&parts, 2);
for (int i = 0; i != parts; i++){
uchar* cur_hash = new uchar[16];
file->Read(cur_hash, 16);
hashlist.Add(cur_hash);
}
if (!checkhash){
memcpy(m_abyFileHash, checkid, 16);
return true;
}
// trust noone ;-)
if (!hashlist.IsEmpty()){
uchar* buffer = new uchar[hashlist.GetCount()*16];
for (int i = 0; i != hashlist.GetCount(); i++)
memcpy(buffer+(i*16), hashlist[i], 16);
CreateHashFromString(buffer, hashlist.GetCount()*16, checkid);
delete[] buffer;
}
if (!memcmp(m_abyFileHash, checkid, 16))
return true;
else{
for (int i = 0; i != hashlist.GetSize(); i++)
delete[] hashlist[i];
hashlist.RemoveAll();
return false;
}
}
bool CKnownFile::LoadTagsFromFile(CFile* file){
uint32 tagcount;
file->Read(&tagcount,4);
for (uint32 j = 0; j != tagcount;j++){
CTag* newtag = new CTag(file);
switch(newtag->tag->specialtag){
case FT_FILENAME:{
m_pszFileName = nstrdup(newtag->tag->stringvalue);
delete newtag;
break;
}
case FT_FILESIZE:{
m_nFileSize = newtag->tag->intvalue;
m_AvailPartFrequency.SetSize(GetPartCount());
for (uint32 i = 0; i != GetPartCount();i++)
m_AvailPartFrequency.Add(0);
delete newtag;
break;
}
case FT_ATTRANSFERED:{
statistic.alltimetransferred = newtag->tag->intvalue;
delete newtag;
break;
}
case FT_ATTRANSFEREDHI:{
uint32 hi,low;
low=statistic.alltimetransferred;
hi = newtag->tag->intvalue;
uint64 hi2;
hi2=hi;
hi2=hi2<<32;
statistic.alltimetransferred=low+hi2;
delete newtag;
break;
}
case FT_ATREQUESTED:{
statistic.alltimerequested = newtag->tag->intvalue;
delete newtag;
break;
}
case FT_ATACCEPTED:{
statistic.alltimeaccepted = newtag->tag->intvalue;
delete newtag;
break;
}
case FT_ULPRIORITY:{
uint8 autoprio = PR_AUTO;
m_iUpPriority = newtag->tag->intvalue;
if( m_iUpPriority == autoprio ){
m_iUpPriority = PR_HIGH;
m_bAutoUpPriority = true;
}
else
m_bAutoUpPriority = false;
delete newtag;
break;
}
case FT_PERMISSIONS:{
m_iPermissions = newtag->tag->intvalue;
delete newtag;
break;
}
default:
taglist.Add(newtag);
}
}
return true;
}
bool CKnownFile::LoadDateFromFile(CFile* file){
file->Read(&date,4);
return true;
}
bool CKnownFile::LoadFromFile(CFile* file){
return (LoadDateFromFile(file) && LoadHashsetFromFile(file,false) && LoadTagsFromFile(file));
}
bool CKnownFile::WriteToFile(FILE* file){
// date
fwrite(&date,4,1,file);
// hashset
fwrite(&m_abyFileHash,16,1,file);
uint16 parts = hashlist.GetCount();
fwrite(&parts,2,1,file);
for (int i = 0; i != parts; i++)
fwrite(hashlist[i],16,1,file);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -