diff options
Diffstat (limited to 'Src/Components/wac_downloadManager/wac_downloadManager.h')
-rw-r--r-- | Src/Components/wac_downloadManager/wac_downloadManager.h | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/Src/Components/wac_downloadManager/wac_downloadManager.h b/Src/Components/wac_downloadManager/wac_downloadManager.h new file mode 100644 index 00000000..aa06819c --- /dev/null +++ b/Src/Components/wac_downloadManager/wac_downloadManager.h @@ -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 |