123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- #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
|