source-engine/replay/cl_downloader.h

110 lines
3.7 KiB
C
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=======================================================================================//
#ifndef CL_DOWNLOADER_H
#define CL_DOWNLOADER_H
#ifdef _WIN32
#pragma once
#endif
//----------------------------------------------------------------------------------------
#include "platform.h"
#include "engine/http.h"
#include "interface.h"
#include "tier0/threadtools.h"
//----------------------------------------------------------------------------------------
struct RequestContext_t;
class CHttpDownloader;
class KeyValues;
//----------------------------------------------------------------------------------------
class IDownloadHandler
{
public:
virtual void OnConnecting( CHttpDownloader *pDownloader ) = 0;
virtual void OnFetch( CHttpDownloader *pDownloader ) = 0;
// Called when the download is done successfully, errors out, or is aborted.
// NOTE: pDownloader should NOT be deleted from within OnDownloadComplete().
// pData contains the downloaded data for processing.
virtual void OnDownloadComplete( CHttpDownloader *pDownloader, const unsigned char *pData ) = 0;
};
//----------------------------------------------------------------------------------------
//
// Generic downloader class - downloads a single file on its own thread, and maintains
// state for that data.
//
// TODO: Derive from CBaseThinker and remove explicit calls to Think() - will make this
// class less bug-prone (easy to forget to call Think()).
//
class CHttpDownloader
{
public:
// Pass in a callback
CHttpDownloader( IDownloadHandler *pHandler = NULL );
~CHttpDownloader();
//
// Download the file at the given URL (HTTP/HTTPS support only)
// pGamePath - Game path where we should put the file - can be NULL if we don't
// want to save to the file to disk
// pUserData - Passed back to IDownloadHandler, if one has been set - can be NULL
// pBytesDownloaded - If non-NULL, # of bytes downloaded written.
// Returns true on success.
//
bool BeginDownload( const char *pURL, const char *pGamePath = NULL,
void *pUserData = NULL, uint32 *pBytesDownloaded = NULL );
//
// Abort the download (if there is one), wait for the download to shutdown and
// do cleanup.
//
void AbortDownloadAndCleanup();
inline bool IsDone() const { return m_bDone; } // Download done?
inline bool CanDelete() const { return m_pThreadState == NULL; } // Can free?
inline HTTPStatus_t GetStatus() const { return m_nHttpStatus; }
inline HTTPError_t GetError() const { return m_nHttpError; }
inline void *GetUserData() const { return m_pUserData; }
inline uint32 GetBytesDownloaded() const { return m_uBytesDownloaded; }
inline uint32 GetSize() const { return m_uSize; } // File size in bytes - NOTE: Not valid until the download is complete, aborted, or errored out
inline const char *GetURL() const { return m_szURL; }
void Think();
KeyValues *GetOgsRow( int nErrorCounter ) const;
static const char *GetHttpErrorToken( HTTPError_t nError );
private:
bool CleanupThreadIfDone();
void InvokeHandler();
RequestContext_t *m_pThreadState;
float m_flNextThinkTime;
bool m_bDone;
HTTPError_t m_nHttpError;
HTTPStatus_t m_nHttpStatus;
uint32 m_uBytesDownloaded;
uint32 *m_pBytesDownloaded; // Passed into BeginDownload()
uint32 m_uSize;
IDownloadHandler *m_pHandler;
void *m_pUserData;
char m_szURL[512];
// Use this to make sure that AbortDownloadAndCleanup isn't executed simultaneously
// by two threads. This was causing use-after-free crashes during shutdown.
CThreadMutex m_lock;
};
//----------------------------------------------------------------------------------------
#endif // CL_DOWNLOADER_H