Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@ -0,0 +1,128 @@
#include "BackgroundDownloader.h"
#include "../../Components\wac_network/wac_network_http_receiver_api.h"
#include "api__wac_downloadManager.h"
#include "api/service/waservicefactory.h"
#include "../nu/AutoChar.h"
#include <strsafe.h>
#define HTTP_BUFFER_SIZE 32768
// {C0A565DC-0CFE-405a-A27C-468B0C8A3A5C}
static const GUID internetConfigGroupGUID =
{ 0xc0a565dc, 0xcfe, 0x405a, { 0xa2, 0x7c, 0x46, 0x8b, 0xc, 0x8a, 0x3a, 0x5c } };
static void SetUserAgent( api_httpreceiver *http )
{
char agent[ 256 ];
StringCchPrintfA( agent, 256, "User-Agent: %S/%S", WASABI_API_APP->main_getAppName(), WASABI_API_APP->main_getVersionNumString() );
http->addheader( agent );
}
static int FeedHTTP( api_httpreceiver *http, Downloader::DownloadCallback &callback, void *userData, bool *noData )
{
char downloadedData[ HTTP_BUFFER_SIZE ];
int result = 0;
int downloadSize = http->get_bytes( downloadedData, HTTP_BUFFER_SIZE );
if ( downloadSize )
{
result = callback( userData, downloadedData, downloadSize );
*noData = false;
}
else
*noData = true;
return result;
}
static void RunDownload( api_httpreceiver *http, Downloader::DownloadCallback &callback, void *userData )
{
int ret;
bool noData;
do
{
Sleep( 50 );
ret = http->run();
if ( FeedHTTP( http, callback, userData, &noData ) != 0 )
return;
} while ( ret == HTTPRECEIVER_RUN_OK );
// finish off the data
do
{
if ( FeedHTTP( http, callback, userData, &noData ) != 0 )
return;
} while ( !noData );
}
bool Downloader::Download( const char *url, Downloader::DownloadCallback &callback, void *userdata, uint64_t startPosition )
{
api_httpreceiver *http = 0;
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid( httpreceiverGUID );
if ( sf )
http = (api_httpreceiver *)sf->getInterface();
if ( !http )
return false;
int use_proxy = 1;
bool proxy80 = AGAVE_API_CONFIG->GetBool( internetConfigGroupGUID, L"proxy80", false );
if ( proxy80 && strstr( url, ":" ) && ( !strstr( url, ":80/" ) && strstr( url, ":80" ) != ( url + strlen( url ) - 3 ) ) )
use_proxy = 0;
const wchar_t *proxy = use_proxy ? AGAVE_API_CONFIG->GetString( internetConfigGroupGUID, L"proxy", 0 ) : 0;
http->AllowCompression();
http->open( API_DNS_AUTODNS, HTTP_BUFFER_SIZE, ( proxy && proxy[ 0 ] ) ? (const char *)AutoChar( proxy ) : NULL );
if ( startPosition > 0 )
{
char temp[ 128 ];
StringCchPrintfA( temp, 128, "Range: bytes=%d-", startPosition );
http->addheader( temp );
}
SetUserAgent( http );
http->connect( url );
int ret;
do
{
Sleep( 10 );
ret = http->run();
if ( ret == -1 ) // connection failed
break;
// ---- check our reply code ----
int replycode = http->getreplycode();
switch ( replycode )
{
case 0:
case 100:
break;
case 200:
{
RunDownload( http, callback, userdata );
sf->releaseInterface( http );
return true;
}
break;
default:
sf->releaseInterface( http );
return false;
}
} while ( ret == HTTPRECEIVER_RUN_OK );
sf->releaseInterface( http );
return false;
}

View File

@ -0,0 +1,14 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_BACKGROUND_DOWNLOADER_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_BACKGROUND_DOWNLOADER_H
#include "bfc/platform/types.h"
class Downloader
{
public:
typedef int ( *DownloadCallback )( void *userdata, void *buffer, size_t bufferSize );
bool Download( const char *url, DownloadCallback &callback, void *userdata, uint64_t startPosition = 0 );
};
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_BACKGROUND_DOWNLOADER_H

View File

@ -0,0 +1,71 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_DOWNLOADCALLBACKT_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_DOWNLOADCALLBACKT_H
#include "wac_downloadManager_api.h"
#define WIN32_LEAN_AND_MEAN
//#include <windows.h> // for InterlockedIncrememt/Decrement
#include <atomic>
/* DownloadCallbackT is reference counted for you. if you don't like that, inherit from ifc_downloadManagerCallback yourself */
template <class T>
class DownloadCallbackT : public ifc_downloadManagerCallback
{
public:
size_t AddRef()
{
return _ref_count.fetch_add( 1 );
}
size_t Release()
{
if (_ref_count.load() == 0 )
return _ref_count.load();
LONG l_ref_count = _ref_count.fetch_sub( 1 );
if ( !l_ref_count )
delete( static_cast<T *>( this ) );
return l_ref_count;
}
protected:
DownloadCallbackT() {}
void OnFinish( DownloadToken token ) { Release(); }
void OnTick( DownloadToken token ) {}
void OnError( DownloadToken token, int error ) { Release(); }
void OnCancel( DownloadToken token ) { Release(); }
void OnConnect( DownloadToken token ) {}
void OnInit( DownloadToken token ) {}
void OnData( DownloadToken token, void *data, size_t datalen ) {}
int GetSource(wchar_t *source, size_t source_cch) { return 1;}
int GetTitle(wchar_t *title, size_t title_cch) { return 1;}
int GetLocation(wchar_t *location, size_t location_cch) { return 1;}
#define CBCLASS T
#define CBCLASST DownloadCallbackT<T>
START_DISPATCH_INLINE;
CBT(ADDREF, AddRef);
CBT(RELEASE, Release);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONTICK, OnTick);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, OnConnect);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONINIT, OnInit);
VCBT(IFC_DOWNLOADMANAGERCALLBACK_ONDATA, OnData);
CBT( IFC_DOWNLOADMANAGERCALLBACK_GETSOURCE, GetSource);
CBT( IFC_DOWNLOADMANAGERCALLBACK_GETTITLE, GetTitle);
CBT( IFC_DOWNLOADMANAGERCALLBACK_GETLOCATION, GetLocation);
END_DISPATCH;
#undef CBCLASS
#undef CBCLASST
private:
std::atomic<std::size_t> _ref_count;
};
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_DOWNLOADCALLBACKT_H

View File

@ -0,0 +1,40 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_API_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_API_H
#include "api/service/api_service.h"
#include "api/application/api_application.h"
#define WASABI_API_APP applicationApi
#include "../Agave/Config/api_config.h"
#include "../nu/threadpool/api_threadpool.h"
extern api_threadpool *threadPoolApi;
#define WASABI_API_THREADPOOL threadPoolApi
template <class api_T>
static void ServiceBuild( api_T *&api_t, GUID factoryGUID_t )
{
if ( WASABI_API_SVC )
{
waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid( factoryGUID_t );
if ( factory )
api_t = reinterpret_cast<api_T *>( factory->getInterface() );
}
}
template <class api_T>
static void ServiceRelease( api_T *api_t, GUID factoryGUID_t )
{
if ( WASABI_API_SVC && api_t )
{
waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid( factoryGUID_t );
if ( factory )
factory->releaseInterface( api_t );
}
api_t = NULL;
}
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_API_H

View File

@ -0,0 +1,69 @@
#include "main.h"
//#include "wac_download_http_receiver_factory.h"
#include "wac_downloadManager.h"
#include "bfc/platform/export.h"
static Singleton2<api_downloadManager, DownloadManager> dlMgrFactory;
static DownloadManager dlMgr;
//static wa::Components::WAC_DownloadsFactory _wac_download_factory;
static wa::Components::WAC_DownloadManager_Component _wac_downloadManager_Component;
//wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory _wac_downloadManager_http_receiver_service;
api_service *WASABI_API_SVC = 0;
api_application *WASABI_API_APP = 0;
api_config *AGAVE_API_CONFIG = 0;
api_threadpool *WASABI_API_THREADPOOL = 0;
void wa::Components::WAC_DownloadManager_Component::RegisterServices( api_service *p_service )
{
WASABI_API_SVC = p_service;
ServiceBuild( WASABI_API_APP, applicationApiServiceGuid );
ServiceBuild( AGAVE_API_CONFIG, AgaveConfigGUID );
ServiceBuild( WASABI_API_THREADPOOL, ThreadPoolGUID );
dlMgrFactory.Register( &dlMgr );
//WASABI_API_SVC->service_register( &_wac_downloadManager_http_receiver_service );
}
void wa::Components::WAC_DownloadManager_Component::DeregisterServices( api_service *p_service )
{
Q_UNUSED( p_service )
ServiceRelease( WASABI_API_APP, applicationApiServiceGuid );
ServiceRelease( AGAVE_API_CONFIG, AgaveConfigGUID );
dlMgr.Kill();
dlMgrFactory.Deregister();
ServiceRelease( WASABI_API_THREADPOOL, ThreadPoolGUID );
//p_service->service_deregister( &_wac_downloadManager_http_receiver_service );
}
extern "C" WAC_DOWNLOAD_MANAGER_EXPORT ifc_wa5component * GetWinamp5SystemComponent()
{
return &_wac_downloadManager_Component;
}
#ifdef CBCLASS
#undef CBCLASS
#endif
#define CBCLASS wa::Components::WAC_DownloadManager_Component
START_DISPATCH;
VCB( API_WA5COMPONENT_REGISTERSERVICES, RegisterServices )
CB( API_WA5COMPONENT_REGISTERSERVICES_SAFE_MODE, RegisterServicesSafeModeOk )
VCB( API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices )
END_DISPATCH;
#undef CBCLASS

View File

@ -0,0 +1,37 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_MAIN_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_MAIN_H
#include "wac_downloadManager_global.h"
#include "api__wac_downloadManager.h"
//#include "wac_downloadManager.h"
//#include "wac_download_http_receiver.h"
#include "bfc/dispatch.h"
#include "../../Winamp/Singleton.h"
#include "../../Agave/Component/ifc_wa5component.h"
namespace wa
{
namespace Components
{
class WAC_DownloadManager_Component : public ifc_wa5component
{
public:
WAC_DownloadManager_Component() {}
void RegisterServices( api_service *service );
int RegisterServicesSafeModeOk() { return 1; }
void DeregisterServices( api_service *service );
protected:
RECVS_DISPATCH;
};
}
}
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_MAIN_H

View File

@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by wac_network.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,1,0,0
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp 5.x System Component"
VALUE "FileVersion", STR_WINAMP_PRODUCTVER
VALUE "InternalName", "wac_downloadManager.w5s"
VALUE "LegalCopyright", "Copyright <20> 2007-2022 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "wac_downloadManager.w5s"
VALUE "ProductName", "Winamp downloadManager Service"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -0,0 +1,872 @@
#include <string.h>
#include <strsafe.h>
#include <iostream>
#include <cstdio>
#include <QtCore/qglobal.h>
#include <QWebEngineProfile>
#include <QtWebEngineWidgets/QtWebEngineWidgets>
#include <QWebEnginePage>
#include <QWebEngineSettings>
#include "api__wac_downloadManager.h"
#include "wac_downloadManager.h"
#include "wac_download_http_receiver_api.h"
#include "..\wac_network\wac_network_http_receiver_api.h"
#include "api/service/waservicefactory.h"
#include "../nu/threadname.h"
#include "../nu/AutoChar.h"
#include "../nu/threadpool/timerhandle.hpp"
#include "..\WAT\WAT.h"
#include "..\Winamp\buildType.h"
static const GUID internetConfigGroupGUID =
{
0xc0a565dc, 0xcfe, 0x405a, { 0xa2, 0x7c, 0x46, 0x8b, 0xc, 0x8a, 0x3a, 0x5c }
};
#define DOWNLOAD_TIMEOUT_MS 60000 // 60 second timeout
#define DOWNLOAD_SLEEP_MS 50
#define DOWNLOAD_BUFFER_SIZE 1310720 // gives a maximum download rate of 25 mb/sec per file
/**********************************************************************************
**********************************************************************************/
/**********************************************************************************
* PUBLIC *
**********************************************************************************/
wa::Components::WAC_DownloadData::WAC_DownloadData( api_wac_download_manager_http_receiver *p_http, const char *p_url, int p_flags, ifc_downloadManagerCallback *p_callback )
{
_http = p_http;
strcpy_s( this->_url, 1024, p_url );
_flags = p_flags;
_callback = p_callback;
if ( _callback )
_callback->AddRef();
_hFile = INVALID_HANDLE_VALUE;
_filepath[ 0 ] = 0;
_fileext = 0;
int download_method = ( api_downloadManager::DOWNLOADEX_MASK_DOWNLOADMETHOD & _flags );
switch ( download_method )
{
case api_downloadManager::DOWNLOADEX_TEMPFILE:
{
wchar_t temppath[ MAX_PATH - 14 ] = { 0 }; // MAX_PATH-14 'cause MSDN said so
GetTempPathW( MAX_PATH - 14, temppath );
GetTempFileNameW( temppath, L"wdl", 0, _filepath );
_hFile = CreateFileW( _filepath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0 );
}
break;
case api_downloadManager::DOWNLOADEX_CALLBACK:
if ( _callback )
_callback->GetLocation( _filepath, MAX_PATH );
break;
}
_source[ 0 ] = 0;
_title[ 0 ] = 0;
if ( _flags & api_downloadManager::DOWNLOADEX_CALLBACK )
{
if ( _callback )
{
_callback->GetSource( _source, 1024 );
_callback->GetTitle( _title, 1024 );
}
}
_connectionStart = _lastDownloadTick = GetTickCount();
_last_status = HTTP_RECEIVER_STATUS_ERROR;
_pending = ( _flags & api_downloadManager::DOWNLOADEX_PENDING ) > 0;
}
wa::Components::WAC_DownloadData::~WAC_DownloadData()
{
ServiceRelease( _http, httpreceiverGUID2 );
_http = NULL;
if ( _fileext )
delete _fileext;
int download_method = ( api_downloadManager::DOWNLOADEX_MASK_DOWNLOADMETHOD & _flags );
if ( download_method == api_downloadManager::DOWNLOADEX_TEMPFILE && _filepath[ 0 ] )
DeleteFileW( _filepath );
if ( _callback )
_callback->Release();
_callback = NULL;
}
void wa::Components::WAC_DownloadData::Retain()
{
this->_refCount.fetch_add( 1 );
}
void wa::Components::WAC_DownloadData::Release()
{
if ( this->_refCount.fetch_sub( 1 ) == 0 )
delete this;
}
void wa::Components::WAC_DownloadData::Close( ifc_downloadManagerCallback **callbackCopy )
{
if ( _hFile != INVALID_HANDLE_VALUE )
CloseHandle( _hFile );
_hFile = INVALID_HANDLE_VALUE;
if ( callbackCopy != NULL )
{
*callbackCopy = _callback;
if ( _callback != NULL )
_callback->AddRef();
}
else if ( _callback != NULL )
{
_callback->Release();
_callback = NULL;
}
// don't want to close http here, because someone might still want to get the headers out of it
}
bool wa::Components::WAC_DownloadData::getExtention()
{
if ( _fileext && *_fileext )
return _fileext;
char l_header_name_content_type[] = "Content-Type";
char *l_content_type = _http->getheader( l_header_name_content_type );
if ( l_content_type && *l_content_type )
{
if ( _CONTENT_TYPES_EXTENSIONS.count( l_content_type ) == 1 )
_fileext = _strdup( _CONTENT_TYPES_EXTENSIONS.find( l_content_type )->second.c_str() );
}
return _fileext;
}
/**********************************************************************************
* PRIVATE *
**********************************************************************************/
/**********************************************************************************
**********************************************************************************/
/**********************************************************************************
* PUBLIC *
**********************************************************************************/
wa::Components::WAC_DownloadManager::WAC_DownloadManager( QObject *parent ) : QNetworkAccessManager( parent )
{
this->setObjectName( "DownloadManagerService" );
this->init();
}
wa::Components::WAC_DownloadManager::~WAC_DownloadManager()
{
disconnect( _connection_authentication_required );
}
DownloadToken wa::Components::WAC_DownloadManager::Download( const char *p_url, ifc_downloadManagerCallback *p_callback )
{
return DownloadEx( p_url, p_callback, api_downloadManager::DOWNLOADEX_TEMPFILE );
}
DownloadToken wa::Components::WAC_DownloadManager::DownloadEx( const char *p_url, ifc_downloadManagerCallback *p_callback, int p_flags )
{
return DownloadToken();
}
/**********************************************************************************
* PRIVATE *
**********************************************************************************/
void wa::Components::WAC_DownloadManager::init()
{
QString l_winamp_user_agent = QString( "%1 Winamp/%2" ).arg( QWebEngineProfile::defaultProfile()->httpUserAgent(), STR_WINAMP_PRODUCTVER ).replace( ",", "." );
QWebEngineProfile::defaultProfile()->setHttpUserAgent( l_winamp_user_agent );
_connection_authentication_required = connect( this, &QNetworkAccessManager::authenticationRequired, this, &wa::Components::WAC_DownloadManager::on_s_authentication_required );
}
QNetworkReply *wa::Components::WAC_DownloadManager::createRequest( Operation p_operation, const QNetworkRequest &p_request, QIODevice *p_outgoing_data )
{
return QNetworkAccessManager::createRequest( p_operation, p_request, p_outgoing_data );
}
/**********************************************************************************
* PRIVATE SLOTS *
**********************************************************************************/
void wa::Components::WAC_DownloadManager::on_s_authentication_required( QNetworkReply *p_reply, QAuthenticator *p_authenticator )
{
Q_UNUSED( p_reply );
Q_UNUSED( p_authenticator );
}
/**********************************************************************************
**********************************************************************************/
DownloadData::DownloadData( api_httpreceiver *p_http, const char *p_url, int p_flags, ifc_downloadManagerCallback *p_callback )
{
flags = p_flags;
http = p_http;
callback = p_callback;
if ( callback )
callback->AddRef();
hFile = INVALID_HANDLE_VALUE;
filepath[ 0 ] = 0;
fileext = 0;
int download_method = ( api_downloadManager::DOWNLOADEX_MASK_DOWNLOADMETHOD & flags );
switch ( download_method )
{
case api_downloadManager::DOWNLOADEX_TEMPFILE:
{
wchar_t temppath[ MAX_PATH - 14 ] = { 0 }; // MAX_PATH-14 'cause MSDN said so
GetTempPathW( MAX_PATH - 14, temppath );
GetTempFileNameW( temppath, L"wdl", 0, filepath );
hFile = CreateFileW( filepath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0 );
}
break;
case api_downloadManager::DOWNLOADEX_CALLBACK:
if ( callback )
callback->GetLocation( filepath, MAX_PATH );
break;
}
strcpy_s( this->url, 1024, p_url );
source[ 0 ] = 0;
title[ 0 ] = 0;
if ( flags & api_downloadManager::DOWNLOADEX_CALLBACK )
{
if ( callback )
{
callback->GetSource( source, 1024 );
callback->GetTitle( title, 1024 );
}
}
connectionStart = lastDownloadTick = GetTickCount();
last_status = HTTPRECEIVER_STATUS_ERROR;
pending = ( flags & api_downloadManager::DOWNLOADEX_PENDING ) > 0;
}
DownloadData::~DownloadData()
{
ServiceRelease( http, httpreceiverGUID );
http = NULL;
if ( fileext )
delete fileext;
int download_method = ( api_downloadManager::DOWNLOADEX_MASK_DOWNLOADMETHOD & flags );
if ( download_method == api_downloadManager::DOWNLOADEX_TEMPFILE && filepath[ 0 ] )
DeleteFileW( filepath );
if ( callback )
callback->Release();
callback = NULL;
}
void DownloadData::Retain()
{
this->_refCount.fetch_add( 1 );
}
void DownloadData::Release()
{
if ( this->_refCount.fetch_sub( 1 ) == 0 )
delete this;
}
void DownloadData::Close( ifc_downloadManagerCallback **callbackCopy )
{
if ( hFile != INVALID_HANDLE_VALUE )
CloseHandle( hFile );
hFile = INVALID_HANDLE_VALUE;
if ( callbackCopy != NULL )
{
*callbackCopy = callback;
if ( callback != NULL )
callback->AddRef();
}
else if ( callback != NULL )
{
callback->Release();
callback = NULL;
}
// don't want to close http here, because someone might still want to get the headers out of it
}
bool DownloadData::getExtention()
{
if ( fileext && *fileext )
return fileext;
char l_header_name_content_type[] = "Content-Type";
char *l_content_type = http->getheader( l_header_name_content_type );
if ( l_content_type && *l_content_type )
{
if ( _CONTENT_TYPES_EXTENSIONS.count( l_content_type ) == 1 )
fileext = _strdup( _CONTENT_TYPES_EXTENSIONS.find( l_content_type )->second.c_str() );
}
return fileext;
}
/**********************************************************************************
**********************************************************************************/
/**********************************************************************************
* PUBLIC *
**********************************************************************************/
DownloadManager::DownloadManager()
{
download_thread = NULL;
killswitch = CreateEvent( NULL, TRUE, FALSE, NULL );
InitializeCriticalSection( &downloadsCS );
}
void DownloadManager::Kill()
{
SetEvent( killswitch );
if ( download_thread )
{
WaitForSingleObject( download_thread, 3000 );
CloseHandle( download_thread );
}
DeleteCriticalSection( &downloadsCS );
CloseHandle( killswitch );
}
static void SetUserAgent( api_httpreceiver *p_http )
{
char agent[ 256 ] = { 0 };
StringCchPrintfA( agent, 256, "User-Agent: %S/%S", WASABI_API_APP->main_getAppName(), WASABI_API_APP->main_getVersionNumString() );
p_http->addheader( agent );
//QString l_winamp_user_agent = QString( "User-Agent: %1 Winamp/%2" ).arg( QWebEngineProfile::defaultProfile()->httpUserAgent(), STR_WINAMP_PRODUCTVER ).replace( ",", "." );
//http->addheader( l_winamp_user_agent.toStdString().c_str() );
}
DownloadToken DownloadManager::Download( const char *url, ifc_downloadManagerCallback *callback )
{
return DownloadEx( url, callback, api_downloadManager::DOWNLOADEX_TEMPFILE );
}
DownloadToken DownloadManager::DownloadEx( const char *url, ifc_downloadManagerCallback *callback, int flags )
{
if ( InitDownloadThread() )
{
api_httpreceiver *http = NULL;
ServiceBuild( http, httpreceiverGUID );
if ( http )
{
DownloadData *downloadData = new DownloadData( http, url, flags, callback );
int use_proxy = 1;
bool proxy80 = AGAVE_API_CONFIG->GetBool( internetConfigGroupGUID, L"proxy80", false );
if ( proxy80 && strstr( url, ":" ) && ( !strstr( url, ":80/" ) && strstr( url, ":80" ) != ( url + strlen( url ) - 3 ) ) )
use_proxy = 0;
const wchar_t *proxy = use_proxy ? AGAVE_API_CONFIG->GetString( internetConfigGroupGUID, L"proxy", 0 ) : 0;
http->open( API_DNS_AUTODNS, DOWNLOAD_BUFFER_SIZE, ( proxy && proxy[ 0 ] ) ? (const char *)AutoChar( proxy ) : NULL );
SetUserAgent( http );
if ( callback )
callback->OnInit( downloadData );
if ( downloadData->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_status : status_callbacks )
l_status->OnInit( downloadData );
}
//only call http->connect when it is not pending download request
if ( !( flags & DOWNLOADEX_PENDING ) )
http->connect( url, 1 );
//http->run(); // let's get this party started
EnterCriticalSection( &downloadsCS );
downloads.push_back( downloadData );
LeaveCriticalSection( &downloadsCS );
return downloadData;
}
}
return 0;
}
void DownloadManager::ResumePendingDownload( DownloadToken p_token )
{
if ( !p_token )
return;
DownloadData *data = (DownloadData *)p_token;
if ( data->pending )
{
data->pending = false;
data->connectionStart = data->lastDownloadTick = GetTickCount();
data->http->connect( data->url );
}
}
void DownloadManager::CancelDownload( DownloadToken p_token )
{
if ( !p_token )
return;
DownloadData *data = (DownloadData *)p_token;
EnterCriticalSection( &downloadsCS );
if ( downloads.end() != std::find( downloads.begin(), downloads.end(), data ) )
{
ifc_downloadManagerCallback *callback;
data->Close( &callback );
//downloads.eraseObject(p_data);
auto it = std::find( downloads.begin(), downloads.end(), data );
if ( it != downloads.end() )
{
downloads.erase( it );
}
LeaveCriticalSection( &downloadsCS );
if ( callback )
{
callback->OnCancel( p_token );
if ( data->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_status : status_callbacks )
l_status->OnCancel( p_token );
}
callback->Release();
}
data->Release();
}
else
LeaveCriticalSection( &downloadsCS );
}
void DownloadManager::RetainDownload( DownloadToken p_token )
{
if ( !p_token )
return;
DownloadData *data = (DownloadData *)p_token;
if ( data )
data->Retain();
}
void DownloadManager::ReleaseDownload( DownloadToken p_token )
{
if ( !p_token )
return;
DownloadData *data = (DownloadData *)p_token;
if ( data )
data->Release();
}
void DownloadManager::RegisterStatusCallback( ifc_downloadManagerCallback *callback )
{
EnterCriticalSection( &downloadsCS );
status_callbacks.push_back( callback );
LeaveCriticalSection( &downloadsCS );
}
void DownloadManager::UnregisterStatusCallback( ifc_downloadManagerCallback *callback )
{
EnterCriticalSection( &downloadsCS );
auto it = std::find( status_callbacks.begin(), status_callbacks.end(), callback );
if ( it != status_callbacks.end() )
status_callbacks.erase( it );
LeaveCriticalSection( &downloadsCS );
}
bool DownloadManager::IsPending( DownloadToken token )
{
DownloadData *data = (DownloadData *)token;
if ( data )
return data->pending;
else
return FALSE;
}
/**********************************************************************************
* PRIVATE *
**********************************************************************************/
bool DownloadManager::DownloadThreadTick()
{
unsigned int i = 0;
char *downloadBuffer = (char *)malloc( DOWNLOAD_BUFFER_SIZE );
while ( WaitForSingleObject( killswitch, 0 ) != WAIT_OBJECT_0 )
{
EnterCriticalSection( &downloadsCS );
if ( downloads.empty() )
{
// TODO: might be nice to dynamically increase the sleep time if this happens
// (maybe to INFINITE and have Download() wake us?)
LeaveCriticalSection( &downloadsCS );
free( downloadBuffer );
return true;
}
if ( i >= downloads.size() )
{
LeaveCriticalSection( &downloadsCS );
free( downloadBuffer );
return true;
}
DownloadData *thisDownload = downloads[ i ];
if ( thisDownload->pending )
{
LeaveCriticalSection( &downloadsCS );
}
else
{
thisDownload->Retain();
LeaveCriticalSection( &downloadsCS );
INT tick = Tick( thisDownload, downloadBuffer, DOWNLOAD_BUFFER_SIZE );
switch ( tick )
{
case TICK_NODATA:
// do nothing
break;
case TICK_CONNECTING:
break;
case TICK_CONNECTED:
if ( thisDownload->callback )
thisDownload->callback->OnConnect( thisDownload );
if ( thisDownload->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_status : status_callbacks )
l_status->OnConnect( thisDownload );
}
break;
case TICK_SUCCESS:
if ( thisDownload->callback )
thisDownload->callback->OnTick( thisDownload );
if ( thisDownload->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_status : status_callbacks )
l_status->OnTick( thisDownload );
}
// TODO: send out update l_callback
break;
case TICK_FINISHED:
case TICK_FAILURE:
case TICK_TIMEOUT:
case TICK_CANT_CONNECT:
case TICK_WRITE_ERROR:
FinishDownload( thisDownload, tick );
break;
}
thisDownload->Release();
}
i++;
}
free( downloadBuffer );
return false; // we only get here when killswitch is set
}
int DownloadManager::DownloadTickThreadPoolFunc( HANDLE handle, void *user_data, intptr_t id )
{
DownloadManager *dlmgr = (DownloadManager *)user_data;
if ( dlmgr->DownloadThreadTick() )
{
TimerHandle t( handle );
t.Wait( DOWNLOAD_SLEEP_MS );
}
else
{
WASABI_API_THREADPOOL->RemoveHandle( 0, handle );
SetEvent( dlmgr->download_thread );
}
return 0;
}
bool DownloadManager::InitDownloadThread()
{
if ( download_thread == NULL )
{
download_thread = CreateEvent( 0, FALSE, FALSE, 0 );
TimerHandle t;
WASABI_API_THREADPOOL->AddHandle( 0, t, DownloadTickThreadPoolFunc, this, 0, api_threadpool::FLAG_LONG_EXECUTION );
t.Wait( DOWNLOAD_SLEEP_MS );
}
return ( download_thread != NULL );
}
void DownloadManager::FinishDownload( DownloadData *p_data, int code )
{
if ( p_data == NULL )
return;
ifc_downloadManagerCallback *l_callback = NULL;
EnterCriticalSection( &downloadsCS );
p_data->Close( &l_callback );
LeaveCriticalSection( &downloadsCS );
if ( l_callback != NULL )
{
if ( code == TICK_FINISHED )
{
l_callback->OnFinish( p_data );
if ( p_data->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_data : status_callbacks )
l_data->OnFinish( p_data );
}
}
else
{
l_callback->OnError( p_data, code );
if ( p_data->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_data : status_callbacks )
l_data->OnError( p_data, code );
}
}
l_callback->Release();
}
EnterCriticalSection( &downloadsCS );
auto it = std::find( downloads.begin(), downloads.end(), p_data );
if ( it != downloads.end() )
downloads.erase( it );
LeaveCriticalSection( &downloadsCS );
p_data->Release();
}
int DownloadManager::Tick( DownloadData *thisDownload, void *buffer, int bufferSize )
{
if ( !thisDownload )
return api_downloadManager::TICK_FAILURE;
int state = thisDownload->http->run();
if ( state == HTTPRECEIVER_RUN_ERROR || thisDownload == NULL )
return api_downloadManager::TICK_FAILURE;
if ( !thisDownload->fileext )
thisDownload->getExtention();
int downloaded = thisDownload->http->get_bytes( buffer, bufferSize );
if ( downloaded )
{
switch ( thisDownload->flags & DOWNLOADEX_MASK_DOWNLOADMETHOD )
{
case api_downloadManager::DOWNLOADEX_BUFFER:
{
thisDownload->buffer.reserve( thisDownload->http->content_length() );
thisDownload->buffer.add( buffer, downloaded );
}
break;
case api_downloadManager::DOWNLOADEX_TEMPFILE:
{
DWORD written = 0;
WriteFile( thisDownload->hFile, buffer, downloaded, &written, NULL );
if ( written != downloaded )
return api_downloadManager::TICK_WRITE_ERROR;
}
break;
case api_downloadManager::DOWNLOADEX_CALLBACK:
{
if ( thisDownload->flags & api_downloadManager::DOWNLOADEX_UI )
{
for ( ifc_downloadManagerCallback *l_status : status_callbacks )
l_status->OnData( thisDownload, buffer, downloaded );
}
if ( thisDownload->callback )
thisDownload->callback->OnData( thisDownload, buffer, downloaded );
}
}
thisDownload->lastDownloadTick = GetTickCount();
thisDownload->bytesDownloaded += downloaded;
return api_downloadManager::TICK_SUCCESS;
}
else // nothing in the buffer
{
if ( state == HTTPRECEIVER_RUN_CONNECTION_CLOSED ) // see if the connection is closed
{
return api_downloadManager::TICK_FINISHED; // yay we're done
}
if ( GetTickCount() - thisDownload->lastDownloadTick > DOWNLOAD_TIMEOUT_MS ) // check for timeout
return api_downloadManager::TICK_TIMEOUT;
switch ( thisDownload->http->get_status() )
{
case HTTPRECEIVER_STATUS_CONNECTING:
if ( thisDownload->last_status != HTTPRECEIVER_STATUS_CONNECTING )
{
thisDownload->last_status = HTTPRECEIVER_STATUS_CONNECTING;
return api_downloadManager::TICK_CONNECTING;
}
else
{
return api_downloadManager::TICK_NODATA;
}
case HTTPRECEIVER_STATUS_READING_HEADERS:
if ( thisDownload->last_status != HTTPRECEIVER_STATUS_READING_HEADERS )
{
thisDownload->last_status = HTTPRECEIVER_STATUS_READING_HEADERS;
return api_downloadManager::TICK_CONNECTED;
}
else
{
return api_downloadManager::TICK_NODATA;
}
}
if ( !thisDownload->replyCode )
thisDownload->replyCode = thisDownload->http->getreplycode();
switch ( thisDownload->replyCode )
{
case 0:
case 100:
case 200:
case 201:
case 202:
case 203:
case 204:
case 205:
case 206:
return api_downloadManager::TICK_NODATA;
default:
return api_downloadManager::TICK_CANT_CONNECT;
}
}
}
#define CBCLASS DownloadManager
START_DISPATCH;
CB( API_DOWNLOADMANAGER_DOWNLOAD, Download )
CB( API_DOWNLOADMANAGER_DOWNLOADEX, DownloadEx )
CB( API_DOWNLOADMANAGER_GETRECEIVER, GetReceiver )
CB( API_DOWNLOADMANAGER_GETLOCATION, GetLocation )
VCB( API_DOWNLOADMANAGER_SETLOCATION, SetLocation )
CB( API_DOWNLOADMANAGER_GETEXTENTION, GetExtention )
CB( API_DOWNLOADMANAGER_GETURL, GetUrl )
CB( API_DOWNLOADMANAGER_GETBYTESDOWNLOADED, GetBytesDownloaded );
CB( API_DOWNLOADMANAGER_GETBUFFER, GetBuffer );
VCB( API_DOWNLOADMANAGER_RESUMEPENDINGDOWNLOAD, ResumePendingDownload );
VCB( API_DOWNLOADMANAGER_CANCELDOWNLOAD, CancelDownload );
VCB( API_DOWNLOADMANAGER_RETAINDOWNLOAD, RetainDownload );
VCB( API_DOWNLOADMANAGER_RELEASEDOWNLOAD, ReleaseDownload );
VCB( API_DOWNLOADMANAGER_REGISTERSTATUSCALLBACK, RegisterStatusCallback );
VCB( API_DOWNLOADMANAGER_UNREGISTERSTATUSCALLBACK, UnregisterStatusCallback );
CB( API_DOWNLOADMANAGER_GETSOURCE, GetSource );
CB( API_DOWNLOADMANAGER_GETTITLE, GetTitle );
CB( API_DOWNLOADMANAGER_ISPENDING, IsPending );
END_DISPATCH;
#undef CBCLASS

View File

@ -0,0 +1,318 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_DOWNLOAD_MANAGER_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_DOWNLOAD_MANAGER_H
#include <vector>
#include <map>
#include <string> // for string class
#include <atomic>
#include <QtCore>
#include <QAuthenticator>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QUrlQuery>
#include "../nu/GrowBuf.h"
//#include "main.h"
//#include "wac_downloadManager_Headers.h"
#include "wac_download_http_receiver.h"
//#include "wac_download_http_receiver_api.h"
#include "wac_downloadManager_api.h"
//#include "../wac_network/wac_network_http_receiver_api.h"
#define MAX_SIMULTANEOUS_DOWNLOADS 2
static std::map<std::string, std::string> _CONTENT_TYPES_EXTENSIONS = {
{ "audio/aac", "aac" },
{ "audio/mp4", "mp4" },
{ "audio/MPA", "MPA" },
{ "audio/mpeg", "mp3" },
{ "audio/opus", "opus" },
{ "audio/ogg", "ogg" },
{ "audio/vorbis", "vorbis" },
{ "audio/wav", "wav" },
{ "video/mp2t", "ts" },
{ "video/mp4", "mp4" },
{ "video/mpeg", "mpeg" },
{ "video/ogg", "ogv" },
{ "video/x-matroska", "mkv" },
{ "video/x-msvideo", "avi" }
};
namespace wa
{
namespace Components
{
class WAC_DownloadData : public QObject
{
Q_OBJECT
public:
WAC_DownloadData( api_wac_download_manager_http_receiver *p_http, const char *p_url, int p_flags, ifc_downloadManagerCallback *p_callback );
~WAC_DownloadData();
void Retain();
void Release();
void Close( ifc_downloadManagerCallback **callbackCopy );
bool getExtention();
api_wac_download_manager_http_receiver *_http = Q_NULLPTR;
ifc_downloadManagerCallback *_callback = Q_NULLPTR;
int _flags = 0;
HANDLE _hFile; // handle to the open file where data is written to
DWORD _lastDownloadTick; // last time we got data out of the connection. used for timeout
DWORD _connectionStart; // used for when the connection starts, to help us calculate a k/s download rate
wchar_t _filepath[ MAX_PATH ]; // where file is downloaded to. probably a temp path
char *_fileext = 0;
char _url[ 1024 ];
wchar_t _source[ 1024 ];
wchar_t _title[ 1024 ];
int _replyCode = 0; // HTTP 200, 404, etc.
uint64_t _bytesDownloaded = 0;
int _last_status; // from http->get_status()
bool _pending;
GrowBuf _buffer;
private:
std::atomic<std::size_t> _refCount = 1;
};
class WAC_DownloadManager : public QNetworkAccessManager, public api_downloadManager
{
Q_OBJECT
public:
WAC_DownloadManager( QObject *parent = Q_NULLPTR );
~WAC_DownloadManager();
static const char *getServiceName() { return "Download Manager Service"; }
static GUID getServiceGuid() { return DownloadManagerGUID; }
DownloadToken Download( const char *p_url, ifc_downloadManagerCallback *p_callback );
DownloadToken DownloadEx( const char *p_url, ifc_downloadManagerCallback *p_callback, int p_flags );
private:
void init();
QNetworkReply *createRequest( Operation p_operation, const QNetworkRequest &p_request, QIODevice *p_outgoing_data = Q_NULLPTR );
QMetaObject::Connection _connection_authentication_required;
std::map<std::string, wa::Components::WAC_Download_HTTP_Receiver *> _runing_downloads;
std::map<std::string, wa::Components::WAC_Download_HTTP_Receiver *> _pending_downloads;
private Q_SLOTS:
void on_s_authentication_required( QNetworkReply *p_reply, QAuthenticator *p_authenticator );
};
}
}
#pragma region "DownloadData"
struct DownloadData
{
DownloadData( api_httpreceiver *http, const char *url, int flags, ifc_downloadManagerCallback *callback );
~DownloadData();
void Retain();
void Release();
void Close( ifc_downloadManagerCallback **callbackCopy );
bool getExtention();
api_httpreceiver *http = NULL;
ifc_downloadManagerCallback *callback = NULL;
wchar_t filepath[ MAX_PATH ]; // where file is downloaded to. probably a temp path
char *fileext = 0;
char url[ 1024 ];
wchar_t source[ 1024 ];
wchar_t title[ 1024 ];
HANDLE hFile; // handle to the open file where data is written to
DWORD lastDownloadTick; // last time we got data out of the connection. used for timeout
DWORD connectionStart; // used for when the connection starts, to help us calculate a k/s download rate
int replyCode = 0; // HTTP 200, 404, etc.
uint64_t bytesDownloaded = 0;
int last_status; // from http->get_status()
bool pending;
int flags;
GrowBuf buffer;
private:
std::atomic<std::size_t> _refCount = 1;
};
#pragma endregion
/* method ideas
Download(url, owner_token, callback, user_data)
Lock() - call before enumerating and doing anything
Unlock()
CancelDownload()
Enum(owner_token)
*/
class DownloadManager : public api_downloadManager
{
public:
static const char *getServiceName() { return "Download Manager"; }
static GUID getServiceGuid() { return DownloadManagerGUID; }
DownloadManager();
void Kill();
DownloadToken Download( const char *url, ifc_downloadManagerCallback *callback );
DownloadToken DownloadEx( const char *url, ifc_downloadManagerCallback *callback, int flags );
void ResumePendingDownload( DownloadToken token );
void CancelDownload( DownloadToken token );
void RetainDownload( DownloadToken token );
void ReleaseDownload( DownloadToken token );
void RegisterStatusCallback( ifc_downloadManagerCallback *callback );
void UnregisterStatusCallback( ifc_downloadManagerCallback *callback );
bool IsPending( DownloadToken token );
/*
only call these during a callback!
*/
api_httpreceiver *GetReceiver( DownloadToken token )
{
if ( token )
return ( (DownloadData *)token )->http;
else
return 0;
}
const wchar_t *GetLocation( DownloadToken token )
{
if ( token )
return ( (DownloadData *)token )->filepath;
else
return 0;
}
const wchar_t *GetSource( DownloadToken p_token )
{
if ( !p_token )
return 0;
DownloadData *data = (DownloadData *)p_token;
if ( data )
return data->source;
else
return 0;
}
const wchar_t *GetTitle( DownloadToken p_token )
{
if ( !p_token )
return 0;
DownloadData *data = (DownloadData *)p_token;
if ( data )
return data->title;
else
return 0;
}
void SetLocation( DownloadToken token, const wchar_t *p_location )
{
if ( token )
wcscpy( ( (DownloadData *)token )->filepath, p_location );
}
const char *GetExtention( DownloadToken token )
{
if ( token )
return ( (DownloadData *)token )->fileext;
else
return 0;
}
const char *GetUrl( DownloadToken token )
{
if ( token )
return ( (DownloadData *)token )->url;
else
return 0;
}
int GetBuffer( DownloadToken token, void **buffer, size_t *bufferlen )
{
if ( token )
{
*buffer = ( (DownloadData *)token )->buffer.get();
*bufferlen = ( (DownloadData *)token )->buffer.getlen();
return 0;
}
else
return 1;
}
uint64_t GetBytesDownloaded( DownloadToken token )
{
if ( token )
return ( (DownloadData *)token )->bytesDownloaded;
else
return 0;
}
private:
CRITICAL_SECTION downloadsCS;
bool DownloadThreadTick();
static int DownloadTickThreadPoolFunc( HANDLE handle, void *user_data, intptr_t id );
bool InitDownloadThread();
void FinishDownload( DownloadData *data, int code );
int Tick( DownloadData *thisDownload, void *buffer, int bufferSize );
HANDLE download_thread;
HANDLE killswitch;
std::vector<DownloadData *> downloads;
typedef std::vector<ifc_downloadManagerCallback *> StatusList;
StatusList status_callbacks;
protected:
RECVS_DISPATCH;
};
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_DOWNLOAD_MANAGER_H

View File

@ -0,0 +1,76 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{66827D3B-AA81-4F38-A671-A0C9B0C2E21D}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'">10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">10.0.19041.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="QtSettings">
<QtInstall>5.15.2_msvc2019</QtInstall>
<QtModules>core;network;concurrent;webengine;webenginewidgets</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="QtSettings">
<QtInstall>5.15.2_msvc2019</QtInstall>
<QtModules>core;network;concurrent;webengine;webenginewidgets</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'">
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetExt>.w5s</TargetExt>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetExt>.w5s</TargetExt>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\Wasabi;..\..\replicant;%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
<WarningLevel>Level3</WarningLevel>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
</ClCompile>
<Link>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<AdditionalDependencies>comctl32.lib;ws2_32.lib;Crypt32.lib;shlwapi.lib;%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<AdditionalIncludeDirectories>..\..\Wasabi;..\..\replicant;%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
<SupportJustMyCode>false</SupportJustMyCode>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
</ClCompile>
<Link>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<AdditionalDependencies>comctl32.lib;ws2_32.lib;Crypt32.lib;shlwapi.lib;%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgInstalledDir>
</VcpkgInstalledDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgInstalledDir>
</VcpkgInstalledDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnabled>true</VcpkgEnabled>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_SSL;WAC_DOWNLOAD_MANAGER_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>None</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_SSL;WAC_DOWNLOAD_MANAGER_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="BackgroundDownloader.cpp" />
<ClCompile Include="wac_downloadManager.cpp">
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">input</DynamicSource>
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).moc</QtMocFileName>
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">input</DynamicSource>
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).moc</QtMocFileName>
</ClCompile>
<ClCompile Include="wac_downloadManager_api.cpp" />
<ClCompile Include="wac_downloadManager_factory.cpp" />
<ClCompile Include="wac_download_http_receiver.cpp" />
<ClCompile Include="wac_download_http_receiver_api.cpp" />
<ClCompile Include="wac_download_http_receiver_factory.cpp" />
<ClInclude Include="resource.h" />
<ClInclude Include="wac_downloadManager_api.h" />
<ClInclude Include="api__wac_downloadManager.h" />
<ClInclude Include="BackgroundDownloader.h" />
<ClInclude Include="DownloadCallbackT.h" />
<ClInclude Include="wac_downloadManager_factory.h" />
<ClInclude Include="wac_downloadManager_global.h" />
<ClInclude Include="main.h" />
<ClCompile Include="main.cpp" />
<ClInclude Include="wac_downloadManager_Headers.h" />
<ClInclude Include="wac_download_http_receiver_api.h" />
<ClInclude Include="wac_download_http_receiver_factory.h" />
<QtMoc Include="wac_download_http_receiver.h" />
<QtMoc Include="wac_downloadManager.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\tataki\tataki.vcxproj">
<Project>{255b68b5-7ef8-45ef-a675-2d6b88147909}</Project>
</ProjectReference>
<ProjectReference Include="..\..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="wac_downloadManager.rc" />
</ItemGroup>
<ItemGroup>
<None Include="version.rc2" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
<Filter Include="Header Files\HTTP Receiver">
<UniqueIdentifier>{738d86e2-2471-4e0d-bcb4-dd3b1c132c01}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\downloadManager">
<UniqueIdentifier>{ddf711c1-7782-4349-9835-758b85fcfe53}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\HTTP Receiver">
<UniqueIdentifier>{9892fa19-d3f5-43cf-a433-aa513290ca0d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\downloadManager">
<UniqueIdentifier>{c31b92ff-4576-420f-885a-333d90811b9b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="api__wac_downloadManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BackgroundDownloader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DownloadCallbackT.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wac_download_http_receiver_factory.h">
<Filter>Header Files\HTTP Receiver</Filter>
</ClInclude>
<ClInclude Include="wac_download_http_receiver_api.h">
<Filter>Header Files\HTTP Receiver</Filter>
</ClInclude>
<ClInclude Include="wac_downloadManager_api.h">
<Filter>Header Files\downloadManager</Filter>
</ClInclude>
<ClInclude Include="wac_downloadManager_factory.h">
<Filter>Header Files\downloadManager</Filter>
</ClInclude>
<ClCompile Include="wac_downloadManager_api.cpp">
<Filter>Source Files\downloadManager</Filter>
</ClCompile>
<ClCompile Include="wac_downloadManager_factory.cpp">
<Filter>Source Files\downloadManager</Filter>
</ClCompile>
<ClCompile Include="wac_download_http_receiver.cpp">
<Filter>Source Files\HTTP Receiver</Filter>
</ClCompile>
<ClCompile Include="wac_download_http_receiver_api.cpp">
<Filter>Source Files\HTTP Receiver</Filter>
</ClCompile>
<ClCompile Include="wac_download_http_receiver_factory.cpp">
<Filter>Source Files\HTTP Receiver</Filter>
</ClCompile>
<ClCompile Include="wac_downloadManager.cpp">
<Filter>Source Files\downloadManager</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="BackgroundDownloader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="wac_download_http_receiver.h">
<Filter>Header Files\HTTP Receiver</Filter>
</QtMoc>
<QtMoc Include="wac_downloadManager.h">
<Filter>Header Files\downloadManager</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="wac_downloadManager_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wac_downloadManager_Headers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="wac_downloadManager.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="version.rc2">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,9 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_HEADERS_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_HEADERS_H
#include "wac_downloadManager.h"
#include "wac_download_http_receiver.h"
#endif // NULLSOFT_WAC_DOWNLOAD_MANAGER_HEADERS_H

View File

@ -0,0 +1 @@
#include "wac_downloadManager_api.h"

View File

@ -0,0 +1,274 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_API_DOWNLOADMANAGER_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_API_DOWNLOADMANAGER_H
#include "bfc/dispatch.h"
typedef void *DownloadToken;
class ifc_downloadManagerCallback;
class api_httpreceiver;
class ifc_downloadManagerCallback : public Dispatchable
{
public:
void OnFinish( DownloadToken token );
void OnTick( DownloadToken token );
void OnError( DownloadToken token, int error );
void OnCancel( DownloadToken token );
void OnConnect( DownloadToken token );
void OnInit( DownloadToken token );
void OnData( DownloadToken token, void *data, size_t datalen );
int GetSource( wchar_t *source, size_t source_cch );
int GetTitle( wchar_t *title, size_t title_cch );
int GetLocation( wchar_t *location, size_t location_cch );
DISPATCH_CODES
{
IFC_DOWNLOADMANAGERCALLBACK_ONFINISH = 10,
IFC_DOWNLOADMANAGERCALLBACK_ONTICK = 20,
IFC_DOWNLOADMANAGERCALLBACK_ONERROR = 30,
IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL = 40,
IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT = 50,
IFC_DOWNLOADMANAGERCALLBACK_ONINIT = 60,
IFC_DOWNLOADMANAGERCALLBACK_ONDATA = 70,
IFC_DOWNLOADMANAGERCALLBACK_GETSOURCE = 80,
IFC_DOWNLOADMANAGERCALLBACK_GETTITLE = 90,
IFC_DOWNLOADMANAGERCALLBACK_GETLOCATION = 100,
};
};
inline void ifc_downloadManagerCallback::OnFinish( DownloadToken token )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, token );
}
inline void ifc_downloadManagerCallback::OnTick( DownloadToken token )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONTICK, token );
}
inline void ifc_downloadManagerCallback::OnError( DownloadToken token, int error )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONERROR, token, error );
}
inline void ifc_downloadManagerCallback::OnCancel( DownloadToken token )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, token );
}
inline void ifc_downloadManagerCallback::OnConnect( DownloadToken token )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, token );
}
inline void ifc_downloadManagerCallback::OnInit( DownloadToken token )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONINIT, token );
}
inline void ifc_downloadManagerCallback::OnData( DownloadToken token, void *data, size_t datalen )
{
_voidcall( IFC_DOWNLOADMANAGERCALLBACK_ONDATA, token, data, datalen );
}
inline int ifc_downloadManagerCallback::GetSource( wchar_t *source, size_t source_cch )
{
return _call( IFC_DOWNLOADMANAGERCALLBACK_GETSOURCE, (int)1, source, source_cch );
}
inline int ifc_downloadManagerCallback::GetTitle( wchar_t *title, size_t title_cch )
{
return _call( IFC_DOWNLOADMANAGERCALLBACK_GETTITLE, (int)1, title, title_cch );
}
inline int ifc_downloadManagerCallback::GetLocation( wchar_t *location, size_t location_cch )
{
return _call( IFC_DOWNLOADMANAGERCALLBACK_GETLOCATION, (int)1, location, location_cch );
}
class api_downloadManager : public Dispatchable
{
public:
DownloadToken Download( const char *url, ifc_downloadManagerCallback *callback );
DownloadToken DownloadEx( const char *url, ifc_downloadManagerCallback *callback, int flags );
api_httpreceiver *GetReceiver( DownloadToken token );
const wchar_t *GetLocation( DownloadToken token );
void SetLocation( DownloadToken token, const wchar_t *p_location );
const char *GetExtention( DownloadToken token );
const char *GetUrl( DownloadToken token );
int GetBuffer( DownloadToken token, void **buffer, size_t *bufferLength );
uint64_t GetBytesDownloaded( DownloadToken token );
void ResumePendingDownload( DownloadToken token );
void CancelDownload( DownloadToken token );
void RetainDownload( DownloadToken token );
void ReleaseDownload( DownloadToken token );
/* added in 5.58 */
void RegisterStatusCallback( ifc_downloadManagerCallback *callback );
void UnregisterStatusCallback( ifc_downloadManagerCallback *callback );
const wchar_t *GetSource( DownloadToken token );
const wchar_t *GetTitle( DownloadToken token );
bool IsPending( DownloadToken token );
DISPATCH_CODES
{
API_DOWNLOADMANAGER_DOWNLOAD = 10,
API_DOWNLOADMANAGER_DOWNLOADEX = 20,
API_DOWNLOADMANAGER_GETRECEIVER = 100,
API_DOWNLOADMANAGER_GETLOCATION = 110,
API_DOWNLOADMANAGER_SETLOCATION = 112,
API_DOWNLOADMANAGER_GETEXTENTION = 115,
API_DOWNLOADMANAGER_GETURL = 117,
API_DOWNLOADMANAGER_GETBYTESDOWNLOADED = 120,
API_DOWNLOADMANAGER_GETBUFFER = 130,
API_DOWNLOADMANAGER_CANCELDOWNLOAD = 140,
API_DOWNLOADMANAGER_RETAINDOWNLOAD = 150,
API_DOWNLOADMANAGER_RELEASEDOWNLOAD = 160,
API_DOWNLOADMANAGER_REGISTERSTATUSCALLBACK = 170,
API_DOWNLOADMANAGER_UNREGISTERSTATUSCALLBACK = 180,
API_DOWNLOADMANAGER_GETSOURCE = 190,
API_DOWNLOADMANAGER_GETTITLE = 200,
API_DOWNLOADMANAGER_RESUMEPENDINGDOWNLOAD = 210,
API_DOWNLOADMANAGER_ISPENDING = 220,
};
enum
{
DOWNLOADEX_TEMPFILE = 0, // download as a temporary file
DOWNLOADEX_BUFFER = 1, // download to memory
DOWNLOADEX_CALLBACK = 2, // send data to OnData callback
DOWNLOADEX_MASK_DOWNLOADMETHOD = 0x3,
DOWNLOADEX_PENDING = 0xF00,
DOWNLOADEX_UI = 0xF000, // show up in the download manager UI
};
enum
{
TICK_NODATA = -2, // not necessarily an error, just means no data this time around
TICK_FINISHED = -1,
TICK_SUCCESS = 0,
TICK_FAILURE = 1,
TICK_TIMEOUT = 2,
TICK_CANT_CONNECT = 3,
TICK_WRITE_ERROR = 4,
TICK_CONNECTING = 5,
TICK_CONNECTED = 6,
};
};
inline DownloadToken api_downloadManager::Download( const char *url, ifc_downloadManagerCallback *callback )
{
return _call( API_DOWNLOADMANAGER_DOWNLOAD, (DownloadToken *)0, url, callback );
}
inline DownloadToken api_downloadManager::DownloadEx( const char *url, ifc_downloadManagerCallback *callback, int flags )
{
return _call( API_DOWNLOADMANAGER_DOWNLOADEX, (DownloadToken *)0, url, callback, flags );
}
inline api_httpreceiver *api_downloadManager::GetReceiver( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETRECEIVER, (api_httpreceiver *)0, token );
}
inline const wchar_t *api_downloadManager::GetLocation( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETLOCATION, (const wchar_t *)0, token );
}
inline void api_downloadManager::SetLocation( DownloadToken token, const wchar_t *p_location )
{
_voidcall( API_DOWNLOADMANAGER_SETLOCATION, token, p_location );
}
inline const char *api_downloadManager::GetExtention( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETEXTENTION, (const char *)0, token );
}
inline const char *api_downloadManager::GetUrl( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETURL, (const char *)0, token );
}
inline uint64_t api_downloadManager::GetBytesDownloaded( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETBYTESDOWNLOADED, (uint64_t)0, token );
}
inline int api_downloadManager::GetBuffer( DownloadToken token, void **buffer, size_t *bufferLength )
{
return _call( API_DOWNLOADMANAGER_GETBUFFER, (int)1, token, buffer, bufferLength );
}
inline void api_downloadManager::ResumePendingDownload( DownloadToken token )
{
_voidcall( API_DOWNLOADMANAGER_RESUMEPENDINGDOWNLOAD, token );
}
inline void api_downloadManager::CancelDownload( DownloadToken token )
{
_voidcall( API_DOWNLOADMANAGER_CANCELDOWNLOAD, token );
}
inline void api_downloadManager::RetainDownload( DownloadToken token )
{
_voidcall( API_DOWNLOADMANAGER_RETAINDOWNLOAD, token );
}
inline void api_downloadManager::ReleaseDownload( DownloadToken token )
{
_voidcall( API_DOWNLOADMANAGER_RELEASEDOWNLOAD, token );
}
inline void api_downloadManager::RegisterStatusCallback( ifc_downloadManagerCallback *callback )
{
_voidcall( API_DOWNLOADMANAGER_REGISTERSTATUSCALLBACK, callback );
}
inline void api_downloadManager::UnregisterStatusCallback( ifc_downloadManagerCallback *callback )
{
_voidcall( API_DOWNLOADMANAGER_UNREGISTERSTATUSCALLBACK, callback );
}
inline const wchar_t *api_downloadManager::GetSource( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETSOURCE, (const wchar_t *)0, token );
}
inline const wchar_t *api_downloadManager::GetTitle( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_GETTITLE, (const wchar_t *)0, token );
}
inline bool api_downloadManager::IsPending( DownloadToken token )
{
return _call( API_DOWNLOADMANAGER_ISPENDING, (bool)0, token );
}
// {9E5E732A-C612-489d-AB52-1501E1AF1710}
static const GUID DownloadManagerGUID =
{ 0x9e5e732a, 0xc612, 0x489d, { 0xab, 0x52, 0x15, 0x1, 0xe1, 0xaf, 0x17, 0x10 } };
extern api_downloadManager *g_downloadManagerApi;
#ifndef WAC_API_DOWNLOADMANAGER
#define WAC_API_DOWNLOADMANAGER g_downloadManagerApi
#endif // !WAC_API_DOWNLOADMANAGER
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_API_DOWNLOADMANAGER_H

View File

@ -0,0 +1,88 @@
#include "wac_downloadManager_factory.h"
static const char serviceName[] = "WAC Downloads";
static const char testString[] = "Downloads Component";
// {B000EE81-199F-48C2-BDCB-F7E3C31A2A13}
static const GUID api_downloads_GUID = { 0xb000ee81, 0x199f, 0x48c2, { 0xbd, 0xcb, 0xf7, 0xe3, 0x1a, 0x12, 0x2a, 0x13 } };
FOURCC wa::Components::WAC_DownloadManagerFactory::GetServiceType()
{
return WaSvc::UNIQUE;
}
const char *wa::Components::WAC_DownloadManagerFactory::GetServiceName()
{
return serviceName;
}
GUID wa::Components::WAC_DownloadManagerFactory::GetGUID()
{
return api_downloads_GUID;
}
const char *wa::Components::WAC_DownloadManagerFactory::GetTestString()
{
return testString;
}
void *wa::Components::WAC_DownloadManagerFactory::GetInterface( int global_lock )
{
return nullptr;
}
int wa::Components::WAC_DownloadManagerFactory::ReleaseInterface( void *ifc )
{
return 1;
}
int wa::Components::WAC_DownloadManagerFactory::SupportNonLockingInterface()
{
return 1;
}
int wa::Components::WAC_DownloadManagerFactory::ServiceNotify( int msg, int param1, int param2 )
{
return 1;
}
HRESULT wa::Components::WAC_DownloadManagerFactory::Register( api_service *p_service )
{
if ( p_service == NULL )
return E_INVALIDARG;
p_service->service_register( this );
return S_OK;
}
HRESULT wa::Components::WAC_DownloadManagerFactory::Unregister( api_service *p_service )
{
if ( p_service == NULL )
return E_INVALIDARG;
p_service->service_deregister( this );
return S_OK;
}
#ifdef CBCLASS
#undef CBCLASS
#endif
#define CBCLASS wa::Components::WAC_DownloadManagerFactory
START_DISPATCH;
CB( WASERVICEFACTORY_GETSERVICETYPE, GetServiceType )
CB( WASERVICEFACTORY_GETSERVICENAME, GetServiceName )
CB( WASERVICEFACTORY_GETGUID, GetGUID )
CB( WASERVICEFACTORY_GETINTERFACE, GetInterface )
CB( WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface )
CB( WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface )
CB( WASERVICEFACTORY_GETTESTSTRING, GetTestString )
CB( WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify )
END_DISPATCH;

View File

@ -0,0 +1,37 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_FACTORY_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_FACTORY_H
#include "api__wac_downloadManager.h"
#include "api/service/waservicefactory.h"
#include "api/service/services.h"
namespace wa
{
namespace Components
{
class WAC_DownloadManagerFactory : public waServiceFactory
{
public:
FOURCC GetServiceType();
const char *GetServiceName();
GUID GetGUID();
const char *GetTestString();
void *GetInterface( int global_lock );
int ReleaseInterface( void *ifc );
int SupportNonLockingInterface();
int ServiceNotify( int msg, int param1, int param2 );
HRESULT Register( api_service *p_service );
HRESULT Unregister( api_service *p_service );
protected:
RECVS_DISPATCH;
};
}
}
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_FACTORY_H

View File

@ -0,0 +1,16 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_GLOBAL_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_GLOBAL_H
#include <QtCore/qglobal.h>
#ifndef BUILD_STATIC
# if defined(WAC_DOWNLOAD_MANAGER_LIB)
# define WAC_DOWNLOAD_MANAGER_EXPORT Q_DECL_EXPORT
# else
# define WAC_DOWNLOAD_MANAGER_EXPORT Q_DECL_IMPORT
# endif
#else
# define WAC_DOWNLOAD_MANAGER_EXPORT
#endif
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_GLOBAL_H

View File

@ -0,0 +1,64 @@
#include "wac_download_http_receiver.h"
wa::Components::WAC_Download_HTTP_Receiver::WAC_Download_HTTP_Receiver()
{}
wa::Components::WAC_Download_HTTP_Receiver::~WAC_Download_HTTP_Receiver()
{}
void wa::Components::WAC_Download_HTTP_Receiver::open( api_dns * p_dns, size_t p_recvbufsize, const char *p_proxy )
{
Q_UNUSED( p_dns )
Q_UNUSED( p_recvbufsize )
Q_UNUSED( p_proxy )
}
std::size_t wa::Components::WAC_Download_HTTP_Receiver::AddRef()
{
return this->_reference_count.fetch_add( 1 );
}
std::size_t wa::Components::WAC_Download_HTTP_Receiver::Release()
{
std::size_t l_reference_count = this->_reference_count.fetch_sub( 1 );
if ( l_reference_count == 0 )
delete this;
return l_reference_count;
}
#ifdef CBCLASS
#undef CBCLASS
#endif
#define CBCLASS wa::Components::WAC_Download_HTTP_Receiver
START_DISPATCH;
CB( ADDREF, AddRef )
CB( RELEASE, Release )
VCB( API_HTTPRECEIVER_OPEN, open )
//VCB( API_HTTPRECEIVER_ADDHEADER, addheader )
//VCB( API_HTTPRECEIVER_ADDHEADERVALUE, addheadervalue )
//VCB( API_HTTPRECEIVER_CONNECT, connect )
//CB( API_HTTPRECEIVER_RUN, run )
//CB( API_HTTPRECEIVER_GETSTATUS, get_status )
//CB( API_HTTPRECEIVER_GETBYTESAVAILABLE, bytes_available )
//CB( API_HTTPRECEIVER_GETBYTES, get_bytes )
//CB( API_HTTPRECEIVER_PEEKBYTES, peek_bytes )
//CB( API_HTTPRECEIVER_GETHEADER, getheader )
//CB( API_HTTPRECEIVER_GETCONTENTLENGTH, content_length )
//CB( API_HTTPRECEIVER_GETALLHEADERS, getallheaders )
//CB( API_HTTPRECEIVER_GETREPLYCODE, getreplycode )
//CB( API_HTTPRECEIVER_GETREPLY, getreply )
//CB( API_HTTPRECEIVER_GETERROR, geterrorstr )
//CB( API_HTTPRECEIVER_GETCONNECTION, get_con )
//VCB( API_HTTPRECEIVER_ALLOW_COMPRESSION, AllowCompression )
//VCB( API_HTTPRECEIVER_RESET_HEADERS, reset_headers )
//CB( API_HTTPRECEIVER_GET_URL, get_url )
//VCB( API_HTTPRECEIVER_SET_SENDBUFSIZE, set_sendbufsize )
//VCB( API_HTTPRECEIVER_SET_ACCEPT_ALL_REPLY_CODES, set_accept_all_reply_codes )
//VCB( API_HTTPRECEIVER_SET_PERSISTENT, set_persistent )
END_DISPATCH;
#undef CBCLASS

View File

@ -0,0 +1,48 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_HTTP_RECEIVER_H
#define NULLSOFT_WAC_NETWORK_HTTP_RECEIVER_H
#include <atomic>
#include <QtCore>
//#include <QAuthenticator>
//#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QUrlQuery>
//#include "wac_downloadManager_Headers.h"
#include "wac_download_http_receiver_api.h"
namespace wa
{
namespace Components
{
class WAC_Download_HTTP_Receiver : public QObject, public api_wac_download_manager_http_receiver
{
Q_OBJECT
public:
WAC_Download_HTTP_Receiver();
~WAC_Download_HTTP_Receiver();
void open( api_dns *p_dns = API_DNS_AUTODNS, size_t p_recvbufsize = PACKET_SIZE, const char *p_proxy = NULL );
std::size_t AddRef();
std::size_t Release();
protected:
RECVS_DISPATCH;
private:
volatile std::atomic<std::size_t> _reference_count = 1;
};
}
}
#endif // !NULLSOFT_WAC_NETWORK_HTTP_RECEIVER_H

View File

@ -0,0 +1 @@
#include "wac_download_http_receiver_api.h"

View File

@ -0,0 +1,237 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_API_HTTP_RECEIVER_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_API_HTTP_RECEIVER_H
#define PACKET_SIZE 16384
#include "bfc/dispatch.h"
#include "bfc/platform/types.h"
#include "../wac_network/wac_network_dns_api.h"
enum
{
HTTP_RECEIVER_STATUS_ERROR = -1,
HTTP_RECEIVER_STATUS_CONNECTING = 0,
HTTP_RECEIVER_STATUS_READING_HEADERS = 1,
HTTP_RECEIVER_STATUS_READING_CONTENT = 2,
};
enum
{
HTTP_RECEIVER_RUN_ERROR = -1,
HTTP_RECEIVER_RUN_OK = 0,
HTTP_RECEIVER_RUN_CONNECTION_CLOSED = 1,
};
class NOVTABLE api_wac_download_manager_http_receiver : public Dispatchable
{
protected:
api_wac_download_manager_http_receiver() {}
~api_wac_download_manager_http_receiver() {}
public:
void open( api_dns *dns = API_DNS_AUTODNS, size_t recvbufsize = PACKET_SIZE, const char *proxy = NULL );
void addheader( const char *header );
void AddHeaderValue( const char *header, const char *value );
void reset_headers();
char *getheader( char *headername );
const char *getallheaders(); // double null terminated, null delimited list
void connect( const char *url, int ver = 0, const char *requestmethod = "GET" );
int run(); // see HTTPRECEIVER_RUN_* enum for return values
int get_status(); // see HTTPRECEIVER_STATUS_* enum for return values
int bytes_available();
int get_bytes( void *buf, int len );
int peek_bytes( void *buf, int len );
uint64_t content_length();
int getreplycode(); // returns 0 if none yet, otherwise returns http reply code.
const char *GetReply();
const char *geterrorstr();
//api_connection *GetConnection();
void AllowCompression();
const char *get_url(); // might not be the same as what you passed in if a redirect happened
void set_sendbufsize( int sendbufsize = PACKET_SIZE ); // call if you're going to POST or do any kind of bidirectional communications
void set_accept_all_reply_codes();
void set_persistent();
DISPATCH_CODES
{
API_HTTPRECEIVER_OPEN = 10,
API_HTTPRECEIVER_ADDHEADER = 20,
API_HTTPRECEIVER_ADDHEADERVALUE = 30,
API_HTTPRECEIVER_CONNECT = 40,
API_HTTPRECEIVER_RUN = 50,
API_HTTPRECEIVER_GETSTATUS = 60,
API_HTTPRECEIVER_GETBYTESAVAILABLE = 70,
API_HTTPRECEIVER_GETBYTES = 80,
API_HTTPRECEIVER_PEEKBYTES = 90,
API_HTTPRECEIVER_GETHEADER = 100,
API_HTTPRECEIVER_GETCONTENTLENGTH = 110,
API_HTTPRECEIVER_GETALLHEADERS = 120,
API_HTTPRECEIVER_GETREPLYCODE = 130,
API_HTTPRECEIVER_GETREPLY = 140,
API_HTTPRECEIVER_GETERROR = 150,
API_HTTPRECEIVER_GETCONNECTION = 160,
API_HTTPRECEIVER_ALLOW_COMPRESSION = 170,
API_HTTPRECEIVER_RESET_HEADERS = 180,
API_HTTPRECEIVER_GET_URL = 190,
API_HTTPRECEIVER_SET_SENDBUFSIZE = 200,
API_HTTPRECEIVER_SET_ACCEPT_ALL_REPLY_CODES = 210,
API_HTTPRECEIVER_SET_PERSISTENT = 220,
};
};
inline void api_wac_download_manager_http_receiver::open( api_dns *dns, size_t recvbufsize, const char *proxy )
{
_voidcall( API_HTTPRECEIVER_OPEN, dns, recvbufsize, proxy );
}
inline void api_wac_download_manager_http_receiver::addheader( const char *header )
{
_voidcall( API_HTTPRECEIVER_ADDHEADER, header );
}
inline void api_wac_download_manager_http_receiver::AddHeaderValue( const char *header, const char *value )
{
_voidcall( API_HTTPRECEIVER_ADDHEADERVALUE, header, value );
}
inline void api_wac_download_manager_http_receiver::reset_headers()
{
_voidcall( API_HTTPRECEIVER_RESET_HEADERS );
}
inline char *api_wac_download_manager_http_receiver::getheader( char *headername )
{
return _call( API_HTTPRECEIVER_GETHEADER, (char *)NULL, headername );
}
inline const char *api_wac_download_manager_http_receiver::getallheaders()
{
return _call( API_HTTPRECEIVER_GETALLHEADERS, (const char *)NULL );
}
inline void api_wac_download_manager_http_receiver::connect( const char *url, int ver, const char *requestmethod )
{
_voidcall( API_HTTPRECEIVER_CONNECT, url, ver, requestmethod );
}
inline int api_wac_download_manager_http_receiver::run()
{
return _call( API_HTTPRECEIVER_RUN, (int)HTTP_RECEIVER_RUN_ERROR );
}
inline int api_wac_download_manager_http_receiver::get_status()
{
return _call( API_HTTPRECEIVER_GETSTATUS, (int)HTTP_RECEIVER_STATUS_ERROR );
}
inline int api_wac_download_manager_http_receiver::bytes_available()
{
return _call( API_HTTPRECEIVER_GETBYTESAVAILABLE, (int)0 );
}
inline int api_wac_download_manager_http_receiver::get_bytes( void *buf, int len )
{
return _call( API_HTTPRECEIVER_GETBYTES, (int)0, buf, len );
}
inline int api_wac_download_manager_http_receiver::peek_bytes( void *buf, int len )
{
return _call( API_HTTPRECEIVER_PEEKBYTES, (int)0, buf, len );
}
inline uint64_t api_wac_download_manager_http_receiver::content_length()
{
return _call( API_HTTPRECEIVER_GETCONTENTLENGTH, (uint64_t)0 );
}
inline int api_wac_download_manager_http_receiver::getreplycode()
{
return _call( API_HTTPRECEIVER_GETREPLYCODE, 0 );
}
inline const char *api_wac_download_manager_http_receiver::GetReply()
{
return _call( API_HTTPRECEIVER_GETREPLY, (const char *)NULL );
}
inline const char *api_wac_download_manager_http_receiver::geterrorstr()
{
return _call( API_HTTPRECEIVER_GETERROR, (const char *)NULL );
}
//inline api_connection *api_wac_download_manager_http_receiver::GetConnection()
//{
// return _call( API_HTTPRECEIVER_GETCONNECTION, (api_connection *)NULL );
//}
inline void api_wac_download_manager_http_receiver::AllowCompression()
{
_voidcall( API_HTTPRECEIVER_ALLOW_COMPRESSION );
}
inline const char *api_wac_download_manager_http_receiver::get_url()
{
return _call( API_HTTPRECEIVER_GET_URL, (const char *)0 );
}
inline void api_wac_download_manager_http_receiver::set_sendbufsize( int sendbufsize )
{
_voidcall( API_HTTPRECEIVER_SET_SENDBUFSIZE, sendbufsize );
}
inline void api_wac_download_manager_http_receiver::set_accept_all_reply_codes()
{
_voidcall( API_HTTPRECEIVER_SET_ACCEPT_ALL_REPLY_CODES );
}
inline void api_wac_download_manager_http_receiver::set_persistent()
{
_voidcall( API_HTTPRECEIVER_SET_PERSISTENT );
}
//////// {12475CD9-1BA3-4665-B395-F87DBF31E30F}
//////static const GUID httpreceiverGUID =
//////{ 0x12475cd9, 0x1ba3, 0x4665, { 0xb3, 0x95, 0xf8, 0x7d, 0xbf, 0x31, 0xe3, 0xf } };
// {1683C6B7-1F6A-4C56-8496-525A3F5929D9}
static const GUID httpreceiverGUID2 =
{ 0x1683c6b7, 0x1f6a, 0x4c56, { 0x84, 0x96, 0x52, 0x5a, 0x3f, 0x59, 0x29, 0xd9 } };
#endif // !NULLSOFT_WAC_DOWNLOAD_MANAGER_API_HTTP_RECEIVER_H

View File

@ -0,0 +1,82 @@
#define GUID_EQUALS_DEFINED
//#include "util.h"
#include "api__wac_downloadManager.h"
#include "wac_download_http_receiver.h"
//#include "wac_download_http_receiver_api.h"
#include "wac_download_http_receiver_factory.h"
static const std::string _serviceName = "DownloadManager HTTP Receiver Service";
FOURCC wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::GetServiceType()
{
return WaSvc::OBJECT;
}
const char *wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::GetServiceName()
{
return _serviceName.c_str();
}
GUID wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::GetGUID()
{
return httpreceiverGUID2;
}
void *wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::GetInterface( int global_lock )
{
//if ( JNL::open_socketlib() )
// return NULL;
api_wac_download_manager_http_receiver *ifc = new wa::Components::WAC_Download_HTTP_Receiver();
//JNL::close_socketlib(); // new JNL_HTTPGet will call open_socketlib also, so we can release now
//// if (global_lock)
//// WASABI_API_SVC->service_lock(this, (void *)ifc);
return ifc;
//return NULL;
}
int wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::SupportNonLockingInterface()
{
return 1;
}
int wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::ReleaseInterface( void *ifc )
{
//WASABI_API_SVC->service_unlock(ifc);
api_wac_download_manager_http_receiver *httpget = static_cast<api_wac_download_manager_http_receiver *>( ifc );
if ( httpget )
httpget->Release();
return 1;
}
const char *wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::GetTestString()
{
return NULL;
}
int wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory::ServiceNotify( int msg, int param1, int param2 )
{
return 1;
}
#define CBCLASS wa::Factory::WAC_DownloadMabager_HTTPReceiver_Factory
START_DISPATCH;
CB( WASERVICEFACTORY_GETSERVICETYPE, GetServiceType )
CB( WASERVICEFACTORY_GETSERVICENAME, GetServiceName )
CB( WASERVICEFACTORY_GETGUID, GetGUID )
CB( WASERVICEFACTORY_GETINTERFACE, GetInterface )
CB( WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface )
CB( WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface )
CB( WASERVICEFACTORY_GETTESTSTRING, GetTestString )
CB( WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify )
END_DISPATCH;
#undef CBCLASS

View File

@ -0,0 +1,33 @@
#ifndef NULLSOFT_WAC_DOWNLOAD_MANAGER_FACTORY_HTTP_RECEIVER_H
#define NULLSOFT_WAC_DOWNLOAD_MANAGER_FACTORY_HTTP_RECEIVER_H
#include <string>
#include "api/service/waservicefactory.h"
#include "api/service/services.h"
namespace wa
{
namespace Factory
{
class WAC_DownloadMabager_HTTPReceiver_Factory : public waServiceFactory
{
public:
FOURCC GetServiceType();
const char *GetServiceName();
GUID GetGUID();
void *GetInterface( int global_lock );
int SupportNonLockingInterface();
int ReleaseInterface( void *ifc );
const char *GetTestString();
int ServiceNotify( int msg, int param1, int param2 );
protected:
RECVS_DISPATCH;
};
}
}
#endif //!NULLSOFT_WAC_DOWNLOAD_MANAGER_FACTORY_HTTP_RECEIVER_H