📄 partfile.cpp
字号:
AddLogLine(false, GetResString(IDS_HASHINGDONE), GetFileName());
}
else{
SetStatus(PS_READY);
if (thePrefs.GetVerbose())
AddDebugLogLine(true, _T("File-hashing failed for \"%s\""), GetFileName());
SavePartFile();
return;
}
if (thePrefs.GetVerbose())
AddDebugLogLine(true, _T("Completed file-hashing for \"%s\""), GetFileName());
SetStatus(PS_READY);
SavePartFile();
theApp.sharedfiles->SafeAddKFile(this);
}
void CPartFile::AddGap(uint32 start, uint32 end)
{
POSITION pos1, pos2;
for (pos1 = gaplist.GetHeadPosition();(pos2 = pos1) != NULL;){
Gap_Struct* cur_gap = gaplist.GetNext(pos1);
if (cur_gap->start >= start && cur_gap->end <= end){ // this gap is inside the new gap - delete
gaplist.RemoveAt(pos2);
delete cur_gap;
}
else if (cur_gap->start >= start && cur_gap->start <= end){// a part of this gap is in the new gap - extend limit and delete
end = cur_gap->end;
gaplist.RemoveAt(pos2);
delete cur_gap;
}
else if (cur_gap->end <= end && cur_gap->end >= start){// a part of this gap is in the new gap - extend limit and delete
start = cur_gap->start;
gaplist.RemoveAt(pos2);
delete cur_gap;
}
else if (start >= cur_gap->start && end <= cur_gap->end){// new gap is already inside this gap - return
return;
}
}
Gap_Struct* new_gap = new Gap_Struct;
new_gap->start = start;
new_gap->end = end;
gaplist.AddTail(new_gap);
UpdateDisplayedInfo();
newdate = true;
}
bool CPartFile::IsComplete(uint32 start, uint32 end) const
{
if (end >= m_nFileSize)
end = m_nFileSize-1;
for (POSITION pos = gaplist.GetHeadPosition();pos != 0;)
{
const Gap_Struct* cur_gap = gaplist.GetNext(pos);
if ( (cur_gap->start >= start && cur_gap->end <= end)
|| (cur_gap->start >= start && cur_gap->start <= end)
|| (cur_gap->end <= end && cur_gap->end >= start)
|| (start >= cur_gap->start && end <= cur_gap->end)
)
{
return false;
}
}
return true;
}
bool CPartFile::IsPureGap(uint32 start, uint32 end) const
{
if (end >= m_nFileSize)
end = m_nFileSize-1;
for (POSITION pos = gaplist.GetHeadPosition();pos != 0;){
const Gap_Struct* cur_gap = gaplist.GetNext(pos);
if (start >= cur_gap->start && end <= cur_gap->end ){
return true;
}
}
return false;
}
bool CPartFile::IsAlreadyRequested(uint32 start, uint32 end) const
{
for (POSITION pos = requestedblocks_list.GetHeadPosition();pos != 0; ){
const Requested_Block_Struct* cur_block = requestedblocks_list.GetNext(pos);
if ((start <= cur_block->EndOffset) && (end >= cur_block->StartOffset))
return true;
}
return false;
}
uint32 CPartFile::GetTotalGapSizeInRange(uint32 uRangeStart, uint32 uRangeEnd) const
{
uint32 uTotalGapSize = 0;
if (uRangeEnd >= m_nFileSize)
uRangeEnd = m_nFileSize - 1;
POSITION pos = gaplist.GetHeadPosition();
while (pos)
{
const Gap_Struct* pGap = gaplist.GetNext(pos);
if (pGap->start < uRangeStart && pGap->end > uRangeEnd)
{
uTotalGapSize += uRangeEnd - uRangeStart + 1;
break;
}
if (pGap->start >= uRangeStart && pGap->start <= uRangeEnd)
{
uint32 uEnd = (pGap->end > uRangeEnd) ? uRangeEnd : pGap->end;
uTotalGapSize += uEnd - pGap->start + 1;
}
else if (pGap->end >= uRangeStart && pGap->end <= uRangeEnd)
{
uTotalGapSize += pGap->end - uRangeStart + 1;
}
}
ASSERT( uTotalGapSize <= uRangeEnd - uRangeStart + 1 );
return uTotalGapSize;
}
uint32 CPartFile::GetTotalGapSizeInPart(UINT uPart) const
{
uint32 uRangeStart = uPart * PARTSIZE;
uint32 uRangeEnd = uRangeStart + PARTSIZE - 1;
if (uRangeEnd >= m_nFileSize)
uRangeEnd = m_nFileSize;
return GetTotalGapSizeInRange(uRangeStart, uRangeEnd);
}
bool CPartFile::GetNextEmptyBlockInPart(uint16 partNumber, Requested_Block_Struct *result) const
{
Gap_Struct *firstGap;
Gap_Struct *currentGap;
uint32 end;
uint32 blockLimit;
// Find start of this part
uint32 partStart = (PARTSIZE * partNumber);
uint32 start = partStart;
// What is the end limit of this block, i.e. can't go outside part (or filesize)
uint32 partEnd = (PARTSIZE * (partNumber + 1)) - 1;
if (partEnd >= GetFileSize())
partEnd = GetFileSize() - 1;
// Loop until find a suitable gap and return true, or no more gaps and return false
for (;;)
{
firstGap = NULL;
// Find the first gap from the start position
for (POSITION pos = gaplist.GetHeadPosition(); pos != 0; )
{
currentGap = gaplist.GetNext(pos);
// Want gaps that overlap start<->partEnd
if ((currentGap->start <= partEnd) && (currentGap->end >= start))
{
// Is this the first gap?
if ((firstGap == NULL) || (currentGap->start < firstGap->start))
firstGap = currentGap;
}
}
// If no gaps after start, exit
if (firstGap == NULL)
return false;
// Update start position if gap starts after current pos
if (start < firstGap->start)
start = firstGap->start;
// If this is not within part, exit
if (start > partEnd)
return false;
// Find end, keeping within the max block size and the part limit
end = firstGap->end;
blockLimit = partStart + (EMBLOCKSIZE * (((start - partStart) / EMBLOCKSIZE) + 1)) - 1;
if (end > blockLimit)
end = blockLimit;
if (end > partEnd)
end = partEnd;
// If this gap has not already been requested, we have found a valid entry
if (!IsAlreadyRequested(start, end))
{
// Was this block to be returned
if (result != NULL)
{
result->StartOffset = start;
result->EndOffset = end;
md4cpy(result->FileID, GetFileHash());
result->transferred = 0;
}
return true;
}
else
{
// Reposition to end of that gap
start = end + 1;
}
// If tried all gaps then break out of the loop
if (end == partEnd)
break;
}
// No suitable gap found
return false;
}
void CPartFile::FillGap(uint32 start, uint32 end)
{
POSITION pos1, pos2;
for (pos1 = gaplist.GetHeadPosition();(pos2 = pos1) != NULL;){
Gap_Struct* cur_gap = gaplist.GetNext(pos1);
if (cur_gap->start >= start && cur_gap->end <= end){ // our part fills this gap completly
gaplist.RemoveAt(pos2);
delete cur_gap;
}
else if (cur_gap->start >= start && cur_gap->start <= end){// a part of this gap is in the part - set limit
cur_gap->start = end+1;
}
else if (cur_gap->end <= end && cur_gap->end >= start){// a part of this gap is in the part - set limit
cur_gap->end = start-1;
}
else if (start >= cur_gap->start && end <= cur_gap->end){
uint32 buffer = cur_gap->end;
cur_gap->end = start-1;
cur_gap = new Gap_Struct;
cur_gap->start = end+1;
cur_gap->end = buffer;
gaplist.InsertAfter(pos1,cur_gap);
break; // [Lord KiRon]
}
}
UpdateCompletedInfos();
UpdateDisplayedInfo();
newdate = true;
}
void CPartFile::UpdateCompletedInfos()
{
uint32 allgaps = 0;
for (POSITION pos = gaplist.GetHeadPosition();pos != 0;){
const Gap_Struct* cur_gap = gaplist.GetNext(pos);
allgaps += cur_gap->end - cur_gap->start + 1;
}
UpdateCompletedInfos(allgaps);
}
void CPartFile::UpdateCompletedInfos(uint32 uTotalGaps)
{
if (uTotalGaps > m_nFileSize){
ASSERT(0);
uTotalGaps = m_nFileSize;
}
if (gaplist.GetCount() || requestedblocks_list.GetCount()){
// 'percentcompleted' is only used in GUI, round down to avoid showing "100%" in case
// we actually have only "99.9%"
percentcompleted = floor((1.0 - (double)uTotalGaps/m_nFileSize) * 1000.0) / 10.0;
completedsize = m_nFileSize - uTotalGaps;
}
else{
percentcompleted = 100.0F;
completedsize = m_nFileSize;
}
}
void CPartFile::DrawShareStatusBar(CDC* dc, LPCRECT rect, bool onlygreyrect, bool bFlat) const
{
if( !IsPartFile() )
{
CKnownFile::DrawShareStatusBar( dc, rect, onlygreyrect, bFlat );
return;
}
const COLORREF crMissing = RGB(255, 0, 0);
s_ChunkBar.SetFileSize(GetFileSize());
s_ChunkBar.SetHeight(rect->bottom - rect->top);
s_ChunkBar.SetWidth(rect->right - rect->left);
s_ChunkBar.Fill(crMissing);
if (!onlygreyrect && !m_SrcpartFrequency.IsEmpty()){
COLORREF crProgress;
COLORREF crHave;
COLORREF crPending;
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);
}
for (int i = 0; i < GetPartCount(); i++){
if(m_SrcpartFrequency[i] > 0 ){
COLORREF color = RGB(0, (210-(22*(m_SrcpartFrequency[i]-1)) < 0) ? 0 : 210-(22*(m_SrcpartFrequency[i]-1)), 255);
s_ChunkBar.FillRange(PARTSIZE*(i),PARTSIZE*(i+1),color);
}
}
}
s_ChunkBar.Draw(dc, rect->left, rect->top, bFlat);
}
void CPartFile::DrawStatusBar(CDC* dc, LPCRECT rect, bool bFlat) /*const*/
{
COLORREF crProgress;
COLORREF crHave;
COLORREF crPending;
COLORREF crMissing; // SLUGFILLER: grayPause - moved down
bool notgray = GetStatus() == PS_EMPTY || GetStatus() == PS_READY; // SLUGFILLER: grayPause - only test once
// SLUGFILLER: grayPause - Colors by status
if(bFlat)
crProgress = RGB(0, 150, 0);
else
crProgress = RGB(0, 224, 0);
if(notgray) {
crMissing = RGB(255, 0, 0);
if(bFlat) {
crHave = RGB(0, 0, 0);
crPending = RGB(255,208,0);
} else {
crHave = RGB(104, 104, 104);
crPending = RGB(255, 208, 0);
}
} else {
crMissing = RGB(191, 64, 64);
if(bFlat) {
crHave = RGB(64, 64, 64);
crPending = RGB(191,168,64);
} else {
crHave = RGB(116, 116, 116);
crPending = RGB(191, 168, 64);
}
}
// SLUGFILLER: grayPause
s_ChunkBar.SetHeight(rect->bottom - rect->top);
s_ChunkBar.SetWidth(rect->right - rect->left);
s_ChunkBar.SetFileSize(m_nFileSize);
s_ChunkBar.Fill(crHave);
if (status == PS_COMPLETE || status == PS_COMPLETING)
{
s_ChunkBar.FillRange(0, m_nFileSize, crProgress);
s_ChunkBar.Draw(dc, rect->left, rect->top, bFlat);
percentcompleted = 100.0F;
completedsize = m_nFileSize;
}
else
{
// red gaps
uint32 allgaps = 0;
for (POSITION pos = gaplist.GetHeadPosition();pos != 0;){
const Gap_Struct* cur_gap = gaplist.GetNext(pos);
allgaps += cur_gap->end - cur_gap->start + 1;
bool gapdone = false;
uint32 gapstart = cur_gap->start;
uint32 gapend = cur_gap->end;
for (uint32 i = 0; i < GetPartCount(); i++){
if (gapstart >= i*PARTSIZE && gapstart <= (i+1)*PARTSIZE - 1){ // is in this part?
if (gapend <= (i+1)*PARTSIZE - 1)
gapdone = true;
else
gapend = (i+1)*PARTSIZE - 1; // and next part
// paint
COLORREF color;
if (m_SrcpartFrequency.GetCount() >= (INT_PTR)i && m_SrcpartFrequency[(uint16)i])
// SLUGFILLER: grayPause
{
if(notgray)
color = RGB(0,
(210-(22*(m_SrcpartFrequency[(uint16)i]-1)) < 0)? 0:210-(22*(m_SrcpartFrequency[(uint16)i]-1))
,255);
else
color = RGB(64,
(169-(11*(m_SrcpartFrequency[(uint16)i]-1)) < 64)? 64:169-(11*(m_SrcpartFrequency[(uint16)i]-1))
,191);
}
// SLUGFILLER: grayPause
else
color = crMissing;
s_ChunkBar.FillRange(gapstart, gapend + 1, color);
if (gapdone) // finished?
break;
else{
gapstart = gapend + 1;
gapend = cur_gap->end;
}
}
}
}
// yellow pending parts
for (POSITION pos = requestedblocks_list.GetHeadPosition();pos != 0;){
const Requested_Block_Struct* block = requestedblocks_list.GetNext(pos);
s_ChunkBar.FillRange(block->StartOffset + block->transferred, block->EndOffset + 1, crPending);
}
s_ChunkBar.Draw(dc, rect->left, rect->top, bFlat);
// green progress
float blockpixel = (float)(rect->right - rect->left)/(float)m_nFileSize;
RECT gaprect;
gaprect.top = rect->top;
gaprect.bottom = gaprect.top + PROGRESS_HEIGHT; // Barry - was 4
gaprect.left = rect->left;
if(!bFlat) {
s_LoadBar.SetWidth((m_nFileSize - allgaps)*blockpixel + 0.5F);
s_LoadBar.Fill(crProgress);
s_LoadBar.Draw(dc, gaprect.left, gaprect.top, false);
} else {
gaprect.right = rect->left + (uint32)((m_nFileSize - allgaps)*blockpixel + 0.5F);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -