static void gtkhash_hash_file_read_finish( G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { data->just_read = g_input_stream_read_finish( G_INPUT_STREAM(data->stream), res, NULL); if (G_UNLIKELY(data->just_read == -1) && !g_cancellable_is_cancelled(data->cancellable)) { g_warning("failed to read file (%s)", data->uri); g_cancellable_cancel(data->cancellable); } else if (G_UNLIKELY(data->just_read == 0)) { g_warning("unexpected EOF (%s)", data->uri); g_cancellable_cancel(data->cancellable); } else { g_mutex_lock(data->priv.mutex); data->priv.total_read += data->just_read; const goffset total_read = data->priv.total_read; g_mutex_unlock(data->priv.mutex); if (G_UNLIKELY(total_read > data->file_size)) { g_warning("read %" G_GOFFSET_FORMAT " more bytes than expected (%s)", total_read - data->file_size, data->uri); g_cancellable_cancel(data->cancellable); } else gtkhash_hash_file_set_state(data, HASH_FILE_STATE_HASH); } if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) gtkhash_hash_file_set_state(data, HASH_FILE_STATE_CLOSE); gtkhash_hash_file_add_source(data); }
static void gtkhash_hash_file_hash_thread(void *func, struct hash_file_s *data) { gtkhash_hash_lib_update(&data->funcs[GPOINTER_TO_UINT(func) - 1], data->buffer, data->just_read); if (g_atomic_int_dec_and_test(&data->pool_threads_n)) gtkhash_hash_file_add_source(data); }
static void gtkhash_hash_file_close_finish( G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { if (G_UNLIKELY(!g_input_stream_close_finish(G_INPUT_STREAM(data->stream), res, NULL) && !g_cancellable_is_cancelled(data->cancellable))) { g_warning("failed to close file (%s)", data->uri); } g_object_unref(data->stream); gtkhash_hash_file_remove_report_source(data); gtkhash_hash_file_set_state(data, HASH_FILE_STATE_FINISH); gtkhash_hash_file_add_source(data); }
void hash_file_start(const char *uri) { if (gui_get_view() != GUI_VIEW_FILE_LIST) gtkhash_hash_file_clear_digests(&hash_priv.file_data); GFile *file = g_file_new_for_uri(uri); char *pname = g_file_get_parse_name(file); gtk_progress_bar_set_text(gui.progressbar, pname); g_free(pname); g_object_unref(file); gtkhash_hash_file_set_uri(&hash_priv.file_data, uri); gtkhash_hash_file_set_stop(&hash_priv.file_data, false); gtkhash_hash_file_set_state(&hash_priv.file_data, HASH_FILE_STATE_START); gtkhash_hash_file_add_source(&hash_priv.file_data); }
static void gtkhash_hash_file_get_size_finish( G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { GFileInfo *info = g_file_input_stream_query_info_finish( data->stream, res, NULL); data->file_size = g_file_info_get_size(info); g_object_unref(info); if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) gtkhash_hash_file_set_state(data, HASH_FILE_STATE_CLOSE); else if (data->file_size == 0) gtkhash_hash_file_set_state(data, HASH_FILE_STATE_HASH); else { gtkhash_hash_file_set_state(data, HASH_FILE_STATE_READ); gtkhash_hash_file_add_report_source(data); } gtkhash_hash_file_add_source(data); }
static void gtkhash_hash_file_hash(struct hash_file_s *data) { if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { gtkhash_hash_file_set_state(data, HASH_FILE_STATE_CLOSE); return; } gtkhash_hash_file_remove_source(data); gtkhash_hash_file_set_state(data, HASH_FILE_STATE_HASH_FINISH); g_atomic_int_inc(&data->pool_threads_n); for (unsigned int i = 0; i < HASH_FUNCS_N; i++) { if (data->funcs[i].enabled) { g_atomic_int_inc(&data->pool_threads_n); g_thread_pool_push(data->thread_pool, GUINT_TO_POINTER(i + 1), NULL); } } if (g_atomic_int_dec_and_test(&data->pool_threads_n)) gtkhash_hash_file_add_source(data); }
static void gtkhash_hash_file_open_finish( G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { data->stream = g_file_read_finish(data->file, res, NULL); if (G_UNLIKELY(!data->stream && !g_cancellable_is_cancelled(data->cancellable))) { g_warning("failed to open file (%s)", data->uri); g_cancellable_cancel(data->cancellable); } if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { if (data->stream) gtkhash_hash_file_set_state(data, HASH_FILE_STATE_CLOSE); else gtkhash_hash_file_set_state(data, HASH_FILE_STATE_FINISH); } else gtkhash_hash_file_set_state(data, HASH_FILE_STATE_GET_SIZE); gtkhash_hash_file_add_source(data); }