WebResourceLoader class
IMPORTANT: The class cannot download from https:// sources because OpenSSL is turned off in curl CMakeLists.txt
This commit is contained in:
90
openVulkanoCpp/Host/WebResourceLoader.cpp
Normal file
90
openVulkanoCpp/Host/WebResourceLoader.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WebResourceLoader.hpp"
|
||||||
|
#include "IO/AppFolders.hpp"
|
||||||
|
#include "Base/Utils.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
size_t curlDownloader(void* contents, size_t size, size_t memBlockCount, void* userData)
|
||||||
|
{
|
||||||
|
size_t totalSize = size * memBlockCount;
|
||||||
|
std::vector<char>* buffer = static_cast<std::vector<char>*>(userData);
|
||||||
|
buffer->insert(buffer->end(), static_cast<char*>(contents), static_cast<char*>(contents) + totalSize);
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebResourceLoader::WebResourceLoader()
|
||||||
|
{
|
||||||
|
m_cacheDirectory = AppFolders::GetAppCacheDir() / "resources";
|
||||||
|
std::filesystem::create_directories(m_cacheDirectory);
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebResourceLoader::~WebResourceLoader() { curl_global_cleanup(); }
|
||||||
|
|
||||||
|
std::filesystem::path WebResourceLoader::GetCacheFilePath(const std::string& url)
|
||||||
|
{
|
||||||
|
size_t hash = std::hash<std::string> {}(url);
|
||||||
|
std::string hashedUrl = std::to_string(hash);
|
||||||
|
|
||||||
|
return m_cacheDirectory / hashedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<char> WebResourceLoader::DownloadResource(const std::string& url)
|
||||||
|
{
|
||||||
|
std::vector<char> buffer;
|
||||||
|
|
||||||
|
CURL* curl = curl_easy_init();
|
||||||
|
if (curl)
|
||||||
|
{
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlDownloader);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSLENGINE, "DarwinSSL");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CURLcode result = curl_easy_perform(curl);
|
||||||
|
if (result != CURLE_OK)
|
||||||
|
{
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
throw std::runtime_error("Failed to download resource: '" + url + "' - " + curl_easy_strerror(result));
|
||||||
|
}
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path cacheFilePath = GetCacheFilePath(url);
|
||||||
|
std::ofstream file(cacheFilePath, std::ios::binary);
|
||||||
|
file.write(buffer.data(), buffer.size());
|
||||||
|
return Array<char>(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebResourceLoader::IsUrl(const std::string& str)
|
||||||
|
{
|
||||||
|
return str.find("http://") == 0 || str.find("https://") == 0 || str.find("ftp://") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<char> WebResourceLoader::GetResource(const std::string& resourceName)
|
||||||
|
{
|
||||||
|
if (IsUrl(resourceName))
|
||||||
|
{
|
||||||
|
std::filesystem::path cacheFilePath = GetCacheFilePath(resourceName);
|
||||||
|
if (std::filesystem::exists(cacheFilePath)) { return Utils::ReadFile(cacheFilePath.string()); }
|
||||||
|
else { return DownloadResource(resourceName); }
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Resource name is not a valid URL");
|
||||||
|
}
|
||||||
|
}
|
||||||
28
openVulkanoCpp/Host/WebResourceLoader.hpp
Normal file
28
openVulkanoCpp/Host/WebResourceLoader.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ResourceLoader.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
class WebResourceLoader : public ResourceLoader
|
||||||
|
{
|
||||||
|
std::filesystem::path m_cacheDirectory;
|
||||||
|
|
||||||
|
std::filesystem::path GetCacheFilePath(const std::string& url);
|
||||||
|
Array<char> DownloadResource(const std::string& url);
|
||||||
|
bool IsUrl(const std::string& str);
|
||||||
|
|
||||||
|
public:
|
||||||
|
WebResourceLoader();
|
||||||
|
~WebResourceLoader();
|
||||||
|
Array<char> GetResource(const std::string& resourceName) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user