Created
October 19, 2013 07:04
-
-
Save c4pt0r/7052512 to your computer and use it in GitHub Desktop.
Downloader Draft
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2013 The Wandoujia Authors. All rights reserved. | |
#ifndef PLATFORM_WDJ_CONNECTION_WRAPPER_WDJ_CONNECTION_DOWNLOADER_H_ | |
#define PLATFORM_WDJ_CONNECTION_WRAPPER_WDJ_CONNECTION_DOWNLOADER_H_ | |
#include <windows.h> | |
#include <map> | |
#include "net/win_http.h" | |
// | |
class EngineDownloader: async_wininet::WinHTTPListener { | |
public: | |
static EngineDownloader* GetInstance(); | |
public: | |
class Listener { | |
public: | |
virtual void OnProgress(size_t cur_bytes, size_t total) = 0; | |
virtual void OnComplete(const std::string& buf) = 0; | |
virtual void OnError(DWORD code) = 0; | |
// if save to file, user need provide fp | |
virtual FILE* fp() { return NULL; } | |
}; | |
void Init(); | |
void Uninit(); | |
DWORD Download(const std::string& url, Listener* listener); | |
void Stop(DWORD id); | |
void StopAll(); | |
public: | |
virtual void OnRedirect(DWORD request_id); | |
virtual void OnBegin(DWORD request_id); | |
virtual void OnProgress(DWORD request_id); | |
virtual void OnComplete(DWORD request_id); | |
virtual void OnError(DWORD request_id); | |
private: | |
EngineDownloader() {} | |
virtual ~EngineDownloader() {} | |
private: | |
inline Listener* GetListener(DWORD request_id); | |
inline const async_wininet::WinHTTP::Request* GetRequest(DWORD request_id); | |
inline void RemoveListener(DWORD request_id); | |
private: | |
async_wininet::WinHTTP* downloader_; | |
typedef std::map<DWORD, Listener*> ListenerMap; | |
typedef std::map<DWORD, std::string> BufMap; | |
ListenerMap listeners_; | |
BufMap buf_; | |
}; | |
#endif // PLATFORM_WDJ_CONNECTION_WRAPPER_WDJ_CONNECTION_DOWNLOADER_H_ | |
////////////////////////////////////////////////////////////////////// | |
// Copyright (c) 2013 The Wandoujia Authors. All rights reserved. | |
#include "wdj_connection_wrapper/wdj_connection_downloader.h" | |
namespace { | |
static EngineDownloader* instance = NULL; | |
} | |
inline EngineDownloader::Listener* EngineDownloader::GetListener(DWORD request_id) { | |
if (listeners_.find(request_id) != listeners_.end()) | |
return listeners_[request_id]; | |
return NULL; | |
} | |
inline const async_wininet::WinHTTP::Request* EngineDownloader::GetRequest(DWORD request_id) { | |
return downloader_->FindRequest(request_id); | |
} | |
inline void EngineDownloader::RemoveListener(DWORD request_id) { | |
downloader_->RemoveRequest(request_id); | |
listeners_.erase(request_id); | |
buf_.erase(request_id); | |
} | |
void EngineDownloader::OnRedirect(DWORD request_id) { | |
} | |
void EngineDownloader::OnBegin(DWORD request_id) { | |
} | |
void EngineDownloader::OnProgress(DWORD request_id) { | |
using namespace async_wininet; | |
Listener* listener = GetListener(request_id); | |
if (listener) { | |
const WinHTTP::Request* req = GetRequest(request_id); | |
// if fp is not NULL, means need write to file | |
if (FILE* fp = listener->fp()) { | |
fwrite(req->internet_buffer.lpvBuffer, | |
req->internet_buffer.dwBufferLength, 1, fp); | |
} else { | |
// We need buffer! for download text | |
std::string t((char*)req->internet_buffer.lpvBuffer, | |
req->internet_buffer.dwBufferLength); | |
buf_[request_id] += t; | |
} | |
listener->OnProgress(req->internet_buffer.dwBufferTotal, | |
req->content_length); | |
} | |
} | |
void EngineDownloader::OnComplete(DWORD request_id) { | |
using namespace async_wininet; | |
Listener* listener = GetListener(request_id); | |
if (listener) { | |
const WinHTTP::Request* req = GetRequest(request_id); | |
// if fp is not NULL, means need write to file | |
if (FILE* fp = listener->fp()) { | |
fclose(fp); | |
listener->OnComplete(""); | |
} else { | |
// We need buffer! for download text | |
listener->OnComplete(buf_[request_id]); | |
} | |
RemoveListener(request_id); | |
} | |
} | |
void EngineDownloader::OnError(DWORD request_id) { | |
using namespace async_wininet; | |
Listener* listener = GetListener(request_id); | |
if (listener) { | |
const WinHTTP::Request* req = GetRequest(request_id); | |
// if fp is not NULL, means need write to file | |
if (FILE* fp = listener->fp()) { | |
fclose(fp); | |
} | |
listener->OnError(req->error_code); | |
RemoveListener(request_id); | |
} | |
} | |
DWORD EngineDownloader::Download(const std::string& url, EngineDownloader::Listener* listener) { | |
async_wininet::WinHTTPRequestParam param; | |
param.url = url; | |
param.http_verb = async_wininet::kWinHTTPRequestGET; | |
DWORD request_id = downloader_->RequestUrl(param); | |
listeners_[request_id] = listener; | |
buf_[request_id] = std::string(4096, '\0'); | |
return request_id; | |
} | |
EngineDownloader* EngineDownloader::GetInstance() { | |
if (instance == NULL) { | |
instance = new EngineDownloader(); | |
instance->Init(); | |
} | |
return instance; | |
} | |
void EngineDownloader::Init() { | |
if (downloader_ == NULL) { | |
downloader_ = new async_wininet::WinHTTP("WDJConnEngine", this); | |
} | |
} | |
void EngineDownloader::Uninit() { | |
if (downloader_) { | |
delete downloader_; | |
downloader_ = NULL; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment