?? downloadpub.cpp
字號:
TRY
{
m_file.Write ( data, size );
}
CATCH( CFileException, e )
{
e->Delete ();
bRet = FALSE;
}
END_CATCH
if ( !bRet )
{
Log ( L_WARNING, "Write data to local file [%s] failed", m_file.GetFileName() );
}
else
{
nDownloadedSize = Get_DownloadedSize();
// TRACE ( "對象.%d, 保存 %d(0x%08x) 字節,偏移 %d(0x%08x) 字節, 共 %d(0x%08x) 字節\n",
// m_nIndex, size, size, m_nWillDownloadStartPos+nDownloadedSize, m_nWillDownloadStartPos+nDownloadedSize,
// nDownloadedSize + size, nDownloadedSize + size );
nDownloadedSize += size;
Set_DownloadedSize ( nDownloadedSize );
if ( m_Proc_SaveDownloadInfo )
m_Proc_SaveDownloadInfo ( m_nIndex, nDownloadedSize, size, m_wSaveDownloadInfo_Param );
}
if ( !bRet ) return -1;
return nDownloadedSize;
}
BOOL CDownloadPub::GetRemoteSiteInfo()
{
return TRUE;
}
CString CDownloadPub::GetRemoteFileName()
{
int nPos = m_csObject.ReverseFind ( '/' );
if ( nPos <= 0 ) return m_csObject;
return m_csObject.Mid ( nPos+1 );
}
const char* g_szBase64TAB = _T( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );
// BASE64編碼
int Base64Encode(LPCTSTR lpszEncoding, CString &strEncoded)
{
UINT m_nBase64Mask[]= { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
int nDigit;
int nNumBits = 6;
int nIndex = 0;
int nInputSize;
strEncoded = _T( "" );
if( lpszEncoding == NULL )
return 0;
if( ( nInputSize = lstrlen(lpszEncoding) ) == 0 )
return 0;
int nBitsRemaining = 0;
long lBitsStorage =0;
long lScratch =0;
int nBits;
UCHAR c;
while( nNumBits > 0 )
{
while( ( nBitsRemaining < nNumBits ) && ( nIndex < nInputSize ) )
{
c = lpszEncoding[ nIndex++ ];
lBitsStorage <<= 8;
lBitsStorage |= (c & 0xff);
nBitsRemaining += 8;
}
if( nBitsRemaining < nNumBits )
{
lScratch = lBitsStorage << ( nNumBits - nBitsRemaining );
nBits = nBitsRemaining;
nBitsRemaining = 0;
}
else
{
lScratch = lBitsStorage >> ( nBitsRemaining - nNumBits );
nBits = nNumBits;
nBitsRemaining -= nNumBits;
}
nDigit = (int)(lScratch & m_nBase64Mask[nNumBits]);
nNumBits = nBits;
if( nNumBits <=0 )
break;
strEncoded += g_szBase64TAB[ nDigit ];
}
// Pad with '=' as per RFC 1521
while( strEncoded.GetLength() % 4 != 0 )
strEncoded += '=';
return strEncoded.GetLength();
}
// STATIC BASE64解碼
int Base64Decode(LPCTSTR lpszDecoding, CString &strDecoded)
{
int nIndex =0;
int nDigit;
int nDecode[ 256 ];
int nSize;
int nNumBits = 6;
if( lpszDecoding == NULL )
return 0;
if( ( nSize = lstrlen(lpszDecoding) ) == 0 )
return 0;
// Build Decode Table
for( int i = 0; i < 256; i++ )
nDecode[i] = -2; // Illegal digit
for( i=0; i < 64; i++ )
{
nDecode[ g_szBase64TAB[ i ] ] = i;
nDecode[ '=' ] = -1;
}
// Clear the output buffer
strDecoded = _T("");
long lBitsStorage =0;
int nBitsRemaining = 0;
int nScratch = 0;
UCHAR c;
// Decode the Input
for( nIndex = 0, i = 0; nIndex < nSize; nIndex++ )
{
c = lpszDecoding[ nIndex ];
// 忽略所有不合法的字符
if( c> 0x7F)
continue;
nDigit = nDecode[c];
if( nDigit >= 0 )
{
lBitsStorage = (lBitsStorage << nNumBits) | (nDigit & 0x3F);
nBitsRemaining += nNumBits;
while( nBitsRemaining > 7 )
{
nScratch = lBitsStorage >> (nBitsRemaining - 8);
strDecoded += (nScratch & 0xFF);
i++;
nBitsRemaining -= 8;
}
}
}
return strDecoded.GetLength();
}
//
// 從URL里面拆分出Server、Object、協議類型等信息,其中 Object 里的值是區分大小寫的,否則有些網站可能會下載不了
//
BOOL ParseURL(LPCTSTR lpszURL, CString &strServer, CString &strObject,USHORT& nPort, CString &csProtocolType)
{
if ( !lpszURL || strlen(lpszURL) < 1 ) return FALSE;
CString csURL_Lower(lpszURL);
csURL_Lower.TrimLeft();
csURL_Lower.TrimRight();
csURL_Lower.Replace ( "\\", "/" );
CString csURL = csURL_Lower;
csURL_Lower.MakeLower ();
// 清除數據
strServer = _T("");
strObject = _T("");
nPort = 0;
int nPos = csURL_Lower.Find("://");
if( nPos == -1 )
{
csURL_Lower.Insert ( 0, "http://" );
csURL.Insert ( 0, "http://" );
nPos = 4;
}
csProtocolType = csURL_Lower.Left ( nPos );
csURL_Lower = csURL_Lower.Mid( csProtocolType.GetLength()+3 );
csURL = csURL.Mid( csProtocolType.GetLength()+3 );
nPos = csURL_Lower.Find('/');
if ( nPos == -1 )
return FALSE;
strObject = csURL.Mid(nPos);
CString csServerAndPort = csURL_Lower.Left(nPos);
// 查找是否有端口號,站點服務器域名一般用小寫
nPos = csServerAndPort.Find(":");
if( nPos == -1 )
{
strServer = csServerAndPort;
nPort = DEFAULT_HTTP_PORT;
if ( csProtocolType == "ftp" )
nPort = DEFAULT_FTP_PORT;
}
else
{
strServer = csServerAndPort.Left( nPos );
csServerAndPort = csServerAndPort.Mid( nPos+1 );
nPort = (USHORT)_ttoi((LPCTSTR)csServerAndPort);
}
return TRUE;
}
void CDownloadPub::Set_DownloadedSize(int nDownloadedSize)
{
m_CSFor_DownloadedSize.Lock ();
m_nDownloadedSize = nDownloadedSize;
m_CSFor_DownloadedSize.Unlock ();
DownloadNotify ( m_nIndex, NOTIFY_TYPE_THREAD_DOWNLOADED_SIZE, (LPVOID)nDownloadedSize, m_pDownloadMTR );
}
int CDownloadPub::Get_DownloadedSize()
{
int nDownloadedSize = 0;
m_CSFor_DownloadedSize.Lock ();
nDownloadedSize = m_nDownloadedSize;
m_CSFor_DownloadedSize.Unlock ();
return nDownloadedSize;
}
void CDownloadPub::Set_TempSaveBytes(int nTempSaveBytes)
{
m_CSFor_TempSaveBytes.Lock ();
m_nTempSaveBytes = nTempSaveBytes;
m_CSFor_TempSaveBytes.Unlock ();
}
int CDownloadPub::Get_TempSaveBytes()
{
int nTempSaveBytes = 0;
m_CSFor_TempSaveBytes.Lock ();
nTempSaveBytes = m_nTempSaveBytes;
m_CSFor_TempSaveBytes.Unlock ();
return nTempSaveBytes;
}
void CDownloadPub::Set_WillDownloadSize(int nWillDownloadSize)
{
m_CSFor_WillDownloadSize.Lock ();
m_nWillDownloadSize = nWillDownloadSize;
m_CSFor_WillDownloadSize.Unlock ();
DownloadNotify ( m_nIndex, NOTIFY_TYPE_WILL_DOWNLOAD_SIZE, (LPVOID)m_nWillDownloadSize, m_pDownloadMTR );
}
int CDownloadPub::Get_WillDownloadSize()
{
int nWillDownloadSize = 0;
m_CSFor_WillDownloadSize.Lock ();
nWillDownloadSize = m_nWillDownloadSize;
m_CSFor_WillDownloadSize.Unlock ();
return nWillDownloadSize;
}
BOOL CDownloadPub::SetSaveFileName(LPCTSTR lpszSaveFileName)
{
if ( !lpszSaveFileName ) return FALSE;
m_csSaveFileName = lpszSaveFileName;
if ( m_csSaveFileName.IsEmpty() )
return FALSE;
return TRUE;
}
//
// 獲取尚未下載的字節數,寫到文件中的和臨時緩沖里的都算是已經下載的
//
int CDownloadPub::GetUndownloadBytes()
{
// 總共需要下載的字節數減去已經下載的字節數
return Get_WillDownloadSize () - ( Get_DownloadedSize () + Get_TempSaveBytes () );
}
BOOL CDownloadPub::OpenFileForSave()
{
ASSERT ( !m_csSaveFileName.IsEmpty() );
// 打開本地文件
if ( HANDLE_IS_VALID ( m_file.m_hFile ) )
{
m_file.Close ();
}
BOOL bRet = FALSE;
TRY
{
if ( m_file.Open ( m_csSaveFileName, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::typeBinary|CFile::shareDenyNone ) )
{
int nWillDownloadStartPos = Get_WillDownloadStartPos ();
nWillDownloadStartPos += Get_DownloadedSize ();
if ( m_file.Seek ( nWillDownloadStartPos, CFile::begin ) == nWillDownloadStartPos )
bRet = TRUE;
}
}
CATCH( CFileException, e )
{
e->Delete ();
bRet = FALSE;
}
END_CATCH
if ( !bRet )
{
Log ( L_WARNING, "Open file [%s] failed. %s", m_csSaveFileName, ::hwFormatMessage ( GetLastError() ) );
}
return bRet;
}
void CDownloadPub::Clear_Thread_Handle()
{
CLOSE_HANDLE ( m_hThread );
}
// 消息通知的回調函數
FUNC_DownloadNotify f_Proc_DownloadNotify = NULL;
WPARAM f_wDownloadNotify_Param = NULL;
//
// 設置通知回調函數
//
void Set_DownloadNotify_Callback ( FUNC_DownloadNotify Proc_DownloadNotify, WPARAM wParam )
{
f_Proc_DownloadNotify = Proc_DownloadNotify;
f_wDownloadNotify_Param = wParam;
}
void DownloadNotify ( int nIndex, UINT nNotityType, LPVOID lpNotifyData, LPVOID pDownloadMTR )
{
ASSERT ( pDownloadMTR );
t_DownloadNotifyPara DownloadNotifyPara = {0};
DownloadNotifyPara.nIndex = nIndex;
DownloadNotifyPara.nNotityType = nNotityType;
DownloadNotifyPara.lpNotifyData = lpNotifyData;
DownloadNotifyPara.pDownloadMTR = pDownloadMTR;
if ( f_Proc_DownloadNotify )
f_Proc_DownloadNotify ( &DownloadNotifyPara, f_wDownloadNotify_Param );
}
//
// 獲取下載對象的文件名(帶擴展名的)
//
CString CDownloadPub::GetDownloadObjectFileName(CString *pcsExtensionName)
{
ASSERT ( !m_csObject.IsEmpty() );
CString csOnlyPath, csOnlyFileName, csExtensionName;
if ( !PartPathAndFileAndExtensionName ( m_csObject, &csOnlyPath, &csOnlyFileName, &csExtensionName ) )
return "";
if ( pcsExtensionName ) *pcsExtensionName = csExtensionName;
if ( !csExtensionName.IsEmpty() )
{
csOnlyFileName += ".";
csOnlyFileName += csExtensionName;
}
return csOnlyFileName;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -