Merge pull request 'WebResourceLoader class' (#51) from webresourceloader into master
Reviewed-on: https://git.madvoxel.net/OpenVulkano/OpenVulkano/pulls/51 Reviewed-by: Georg Hagen <georg.hagen@madvoxel.com>
This commit is contained in:
92
openVulkanoCpp/Host/WebResourceLoader.cpp
Normal file
92
openVulkanoCpp/Host/WebResourceLoader.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 "Base/Logger.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;
|
||||
}
|
||||
}
|
||||
|
||||
bool WebResourceLoader::IsUrl(const std::string& str)
|
||||
{
|
||||
return str.find("http://") == 0 || str.find("https://") == 0 || str.find("ftp://") == 0;
|
||||
}
|
||||
|
||||
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);
|
||||
Logger::APP->error("Failed to download resource: '" + url + "' - " + curl_easy_strerror(result));
|
||||
return Array<char>();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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); }
|
||||
}
|
||||
return Array<char>();
|
||||
}
|
||||
}
|
||||
29
openVulkanoCpp/Host/WebResourceLoader.hpp
Normal file
29
openVulkanoCpp/Host/WebResourceLoader.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
public:
|
||||
static bool IsUrl(const std::string& str);
|
||||
|
||||
WebResourceLoader();
|
||||
~WebResourceLoader();
|
||||
Array<char> GetResource(const std::string& resourceName) override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user