diff --git a/source/core/http.c b/source/core/http.c index 481b45e..6a0febb 100644 --- a/source/core/http.c +++ b/source/core/http.c @@ -278,6 +278,7 @@ typedef struct { u64* contentLength; void* userData; Result (*callback)(void* userData, void* buffer, size_t size); + Result (*checkRunning)(void* userData); void* buf; u32 pos; @@ -312,6 +313,10 @@ static size_t http_curl_header_callback(char* buffer, size_t size, size_t nitems static size_t http_curl_write_callback(char* ptr, size_t size, size_t nmemb, void* userdata) { http_curl_data* curlData = (http_curl_data*) userdata; + if(curlData->checkRunning != NULL && R_FAILED(curlData->res = curlData->checkRunning(curlData->userData))) { + return 0; + } + size_t srcPos = 0; size_t available = size * nmemb; while(available > 0) { @@ -333,7 +338,8 @@ static size_t http_curl_write_callback(char* ptr, size_t size, size_t nmemb, voi return R_SUCCEEDED(curlData->res) ? size * nmemb : 0; } -Result http_download_callback(const char* url, u32 bufferSize, u64* contentLength, void* userData, Result (*callback)(void* userData, void* buffer, size_t size)) { +Result http_download_callback(const char* url, u32 bufferSize, u64* contentLength, void* userData, Result (*callback)(void* userData, void* buffer, size_t size), + Result (*checkRunning)(void* userData)) { Result res = 0; void* buf = malloc(bufferSize); @@ -349,6 +355,7 @@ Result http_download_callback(const char* url, u32 bufferSize, u64* contentLengt u32 total = 0; u32 currSize = 0; while(total < dlSize + && (checkRunning == NULL || R_SUCCEEDED(res = checkRunning(userData))) && R_SUCCEEDED(res = http_read(context, &currSize, buf, bufferSize)) && R_SUCCEEDED(res = callback(userData, buf, currSize))) { total += currSize; @@ -364,7 +371,7 @@ Result http_download_callback(const char* url, u32 bufferSize, u64* contentLengt CURL* curl = curl_easy_init(); if(curl != NULL) { - http_curl_data curlData = {bufferSize, contentLength, userData, callback, buf, 0, 0}; + http_curl_data curlData = {bufferSize, contentLength, userData, callback, checkRunning, buf, 0, 0}; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_USERAGENT, HTTP_USER_AGENT); @@ -445,7 +452,7 @@ static Result http_download_buffer_callback(void* userData, void* buffer, size_t Result http_download_buffer(const char* url, u32* downloadedSize, void* buf, size_t size) { http_buffer_data data = {buf, size, 0}; - Result res = http_download_callback(url, size, NULL, &data, http_download_buffer_callback); + Result res = http_download_callback(url, size, NULL, &data, http_download_buffer_callback, NULL); if(R_SUCCEEDED(res)) { *downloadedSize = data.pos; diff --git a/source/core/http.h b/source/core/http.h index abb3cff..0842801 100644 --- a/source/core/http.h +++ b/source/core/http.h @@ -9,7 +9,8 @@ Result http_get_size(http_context context, u32* size); Result http_get_file_name(http_context context, char* out, u32 size); Result http_read(http_context context, u32* bytesRead, void* buffer, u32 size); -Result http_download_callback(const char* url, u32 bufferSize, u64* contentLength, void* userData, Result (*callback)(void* userData, void* buffer, size_t size)); +Result http_download_callback(const char* url, u32 bufferSize, u64* contentLength, void* userData, Result (*callback)(void* userData, void* buffer, size_t size), + Result (*checkRunning)(void* userData)); Result http_download_buffer(const char* url, u32* downloadedSize, void* buf, size_t size); Result http_download_json(const char* url, json_t** json, size_t maxSize); Result http_download_seed(u64 titleId); \ No newline at end of file diff --git a/source/core/task/dataop.c b/source/core/task/dataop.c index bba719d..ed6e5c9 100644 --- a/source/core/task/dataop.c +++ b/source/core/task/dataop.c @@ -155,44 +155,48 @@ static Result task_data_op_download_callback(void* userData, void* buffer, size_ Result res = 0; - if(R_SUCCEEDED(res = task_data_op_check_running(data))) { - if(downloadData->firstRun) { - downloadData->firstRun = false; + if(downloadData->firstRun) { + downloadData->firstRun = false; - if(R_FAILED(res = data->openDst(data->data, downloadData->index, buffer, data->currTotal, &downloadData->dstHandle))) { - return res; - } + if(R_FAILED(res = data->openDst(data->data, downloadData->index, buffer, data->currTotal, &downloadData->dstHandle))) { + return res; } + } - u32 bytesWritten = 0; - if(R_SUCCEEDED(res = data->writeDst(data->data, downloadData->dstHandle, &bytesWritten, buffer, data->currProcessed, size))) { - data->currProcessed += bytesWritten; - downloadData->bytesSinceUpdate += bytesWritten; + u32 bytesWritten = 0; + if(R_SUCCEEDED(res = data->writeDst(data->data, downloadData->dstHandle, &bytesWritten, buffer, data->currProcessed, size))) { + data->currProcessed += bytesWritten; + downloadData->bytesSinceUpdate += bytesWritten; - u64 time = osGetTime(); - u64 elapsed = time - downloadData->lastBytesPerSecondUpdate; - if(elapsed >= 1000) { - data->bytesPerSecond = (u32) (downloadData->bytesSinceUpdate / (elapsed / 1000.0f)); + u64 time = osGetTime(); + u64 elapsed = time - downloadData->lastBytesPerSecondUpdate; + if(elapsed >= 1000) { + data->bytesPerSecond = (u32) (downloadData->bytesSinceUpdate / (elapsed / 1000.0f)); - if(downloadData->ioStartTime != 0) { - data->estimatedRemainingSeconds = (u32) ((data->currTotal - data->currProcessed) / (data->currProcessed / ((time - downloadData->ioStartTime) / 1000.0f))); - } else { - data->estimatedRemainingSeconds = 0; - } - - if(downloadData->ioStartTime == 0 && data->currProcessed > 0) { - downloadData->ioStartTime = time; - } - - downloadData->bytesSinceUpdate = 0; - downloadData->lastBytesPerSecondUpdate = time; + if(downloadData->ioStartTime != 0) { + data->estimatedRemainingSeconds = (u32) ((data->currTotal - data->currProcessed) / (data->currProcessed / ((time - downloadData->ioStartTime) / 1000.0f))); + } else { + data->estimatedRemainingSeconds = 0; } + + if(downloadData->ioStartTime == 0 && data->currProcessed > 0) { + downloadData->ioStartTime = time; + } + + downloadData->bytesSinceUpdate = 0; + downloadData->lastBytesPerSecondUpdate = time; } } return res; } +static Result task_data_op_download_check_running(void* userData) { + data_op_download_data* downloadData = (data_op_download_data*) userData; + + return task_data_op_check_running(downloadData->data); +} + static Result task_data_op_download(data_op_data* data, u32 index) { data->currProcessed = 0; data->currTotal = 0; @@ -205,7 +209,7 @@ static Result task_data_op_download(data_op_data* data, u32 index) { char url[DOWNLOAD_URL_MAX]; if(R_SUCCEEDED(res = data->getSrcUrl(data->data, index, url, DOWNLOAD_URL_MAX))) { data_op_download_data downloadData = {data, index, 0, true, 0, osGetTime(), 0}; - res = http_download_callback(url, data->bufferSize, &data->currTotal, &downloadData, task_data_op_download_callback); + res = http_download_callback(url, data->bufferSize, &data->currTotal, &downloadData, task_data_op_download_callback, task_data_op_download_check_running); if(downloadData.dstHandle != 0) { Result closeDstRes = data->closeDst(data->data, index, res == 0, downloadData.dstHandle);