From 4be4bb926a688cd634c9481da4aaf1ebcf30ae1f Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Fri, 5 Jun 2026 16:27:05 +0300 Subject: [PATCH] new realization of cancel download [need review] --- src/file_processor.c | 116 ++++++++++++++++++++++++++++--------------- src/main.c | 1 - src/main.h | 5 +- src/modals/load_pr.c | 12 ++--- src/query.c | 4 +- src/utils/utils.h | 11 ++-- 6 files changed, 94 insertions(+), 55 deletions(-) diff --git a/src/file_processor.c b/src/file_processor.c index 8b8933e..ce36ba3 100644 --- a/src/file_processor.c +++ b/src/file_processor.c @@ -102,61 +102,97 @@ int32_t ui_file_select(file_args_t *f_args, query_args_t *q_args, int32_t idx) { } server_send_string(q_args, "file download [%s]\n", f_selected->name); q_args->state = S_DOWNLOAD_FILE; + + q_args->file = malloc(sizeof(p_file_t)); + q_args->file->name = f_selected->name; + q_args->file->rest = f_selected->size; + q_args->file->size = f_selected->size; + q_args->file->package_rest = PACKAGE_SIZE; + q_args->file->signal = sig_continue; + q_args->file->it_count = 0; + q_args->file->fd = f_args->file_d; + + q_args->file->it_interval = + (f_selected->size / INBUFSIZE / 100); /* every 1% */ + if (q_args->file->it_interval == 0) + q_args->file->it_interval = 1; + free(file_path); return OK; } +#define file_download_receive_after(qlen, q_args, f_args, d, pb) \ + { \ + if (qlen) { \ + q_args->file->it_count++; \ + q_args->file->package_rest -= qlen; \ + if (!(q_args->file->it_count % q_args->file->it_interval)) { \ + pb->percentage = progress; \ + d->needs_update = true; \ + } else { \ + q_args->buf_used = 0; \ + } \ + if (q_args->file->rest < qlen) { \ + q_args->file->rest = 0; \ + } else { \ + q_args->file->rest -= qlen; \ + } \ + if (q_args->file->rest == 0) { \ + q_args->file->it_count = 0; \ + q_args->file->it_interval = 0; \ + f_selected->size = 0; \ + close(f_args->file_d); \ + d->needs_destroy = true; \ + sprintf(answer, "File %s is downloaded from the server!", \ + f_selected->name); \ + q_args->notification = malloc(strlen(answer) + 1); \ + strcpy(q_args->notification, answer); \ + free(f_selected->name); \ + server_send_string(q_args, "file list %d %d\n%n", fui->max_lines, \ + fui->current_page, &a_len); \ + q_args->state = S_FILE_LIST; \ + } \ + } \ + } + +/* TODO: revise */ void file_download(file_args_t *f_args, query_args_t *q_args) { fl_item_t *f_selected = &(f_args->f_selected); - static int32_t it_count = 0; - static size_t it_interval = 0; - - if (it_interval == 0) { - it_interval = (f_selected->size / INBUFSIZE / 100) * 5; /* every 1% */ - if (it_interval == 0) - it_interval = 1; - } char answer[256]; - static size_t size_rest = 0; - int32_t progress = (f_selected->size - size_rest) * 100 / f_selected->size; + int32_t progress = + (f_selected->size - q_args->file->rest) * 100 / f_selected->size; w_pgb_ui_t *pb = (w_pgb_ui_t *)q_args->progress_bar; w_dialogue_t *d = (w_dialogue_t *)q_args->active_dialogue; w_ui_file_list_t *fui = (w_ui_file_list_t *)q_args->main_ui->ui; int32_t a_len = 0; + int32_t qlen; - if (size_rest == 0 && it_count == 0) - size_rest = f_selected->size; - int32_t qlen = write(f_args->file_d, q_args->buf, q_args->buf_used); - if (qlen) { - it_count++; - if (!(it_count % it_interval)) { - pb->percentage = progress; - d->needs_update = true; - } else { - q_args->buf_used = 0; - } - if (size_rest < qlen) { - size_rest = 0; - } else { - size_rest -= qlen; - } - if (size_rest == 0) { - it_count = 0; - it_interval = 0; - f_selected->size = 0; - close(f_args->file_d); + int write_len = q_args->buf_used; + + if (q_args->file->package_rest <= q_args->buf_used) { + write_len = q_args->file->package_rest; + qlen = write(f_args->file_d, q_args->buf, write_len); + file_download_receive_after(qlen, q_args, f_args, d, pb) + server_send_string(q_args, "continue\n"); + if (q_args->file->signal == sig_continue) { + q_args->file->package_rest = PACKAGE_SIZE; + if (q_args->file->package_rest == q_args->buf_used) { + return; + } + int buf_offset = q_args->file->package_rest; + write_len = q_args->buf_used - q_args->file->package_rest; + qlen = write(f_args->file_d, q_args->buf + buf_offset, write_len); + file_download_receive_after(qlen, q_args, f_args, d, pb) return; + } else if (q_args->file->signal == sig_cancel) { + server_send_string(q_args, "cancel\n"); + FILE_CLEAN(q_args->file); d->needs_destroy = true; - sprintf(answer, "File %s is downloaded from the server!", - f_selected->name); - q_args->notification = malloc(strlen(answer) + 1); - strcpy(q_args->notification, answer); - free(f_selected->name); - server_send_string(q_args, "file list %d %d\n%n", fui->max_lines, - fui->current_page, &a_len); - q_args->state = S_FILE_LIST; + return; } } + qlen = write(f_args->file_d, q_args->buf, write_len); + file_download_receive_after(qlen, q_args, f_args, d, pb) } int32_t file_upload_open(char *dpath, char *fname, query_args_t *q_args) { @@ -205,7 +241,7 @@ int32_t file_upload_start(query_args_t *q_args) { } else { \ it_count++; \ if (!(it_count % it_interval)) { \ - pb->percentage = progress; \ + pb->percentage = progress; \ d->needs_update = true; \ } \ q_args->file->rest -= wlen; \ diff --git a/src/main.c b/src/main.c index 390a1ce..3b128d1 100644 --- a/src/main.c +++ b/src/main.c @@ -42,7 +42,6 @@ int main(int argc, char **argv) { /* init alert */ w_alert_init(app); - w_alert("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem."); init_query_args(q_args, app->params); q_args->buf = malloc(INBUFSIZE); diff --git a/src/main.h b/src/main.h index 74a824f..4b07ae3 100644 --- a/src/main.h +++ b/src/main.h @@ -73,6 +73,9 @@ typedef struct p_file { char *description; size_t size; size_t rest; + size_t package_rest; + int32_t it_count; + size_t it_interval; enum package_signal signal; int fd; } p_file_t; @@ -105,7 +108,7 @@ typedef struct main_window { void *ui; /* structure which describes window UI */ int32_t (*cb_b_press)(void *app, void *args); /* callback on button press */ void (*cb_ui_refresh)(void *app); /* refresh callback */ - void (*reset)(void *app); /* function to reset the state of the window */ + void (*reset)(void *app); /* function to reset the state of the window */ draw_f_t *draw; struct action_key *b_keys; int32_t b_keys_len; diff --git a/src/modals/load_pr.c b/src/modals/load_pr.c index 1a76c00..1ffd835 100644 --- a/src/modals/load_pr.c +++ b/src/modals/load_pr.c @@ -1,9 +1,9 @@ #include "../server.h" +#include "../windows/file_list.h" #include "alert.h" #include "dialogue.h" #include "group.h" #include "utils.h" -#include "../windows/file_list.h" #include #include #include @@ -13,11 +13,11 @@ void dwn_pr_modal_cb(w_cb_args_t *args) { /* only cancel action */ int32_t key = *((int32_t *)args->data); - + if (key != '\n') { return; } - + app_t *app = args->app; w_dialogue_t *d = &(app->modal); /* TODO: forward actual file name */ @@ -32,9 +32,9 @@ void dwn_pr_modal_cb(w_cb_args_t *args) { bool response = w_bool_ask("Cancel file download", "Yes", "No", false, "You're going to cancel download\n Are you sure?"); - server_send_string(app->query_args, "cancel\n"); - FILE_CLEAN(app); - d->needs_destroy = true; + if (response) { + app->query_args->file->signal = sig_cancel; + } } } diff --git a/src/query.c b/src/query.c index 32970fc..fd0b4c6 100644 --- a/src/query.c +++ b/src/query.c @@ -183,7 +183,7 @@ int process_query(app_t *app) { if (!file_upload_start(query_args)) { query_args->state = S_UPLOAD_FILE; } else { - FILE_CLEAN(app); + FILE_CLEAN(app->query_args->file); query_args->state = WAIT_CLIENT; } break; @@ -198,7 +198,7 @@ int process_query(app_t *app) { /* cancel case */ w_notification("Alert", dc_alert, "File %s didn't upload!", query_args->file->name); - FILE_CLEAN(app); + FILE_CLEAN(app->query_args->file); w_dialogue_t *d = &(app->modal); d->needs_destroy = true; query_args->state = WAIT_CLIENT; diff --git a/src/utils/utils.h b/src/utils/utils.h index 9fa510b..ebf4543 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -10,10 +10,11 @@ arg = NULL; \ } -#define FILE_CLEAN(app) \ - if (app->query_args->file != NULL) { \ - FREE_MLC(app->query_args->file->name); \ - FREE_MLC(app->query_args->file->path); \ - FREE_MLC(app->query_args->file); \ +#define FILE_CLEAN(file) \ + if (file != NULL) { \ + FREE_MLC(file->name); \ + FREE_MLC(file->path); \ + FREE_MLC(file); \ + file = NULL; \ } #endif \ No newline at end of file