2025-10-09 13:04:39 +03:00
|
|
|
#ifdef __EMSCRIPTEN__
|
|
|
|
|
#include "FileDownloader.hpp"
|
|
|
|
|
#include <cstdio>
|
2025-10-09 17:58:12 +03:00
|
|
|
#include <iostream>
|
2025-10-09 13:04:39 +03:00
|
|
|
|
|
|
|
|
std::vector<FileDownloader::DownloadHandler> FileDownloader::currentDownloads;
|
|
|
|
|
|
2025-10-09 17:58:12 +03:00
|
|
|
void FileDownloader::download_progress(emscripten_fetch_t *fetch) {
|
|
|
|
|
DownloadData* downData = static_cast<DownloadData*>(fetch->userData);
|
|
|
|
|
if(fetch->totalBytes == 0)
|
|
|
|
|
downData->progress = 0.0f;
|
|
|
|
|
else
|
|
|
|
|
downData->progress = static_cast<float>(fetch->dataOffset) / static_cast<float>(fetch->totalBytes);
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-09 13:04:39 +03:00
|
|
|
void FileDownloader::download_succeeded(emscripten_fetch_t *fetch) {
|
|
|
|
|
DownloadData* downData = static_cast<DownloadData*>(fetch->userData);
|
|
|
|
|
downData->str = std::string(fetch->data, fetch->numBytes);
|
2025-10-11 13:02:07 +03:00
|
|
|
|
|
|
|
|
size_t headerLength = emscripten_fetch_get_response_headers_length(fetch);
|
|
|
|
|
if(headerLength != 0) {
|
|
|
|
|
std::string header(headerLength + 1, ' ');
|
|
|
|
|
emscripten_fetch_get_response_headers(fetch, header.data(), header.size() + 1);
|
|
|
|
|
if(!header.empty())
|
|
|
|
|
header.pop_back(); // Remove additional null terminator
|
|
|
|
|
std::string newFilename = parse_http_headers_for_filename(header);
|
|
|
|
|
if(!newFilename.empty())
|
|
|
|
|
downData->fileName = newFilename;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-09 13:04:39 +03:00
|
|
|
downData->status = DownloadData::Status::SUCCESS;
|
2025-10-11 13:02:07 +03:00
|
|
|
|
2025-10-09 13:04:39 +03:00
|
|
|
std::erase_if(currentDownloads, [fetch](DownloadHandler& d) {
|
|
|
|
|
return (DownloadData*)fetch->userData == d.data.get();
|
|
|
|
|
});
|
2025-10-11 13:02:07 +03:00
|
|
|
|
2025-10-09 13:04:39 +03:00
|
|
|
emscripten_fetch_close(fetch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FileDownloader::download_failed(emscripten_fetch_t *fetch) {
|
|
|
|
|
DownloadData* downData = static_cast<DownloadData*>(fetch->userData);
|
|
|
|
|
downData->status = DownloadData::Status::FAILURE;
|
|
|
|
|
std::erase_if(currentDownloads, [fetch](DownloadHandler& d) {
|
|
|
|
|
return (DownloadData*)fetch->userData == d.data.get();
|
|
|
|
|
});
|
|
|
|
|
emscripten_fetch_close(fetch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FileDownloader::init() {
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-11 13:02:07 +03:00
|
|
|
std::shared_ptr<FileDownloader::DownloadData> FileDownloader::download_data_from_url(const std::string& url) {
|
2025-10-09 13:04:39 +03:00
|
|
|
DownloadHandler& newDownload = currentDownloads.emplace_back();
|
|
|
|
|
newDownload.data = std::make_shared<DownloadData>();
|
2025-10-11 13:02:07 +03:00
|
|
|
newDownload.data->fileName = get_potential_filename_from_url(url);
|
2025-10-09 13:04:39 +03:00
|
|
|
|
|
|
|
|
emscripten_fetch_attr_t attr;
|
|
|
|
|
emscripten_fetch_attr_init(&attr);
|
|
|
|
|
std::strcpy(attr.requestMethod, "GET");
|
|
|
|
|
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
|
|
|
|
|
attr.onsuccess = download_succeeded;
|
2025-10-09 17:58:12 +03:00
|
|
|
attr.onprogress = download_progress;
|
2025-10-09 13:04:39 +03:00
|
|
|
attr.onerror = download_failed;
|
|
|
|
|
attr.userData = static_cast<void*>(newDownload.data.get());
|
|
|
|
|
emscripten_fetch(&attr, url.data());
|
|
|
|
|
|
|
|
|
|
return newDownload.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FileDownloader::cleanup() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|