diff options
Diffstat (limited to 'Src/omBrowser/cacheDownloader.cpp')
-rw-r--r-- | Src/omBrowser/cacheDownloader.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/Src/omBrowser/cacheDownloader.cpp b/Src/omBrowser/cacheDownloader.cpp new file mode 100644 index 00000000..44f3af70 --- /dev/null +++ b/Src/omBrowser/cacheDownloader.cpp @@ -0,0 +1,274 @@ +#include "main.h" + +#include "./cacheDownloader.h" +#include "./cacheRecord.h" +#include "./ifc_wasabihelper.h" + +#include "..\Components\wac_network\wac_network_http_receiver_api.h" + +#include <strsafe.h> + +CacheDownloader::CacheDownloader(CacheRecord *record, BOOL fEnableCompression) + : ref(1), manager(NULL), cookie(NULL), owner(record), state(stateReady), enableCompression(fEnableCompression) +{ + InitializeCriticalSection(&lock); +} + +CacheDownloader::~CacheDownloader() +{ + EnterCriticalSection( &lock ); + + if ( manager != NULL ) + { + if ( NULL != cookie ) + { + Abort(); + } + + ifc_wasabihelper *wasabi; + if ( SUCCEEDED( Plugin_GetWasabiHelper( &wasabi ) ) ) + { + wasabi->ReleaseWasabiInterface( &DownloadManagerGUID, (void **)&manager ); + wasabi->Release(); + } + manager = NULL; + } + + LeaveCriticalSection( &lock ); + DeleteCriticalSection( &lock ); +} + +HRESULT CacheDownloader::CreateInstance(CacheRecord *record, LPCWSTR pszAddress, BOOL fEnableCompression, CacheDownloader **instance) +{ + + if (NULL == instance) return E_POINTER; + *instance = NULL; + + if (NULL == record || NULL == pszAddress || L'\0' == *pszAddress) + return E_INVALIDARG; + + HRESULT hr; + + *instance = new CacheDownloader(record, fEnableCompression); + if (NULL == *instance) + { + hr = E_OUTOFMEMORY; + } + else + { + hr = (*instance)->Start(pszAddress); + if (FAILED(hr)) + { + (*instance)->Release(); + *instance = NULL; + } + } + + return hr; + +} + +size_t CacheDownloader::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t CacheDownloader::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int CacheDownloader::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + *object = NULL; + return E_NOINTERFACE; + +} + +HRESULT CacheDownloader::Start(LPCWSTR pszAddress) +{ + HRESULT hr = S_OK; + + LPSTR address = Plugin_WideCharToMultiByte(CP_ACP, 0, pszAddress, -1, NULL, NULL); + if (NULL == address) return E_OUTOFMEMORY; + + + EnterCriticalSection(&lock); + state = stateInitializing; + LeaveCriticalSection(&lock); + + if ( manager == NULL ) + { + ifc_wasabihelper *wasabi; + hr = Plugin_GetWasabiHelper(&wasabi); + if (SUCCEEDED(hr)) + { + hr = wasabi->QueryWasabiInterface(&DownloadManagerGUID, (void**)&manager); + wasabi->Release(); + } + } + + if (SUCCEEDED(hr)) + { + cookie = manager->DownloadEx(address, this, api_downloadManager::DOWNLOADEX_TEMPFILE); + if (NULL == cookie) + { + hr = E_FAIL; + } + } + + if (FAILED(hr)) + { + EnterCriticalSection(&lock); + state = stateCompleted; + LeaveCriticalSection(&lock); + } + + Plugin_FreeAnsiString(address); + return hr; +} + +HRESULT CacheDownloader::Abort() +{ + HRESULT hr; + EnterCriticalSection(&lock); + + if (NULL == manager || NULL == cookie) + { + hr = E_UNEXPECTED; + } + else if (stateCompleted == state) + { + hr = S_FALSE; + } + else + { + state = stateAborting; + manager->CancelDownload(cookie); + hr = S_OK; + } + + LeaveCriticalSection(&lock); + return hr; +} + +UINT CacheDownloader::GetState() +{ + return state; +} + +HRESULT CacheDownloader::SetOwner(CacheRecord *record) +{ + owner = record; + return S_OK; +} + +HRESULT CacheDownloader::DownloadCompleted(INT errorCode) +{ + AddRef(); + EnterCriticalSection(&lock); + + state = stateCompleted; + + if (NULL != owner) + { + LPCWSTR pszFile = (api_downloadManager::TICK_SUCCESS == errorCode) ? manager->GetLocation(cookie) : NULL; + + owner->DownloadCompleted(pszFile, errorCode); + owner = NULL; + } + + manager->ReleaseDownload(cookie); + cookie = NULL; + + ifc_wasabihelper *wasabi; + if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi))) + { + wasabi->ReleaseWasabiInterface(&DownloadManagerGUID, (void**)&manager); + wasabi->Release(); + manager = NULL; + } + + LeaveCriticalSection(&lock); + + Release(); + return S_OK; +} + +void CacheDownloader::OnInit(DownloadToken token) +{ + EnterCriticalSection(&lock); + + cookie = token; + if (NULL != cookie) + { + manager->RetainDownload(cookie); + } + + state = stateConnecting; + + if (FALSE != enableCompression) + { + api_httpreceiver *receiver = manager->GetReceiver(token); + if (NULL != receiver) + receiver->AllowCompression(); + } + + LeaveCriticalSection(&lock); +} + +void CacheDownloader::OnFinish(DownloadToken token) +{ + DownloadCompleted(api_downloadManager::TICK_SUCCESS); +} + +void CacheDownloader::OnError(DownloadToken token, int errorCode) +{ + DownloadCompleted(errorCode); +} + +void CacheDownloader::OnCancel(DownloadToken token) +{ + DownloadCompleted(api_downloadManager::TICK_NODATA); +} + +void CacheDownloader::OnTick(DownloadToken token) +{ + EnterCriticalSection(&lock); + + if (stateConnecting == state) + state = stateReceiving; + LeaveCriticalSection(&lock); + +} + +void CacheDownloader::OnConnect(DownloadToken dlToken) +{ + EnterCriticalSection(&lock); + state = stateReceiving; + LeaveCriticalSection(&lock); +} + + +#define CBCLASS CacheDownloader +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +VCB(IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish) +VCB(IFC_DOWNLOADMANAGERCALLBACK_ONTICK, OnTick) +VCB(IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError) +VCB(IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel) +VCB(IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, OnConnect) +VCB(IFC_DOWNLOADMANAGERCALLBACK_ONINIT, OnInit) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file |