00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Download.h"
00026 #include "Downloads.h"
00027 #include "DownloadSource.h"
00028 #include "DownloadTransfer.h"
00029 #include "FragmentedFile.h"
00030 #include "Network.h"
00031 #include "Buffer.h"
00032 #include "SHA.h"
00033 #include "ED2K.h"
00034 #include "SourceURL.h"
00035 #include "XML.h"
00036 #include "DownloadTransferBT.h"
00037
00038 #ifdef _DEBUG
00039 #undef THIS_FILE
00040 static char THIS_FILE[]=__FILE__;
00041 #define new DEBUG_NEW
00042 #endif
00043
00044
00046
00047
00048 CDownloadTransfer::CDownloadTransfer(CDownloadSource* pSource, PROTOCOLID nProtocol)
00049 {
00050 m_nProtocol = nProtocol;
00051 m_pDownload = pSource->m_pDownload;
00052 m_pDlPrev = NULL;
00053 m_pDlNext = NULL;
00054 m_pSource = pSource;
00055
00056 m_nState = dtsNull;
00057
00058 m_nQueuePos = 0;
00059 m_nQueueLen = 0;
00060
00061 m_nOffset = SIZE_UNKNOWN;
00062 m_nLength = 0;
00063 m_nPosition = 0;
00064 m_nDownloaded = 0;
00065
00066 m_bWantBackwards = m_bRecvBackwards = FALSE;
00067
00068 m_pDownload->AddTransfer( this );
00069 }
00070
00071 CDownloadTransfer::~CDownloadTransfer()
00072 {
00073 ASSERT( m_pSource == NULL );
00074 }
00075
00077
00078
00079 void CDownloadTransfer::Close(TRISTATE bKeepSource)
00080 {
00081 SetState( dtsNull );
00082
00083 CTransfer::Close();
00084
00085 if ( m_pSource != NULL )
00086 {
00087 switch ( bKeepSource )
00088 {
00089 case TS_TRUE:
00090 m_pSource->OnFailure( TRUE );
00091 break;
00092 case TS_UNKNOWN:
00093 m_pSource->OnFailure( FALSE );
00094 break;
00095 case TS_FALSE:
00096 m_pSource->Remove( FALSE, TRUE );
00097 break;
00098 }
00099
00100 m_pSource = NULL;
00101 }
00102
00103 ASSERT( m_pDownload != NULL );
00104 m_pDownload->RemoveTransfer( this );
00105 }
00106
00108
00109
00110 void CDownloadTransfer::Boost()
00111 {
00112 m_mInput.pLimit = m_mOutput.pLimit = NULL;
00113 }
00114
00115 DWORD CDownloadTransfer::GetAverageSpeed()
00116 {
00117 return GetMeasuredSpeed();
00118 }
00119
00120 DWORD CDownloadTransfer::GetMeasuredSpeed()
00121 {
00122 Measure();
00123 return m_mInput.nMeasure;
00124 }
00125
00127
00128
00129 CString CDownloadTransfer::GetStateText(BOOL bLong)
00130 {
00131 CString str, strQ, strQueued, strOf;
00132
00133 switch ( m_nState )
00134 {
00135 case dtsConnecting:
00136 LoadString( str, IDS_STATUS_CONNECTING );
00137 break;
00138 case dtsRequesting:
00139 LoadString( str, IDS_STATUS_REQUESTING );
00140 break;
00141 case dtsHeaders:
00142 case dtsFlushing:
00143 LoadString( str, IDS_STATUS_RESPONSE );
00144 break;
00145 case dtsDownloading:
00146 LoadString( str, IDS_STATUS_DOWNLOADING );
00147 break;
00148 case dtsTiger:
00149 LoadString( str, IDS_STATUS_TIGERTREE );
00150 break;
00151 case dtsHashset:
00152 LoadString( str, IDS_STATUS_HASHSET );
00153 break;
00154 case dtsMetadata:
00155 LoadString( str, IDS_STATUS_METADATA );
00156 break;
00157 case dtsBusy:
00158 LoadString( str, IDS_STATUS_BUSY );
00159 break;
00160 case dtsEnqueue:
00161 LoadString( str, IDS_STATUS_ENQUEUE );
00162 break;
00163 case dtsQueued:
00164 LoadString( strQ, IDS_STATUS_Q );
00165 LoadString( strQueued, IDS_STATUS_QUEUED );
00166 LoadString( strOf, IDS_GENERAL_OF );
00167 if ( ! bLong )
00168 {
00169 str.Format( m_nQueueLen ? _T("%s %i %s %i") : _T("%s #%i"),
00170 strQ, m_nQueuePos, strOf, m_nQueueLen );
00171 }
00172 else if ( m_sQueueName.GetLength() )
00173 {
00174 str.Format( _T("%s: %s: %i %s %i"), strQueued,
00175 (LPCTSTR)m_sQueueName, m_nQueuePos, strOf, m_nQueueLen );
00176 }
00177 else
00178 {
00179 str.Format( m_nQueueLen ? _T("%s: %i %s %i") : _T("%s: #%i"), strQueued,
00180 m_nQueuePos, strOf, m_nQueueLen );
00181 }
00182 break;
00183 default:
00184 LoadString( str, IDS_STATUS_UNKNOWN );
00185 break;
00186 }
00187
00188 return str;
00189 }
00190
00192
00193
00194 BOOL CDownloadTransfer::OnRun()
00195 {
00196 return CTransfer::OnRun();
00197 }
00198
00200
00201
00202 void CDownloadTransfer::SetState(int nState)
00203 {
00204 if ( m_pDownload != NULL )
00205 {
00206 if ( Settings.Downloads.SortSources )
00207 {
00208
00209 static BYTE StateSortOrder[13]={ 13 ,12 ,10 ,4 ,0 ,4 ,1 ,2 ,3 ,12 ,8 ,6 ,9};
00210
00211
00212
00213
00214
00215 m_pSource->m_nSortOrder = StateSortOrder[ min( nState, 13 ) ];
00216
00217 if ( m_pSource->m_nSortOrder >= 13 )
00218 {
00219 m_pDownload->SortSource( m_pSource, FALSE );
00220 m_pSource->m_nSortOrder = -1;
00221 }
00222 else
00223 {
00224
00225 if( ( nState == dtsTorrent ) && ( m_pSource->m_pTransfer ) )
00226 {
00227 CDownloadTransferBT* pBT = (CDownloadTransferBT*)m_pSource->m_pTransfer;
00228 if ( ! pBT->m_bInterested ) m_pSource->m_nSortOrder = 11;
00229 else if ( pBT->m_bChoked ) m_pSource->m_nSortOrder = 7;
00230 else m_pSource->m_nSortOrder = 10;
00231 }
00232 m_pSource->m_nSortOrder <<= 8;
00233
00234 if ( m_nProtocol != PROTOCOL_HTTP )
00235 m_pSource->m_nSortOrder += ( m_nProtocol & 0xFF );
00236 m_pSource->m_nSortOrder <<= 16;
00237
00238 if ( nState == dtsQueued )
00239 m_pSource->m_nSortOrder += ( min( m_nQueuePos, 10000 ) & 0xFFFF );
00240 else
00241 m_pSource->m_nSortOrder += ( ( m_pSource->m_pAddress.S_un.S_un_b.s_b1 << 8 ) |
00242 ( m_pSource->m_pAddress.S_un.S_un_b.s_b2 ) );
00243
00244
00245 m_pDownload->SortSource( m_pSource );
00246 }
00247 }
00248 else
00249 {
00250 if ( nState == dtsDownloading && m_nState != dtsDownloading )
00251 {
00252 m_pDownload->SortSource( m_pSource, TRUE );
00253 }
00254 else if ( nState != dtsDownloading && m_nState == dtsDownloading )
00255 {
00256 m_pDownload->SortSource( m_pSource, FALSE );
00257 }
00258 }
00259 }
00260
00261 m_nState = nState;
00262 }
00263
00265
00266
00267 void CDownloadTransfer::ChunkifyRequest(QWORD* pnOffset, QWORD* pnLength, QWORD nChunk, BOOL bVerifyLock)
00268 {
00269 ASSERT( pnOffset != NULL && pnLength != NULL );
00270
00271 if ( m_pSource->m_bCloseConn ) return;
00272
00273 nChunk = min( nChunk, (QWORD)Settings.Downloads.ChunkSize );
00274
00275 if ( bVerifyLock )
00276 {
00277 if ( QWORD nVerify = m_pDownload->GetVerifyLength() )
00278 {
00279 nVerify = nVerify * 3 / 2;
00280 nChunk = max( nChunk, nVerify );
00281 }
00282
00283 if ( Settings.Downloads.ChunkStrap > 0 && m_nDownloaded == 0 )
00284 {
00285 nChunk = Settings.Downloads.ChunkStrap;
00286 }
00287 }
00288
00289 if ( nChunk == 0 || *pnLength <= nChunk ) return;
00290
00291 if ( m_pDownload->GetVolumeComplete() == 0 || *pnOffset == 0 )
00292 {
00293 *pnLength = nChunk;
00294 }
00295 else if ( m_bWantBackwards )
00296 {
00297 *pnOffset = *pnOffset + *pnLength - nChunk;
00298 *pnLength = nChunk;
00299 }
00300 else
00301 {
00302 QWORD nCount = *pnLength / nChunk;
00303 if ( *pnLength % nChunk ) nCount++;
00304 nCount = rand() % nCount;
00305
00306 QWORD nStart = *pnOffset + nChunk * nCount;
00307 *pnLength = min( nChunk, *pnOffset + *pnLength - nStart );
00308 *pnOffset = nStart;
00309 }
00310 }