Spaces:
Sleeping
Sleeping
//======================================================================== | |
// | |
// CurlCachedFile.cc | |
// | |
// This file is licensed under the GPLv2 or later | |
// | |
// Copyright 2009 Stefan Thomas <[email protected]> | |
// Copyright 2010, 2011 Hib Eris <[email protected]> | |
// Copyright 2010, 2019, 2021, 2022 Albert Astals Cid <[email protected]> | |
// | |
//======================================================================== | |
//------------------------------------------------------------------------ | |
CurlCachedFileLoader::CurlCachedFileLoader(const std::string &urlA) : url(urlA) | |
{ | |
cachedFile = nullptr; | |
curl = nullptr; | |
} | |
CurlCachedFileLoader::~CurlCachedFileLoader() | |
{ | |
curl_easy_cleanup(curl); | |
} | |
static size_t noop_cb(char *ptr, size_t size, size_t nmemb, void *ptr2) | |
{ | |
return size * nmemb; | |
} | |
size_t CurlCachedFileLoader::init(CachedFile *cachedFileA) | |
{ | |
curl_off_t contentLength = -1; | |
long code = 0; | |
size_t size; | |
cachedFile = cachedFileA; | |
curl = curl_easy_init(); | |
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | |
curl_easy_setopt(curl, CURLOPT_HEADER, 1); | |
curl_easy_setopt(curl, CURLOPT_NOBODY, 1); | |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_cb); | |
curl_easy_perform(curl); | |
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); | |
if (code) { | |
curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &contentLength); | |
size = contentLength; | |
} else { | |
error(errInternal, -1, "Failed to get size of '{0:s}'.", url.c_str()); | |
size = -1; | |
} | |
curl_easy_reset(curl); | |
return size; | |
} | |
static size_t load_cb(const char *ptr, size_t size, size_t nmemb, void *data) | |
{ | |
CachedFileWriter *writer = (CachedFileWriter *)data; | |
return (writer->write)(ptr, size * nmemb); | |
} | |
int CurlCachedFileLoader::load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer) | |
{ | |
CURLcode r = CURLE_OK; | |
unsigned long long fromByte, toByte; | |
for (const ByteRange &bRange : ranges) { | |
fromByte = bRange.offset; | |
toByte = fromByte + bRange.length - 1; | |
const std::unique_ptr<GooString> range = GooString::format("{0:ulld}-{1:ulld}", fromByte, toByte); | |
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, load_cb); | |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, writer); | |
curl_easy_setopt(curl, CURLOPT_RANGE, range->c_str()); | |
r = curl_easy_perform(curl); | |
curl_easy_reset(curl); | |
if (r != CURLE_OK) { | |
break; | |
} | |
} | |
return r; | |
} | |
//------------------------------------------------------------------------ | |