182 lines
6.2 KiB
C++
182 lines
6.2 KiB
C++
#ifndef __ProgressInfo_h__
|
|
#define __ProgressInfo_h__
|
|
|
|
#include <windows.h>
|
|
#include "stdstring.h"
|
|
#include "httpfilepost.h"
|
|
|
|
enum TRANSFER_STATUS
|
|
{
|
|
TRANSFER_FATAL_ERROR = -1, // transfer is aborting due to unrecoverable error
|
|
TRANSFER_OK, // currently not used
|
|
TRANSFER_SKIPPING_FILE, // file transfer failed, non-fatal, continuing with remaining files
|
|
TRANSFER_SESSION_INITIATE, // beginning batch file transfer (only agragate vars are valid)
|
|
TRANSFER_FILE_INITATE, // starting the transfer of a file (current file vars are now valid)
|
|
TRANSFER_FILE_TRANSFERING, // all vars reflect current progress
|
|
TRANSFER_FILE_COMPLETE, // file has completed transfering
|
|
TRANSFER_SESSION_COMPLETE, // session compelete, last callback that will be sent unless
|
|
// there is an unrecoverable error in which case
|
|
// TRANSFER_FATAL_ERROR will be the final message
|
|
};
|
|
#include <MMSystem.h> // Windows Multimedia Support (for timeGetTime())
|
|
|
|
class CProgressInfo;
|
|
class CWebCabPublisher;
|
|
typedef UINT (*CS_PROGRESS_PROC)(CProgressInfo*);
|
|
|
|
#define STATUS_BUFFSIZE 1024
|
|
|
|
class CProgressInfo
|
|
{
|
|
public:
|
|
// while the upload/download thread is updating the variables,
|
|
// critsec will be locked. users of this class must lock
|
|
// this critsec before accessing the variables, or they
|
|
// may get only partially updated values
|
|
CRITICAL_SECTION critsec;
|
|
|
|
DWORD dwStatusCallback; // status from WinInet
|
|
char szStatusString[STATUS_BUFFSIZE]; //buffer for status message
|
|
|
|
TRANSFER_STATUS dwStatus;
|
|
DWORD dwErrorCount; // count of errors encountered this transfer
|
|
CStdString strFilename; // full path of the currently transfering file
|
|
CStdString strTitle; // friendly (user specified) title of the file
|
|
|
|
DWORD dwTotalFiles; // total count of files to transfer
|
|
DWORD dwDoneFiles; // count of files done
|
|
|
|
DWORD dwTotalBytes; // total bytes to transfer
|
|
DWORD dwTotalDone; // bytes transfered
|
|
|
|
DWORD dwCurrentBytes; // total bytes to transfer for this file
|
|
DWORD dwCurrentDone; // bytes transfered for this file
|
|
|
|
DWORD dwStartMS; // time started (milliseconds)
|
|
|
|
DWORD dwTransferRate; // (estimated) transfer rate
|
|
|
|
time_t timeElapsed; // time elapsed
|
|
time_t timeRemaining; // (estimated) time remaining
|
|
|
|
DWORD dwOverallPercent; // overall percent done
|
|
DWORD dwCurrentPercent; // percent done for this file
|
|
|
|
// these two are used for updating a progress ctrl
|
|
DWORD dwOverallPos; // (estimated) overall progress (range 0-ffffffff)
|
|
DWORD dwCurrentPos; // (estimated) current progress (range 0-ffffffff)
|
|
|
|
CS_PROGRESS_PROC pfnProgress; // pointer to callback function
|
|
LPARAM lParam; // lParam (caller defined value passed back to caller)
|
|
|
|
// caller returns 0 to continue, non-zero to abort (value will be reason for abort)
|
|
// if caller didn't specify a callback, then assume continue (0)
|
|
void NotifyCaller()
|
|
{
|
|
if(pfnProgress && (*pfnProgress)(this))
|
|
{
|
|
ThrowUploaderException(0);
|
|
}
|
|
}
|
|
|
|
|
|
void StartSession(DWORD dwCountFiles, DWORD dwCountBytes)
|
|
{
|
|
InitializeCriticalSection(&critsec);
|
|
EnterCriticalSection(&critsec);
|
|
{ // critical section
|
|
dwStatus = TRANSFER_SESSION_INITIATE;
|
|
dwErrorCount = 0;
|
|
strFilename = "";
|
|
dwTotalFiles = dwCountFiles;
|
|
dwDoneFiles = 0;
|
|
dwTotalDone = 0;
|
|
dwTotalBytes = dwCountBytes;
|
|
dwTotalDone = 0;
|
|
dwCurrentBytes = 0;
|
|
dwCurrentDone = 0;
|
|
dwStartMS = timeGetTime();
|
|
dwTransferRate = 0;
|
|
timeElapsed = 0;
|
|
timeRemaining = 0;
|
|
dwOverallPercent = 0;
|
|
dwCurrentPercent = 0;
|
|
dwOverallPos = 0;
|
|
dwCurrentPos = 0;
|
|
}
|
|
LeaveCriticalSection(&critsec);
|
|
NotifyCaller();
|
|
}
|
|
|
|
void EndSession(UINT uSuccess)
|
|
{
|
|
EnterCriticalSection(&critsec);
|
|
{
|
|
dwStatus = uSuccess ? TRANSFER_SESSION_COMPLETE : TRANSFER_FATAL_ERROR;
|
|
}
|
|
LeaveCriticalSection(&critsec);
|
|
|
|
//DeleteCriticalSection(&critsec);
|
|
|
|
NotifyCaller();
|
|
}
|
|
|
|
void StartFile(const CStdString& name, const CStdString& title, DWORD size)
|
|
{
|
|
EnterCriticalSection(&critsec);
|
|
{ // critical section
|
|
dwStatus = TRANSFER_FILE_INITATE;
|
|
strFilename = name;
|
|
strTitle = title;
|
|
dwCurrentBytes = size;
|
|
dwCurrentDone = 0;
|
|
dwCurrentPercent = 0;
|
|
dwCurrentPos = 0;
|
|
}
|
|
LeaveCriticalSection(&critsec);
|
|
|
|
NotifyCaller();
|
|
}
|
|
|
|
void UpdateProgress(DWORD dwBytesTransfered)
|
|
{
|
|
EnterCriticalSection(&critsec);
|
|
{ // critical section
|
|
dwStatus = TRANSFER_FILE_TRANSFERING;
|
|
dwTotalDone += dwBytesTransfered;
|
|
dwCurrentDone += dwBytesTransfered;
|
|
|
|
dwOverallPos = dwTotalBytes ? MulDiv(dwTotalDone, 0xFFFF, dwTotalBytes) : 0;
|
|
dwCurrentPos = dwCurrentBytes ? MulDiv(dwCurrentDone, 0xFFFF, dwCurrentBytes) : 0;
|
|
|
|
dwOverallPercent = (dwOverallPos * 100) / 0xFFFF;
|
|
dwCurrentPercent = (dwCurrentPos * 100) / 0xFFFF;
|
|
|
|
DWORD dwElapsedMS = timeGetTime() - dwStartMS;
|
|
dwTransferRate = MulDiv(dwTotalDone, 1000, dwElapsedMS);
|
|
|
|
DWORD dwTimeRemaining = MulDiv(dwElapsedMS, dwTotalBytes, dwTotalDone) - dwElapsedMS;
|
|
timeRemaining = dwTimeRemaining / 1000;
|
|
timeElapsed = dwElapsedMS / 1000;
|
|
}
|
|
LeaveCriticalSection(&critsec);
|
|
|
|
NotifyCaller();
|
|
}
|
|
|
|
|
|
void EndFile()
|
|
{
|
|
EnterCriticalSection(&critsec);
|
|
{ // critical section
|
|
dwStatus = TRANSFER_FILE_COMPLETE;
|
|
dwDoneFiles++;
|
|
}
|
|
LeaveCriticalSection(&critsec);
|
|
|
|
NotifyCaller();
|
|
}
|
|
};
|
|
|
|
|
|
#endif //__ProgressInfo_h__
|