/** * PRIVATE. Insert a region in a context. */ static inline int bfwork_region_insert(bam_fwork_t *fwork, bam_region_t *region) { linked_list_t *list; size_t list_l; assert(fwork); assert(region); omp_set_lock(&fwork->regions_lock); //List handle list = fwork->regions_list; list_l = linked_list_size(list); if(list_l >= FWORK_REGIONS_MAX) { omp_unset_lock(&fwork->regions_lock); //Wait for free slots if(!omp_test_lock(&fwork->free_slots)) { if(omp_get_num_threads() == 2) { #pragma omp taskwait //Force processing } omp_set_lock(&fwork->free_slots); } //LOG_FATAL_F("Not enough region slots, current: %d\n", list_l); } //This lock must be always locked until regions buffer have regions free omp_test_lock(&fwork->free_slots); //Add region to list linked_list_insert_last(region, list); omp_set_lock(®ion->lock); LOG_INFO_F("Inserting region %d:%lu-%lu with %d reads\n", region->chrom + 1, region->init_pos + 1, region->end_pos + 1, region->size); LOG_INFO_F("Regions to process %lu\n", linked_list_size(list)); omp_unset_lock(®ion->lock); omp_unset_lock(&fwork->regions_lock); return NO_ERROR; }
static void titles_filters_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { titles_data* listData = (titles_data*) data; if(hidKeysDown() & KEY_B) { linked_list_iter iter; linked_list_iterate(items, &iter); while(linked_list_iter_has_next(&iter)) { free(linked_list_iter_next(&iter)); linked_list_iter_remove(&iter); } ui_pop(); list_destroy(view); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { bool* val = (bool*) selected->data; *val = !(*val); selected->color = *val ? COLOR_ENABLED : COLOR_DISABLED; listData->populated = false; } if(linked_list_size(items) == 0) { titles_filters_add_entry(items, "Show game card", &listData->showGameCard); titles_filters_add_entry(items, "Show SD", &listData->showSD); titles_filters_add_entry(items, "Show NAND", &listData->showNAND); } }
static void files_filters_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { files_data* listData = (files_data*) data; if(hidKeysDown() & KEY_B) { linked_list_iter iter; linked_list_iterate(items, &iter); while(linked_list_iter_has_next(&iter)) { free(linked_list_iter_next(&iter)); linked_list_iter_remove(&iter); } ui_pop(); list_destroy(view); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { bool* val = (bool*) selected->data; *val = !(*val); selected->color = *val ? COLOR_ENABLED : COLOR_DISABLED; listData->populated = false; } if(linked_list_size(items) == 0) { files_filters_add_entry(items, "Show directories", &listData->showDirectories); files_filters_add_entry(items, "Show CIAs", &listData->showCias); files_filters_add_entry(items, "Show tickets", &listData->showTickets); files_filters_add_entry(items, "Show miscellaneous", &listData->showMisc); } }
/** * Destroy BAM framework data structure. */ void bfwork_destroy(bam_fwork_t *fwork) { int i; bam_region_t *region; linked_list_t *list; size_t list_l; assert(fwork); assert(fwork->regions_list); //Handle to list list = fwork->regions_list; //Regions exists? if(fwork->regions_list) { //for(i = 0; i < wanderer->regions_l; i++) list_l = linked_list_size(list); for(i = 0; i < list_l; i++) { //Get region region = linked_list_get(i, list); breg_destroy(region, 1); free(region); } linked_list_free(list, NULL); } //Destroy lock omp_destroy_lock(&fwork->regions_lock); omp_destroy_lock(&fwork->output_file_lock); omp_destroy_lock(&fwork->reference_lock); }
static void mainmenu_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { if(hidKeysDown() & KEY_START) { ui_pop(); list_destroy(view); return; } if(selected != NULL && (selectedTouched || hidKeysDown() & KEY_A) && selected->data != NULL) { ((void(*)()) selected->data)(); return; } if(linked_list_size(items) == 0) { linked_list_add(items, &sd); linked_list_add(items, &ctr_nand); linked_list_add(items, &twl_nand); linked_list_add(items, &twl_photo); linked_list_add(items, &twl_sound); linked_list_add(items, &dump_nand); linked_list_add(items, &titles); linked_list_add(items, &pending_titles); linked_list_add(items, &tickets); linked_list_add(items, &ext_save_data); linked_list_add(items, &system_save_data); linked_list_add(items, &titledb); linked_list_add(items, &network_install); linked_list_add(items, &qr_code_install); linked_list_add(items, &update); } }
static void pendingtitles_action_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { pendingtitles_action_data* actionData = (pendingtitles_action_data*) data; if(hidKeysDown() & KEY_B) { ui_pop(); list_destroy(view); free(data); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { void(*action)(linked_list*, list_item*) = (void(*)(linked_list*, list_item*)) selected->data; ui_pop(); list_destroy(view); action(actionData->items, actionData->selected); free(data); return; } if(linked_list_size(items) == 0) { linked_list_add(items, &delete_pending_title); linked_list_add(items, &delete_all_pending_titles); } }
static void titles_options_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { titles_data* listData = (titles_data*) data; if(hidKeysDown() & KEY_B) { linked_list_iter iter; linked_list_iterate(items, &iter); while(linked_list_iter_has_next(&iter)) { free(linked_list_iter_next(&iter)); linked_list_iter_remove(&iter); } ui_pop(); list_destroy(view); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { bool* val = (bool*) selected->data; *val = !(*val); if(*val && (val == &listData->sortById || val == &listData->sortByName || val == &listData->sortBySize)) { if(val == &listData->sortById) { listData->sortByName = false; listData->sortBySize = false; } else if(val == &listData->sortByName) { listData->sortById = false; listData->sortBySize = false; } else if(val == &listData->sortBySize) { listData->sortById = false; listData->sortByName = false; } linked_list_iter iter; linked_list_iterate(items, &iter); while(linked_list_iter_has_next(&iter)) { list_item* item = (list_item*) linked_list_iter_next(&iter); item->color = *(bool*) item->data ? COLOR_ENABLED : COLOR_DISABLED; } } else { selected->color = *val ? COLOR_ENABLED : COLOR_DISABLED; } listData->populated = false; } if(linked_list_size(items) == 0) { titles_options_add_entry(items, "Show game card", &listData->showGameCard); titles_options_add_entry(items, "Show SD", &listData->showSD); titles_options_add_entry(items, "Show NAND", &listData->showNAND); titles_options_add_entry(items, "Sort by ID", &listData->sortById); titles_options_add_entry(items, "Sort by name", &listData->sortByName); titles_options_add_entry(items, "Sort by size", &listData->sortBySize); } }
static void titles_action_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { titles_action_data* actionData = (titles_action_data*) data; if(hidKeysDown() & KEY_B) { ui_pop(); list_destroy(view); free(data); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { void(*action)(linked_list*, list_item*) = (void(*)(linked_list*, list_item*)) selected->data; ui_pop(); list_destroy(view); action(actionData->items, actionData->selected); free(data); return; } if(linked_list_size(items) == 0) { linked_list_add(items, &launch_title); title_info* info = (title_info*) actionData->selected->data; if(info->mediaType != MEDIATYPE_GAME_CARD) { linked_list_add(items, &delete_title); linked_list_add(items, &delete_title_ticket); } if(!info->twl) { linked_list_add(items, &extract_smdh); if(info->mediaType != MEDIATYPE_GAME_CARD) { linked_list_add(items, &import_seed); } linked_list_add(items, &browse_save_data); if(info->mediaType != MEDIATYPE_GAME_CARD) { linked_list_add(items, &import_secure_value); linked_list_add(items, &export_secure_value); linked_list_add(items, &delete_secure_value); } } else if(info->mediaType == MEDIATYPE_GAME_CARD) { linked_list_add(items, &import_save_data); linked_list_add(items, &export_save_data); linked_list_add(items, &erase_save_data); } } }
void test_keys() { char *keys[] = { "key", "keys2", "1234567890", "1234567809" }; char *values[] = { "value", "value2", "9090", "0909" }; linked_list *keys_list = hash_map_keys(map); TEST_ASSERT_EQUAL_UINT(0, linked_list_size(keys_list)); for (int i = 0; i < sizeof(keys) / sizeof(*keys); i++) { hash_map_put(map, keys[i], values[i]); } keys_list = hash_map_keys(map); TEST_ASSERT_EQUAL_UINT(4, linked_list_size(keys_list)); linked_list_node *node = linked_list_head(keys_list); for (int i = 0; i < sizeof(keys) / sizeof(*keys); i++) { TEST_ASSERT_EQUAL_STRING(keys[i], node->data); node = node->next; } }
void netbench_list_result_send(struct linked_list *results,int rank) { unsigned int size; size = linked_list_size(results); if (!size) return; netbench_comm_list_send(size,rank); while (results) { netbench_result_send(results->value->u.res,rank); results = results->next; } }
void test_insert() { // regular insert linked_list* ll = linked_list_new(); linked_list_insert(ll, 2); linked_list_insert(ll, 4); linked_list_insert(ll, 6); assert_equals(linked_list_size(ll), 3); assert_true(linked_list_contains(ll, 2)); assert_true(linked_list_contains(ll, 4)); assert_true(linked_list_contains(ll, 6)); assert_false(linked_list_contains(ll, -1)); assert_false(linked_list_contains(ll, 0)); linked_list_clear(ll); linked_list* ll = linked_list_new(); assert_equals(linked_list_size(ll), 0); assert_false(linked_list_contains(ll, 1)); linked_list_insert(ll, 1); assert_equals(linked_list_size(ll), 1); assert_true(linked_list_contains(ll, 1)); linked_list_clear(ll); // insert by index // set by index }
int main(int argc, char** argv) { t_maillon* list = new_maillon(4); list->next = new_maillon(19); list->next->next = new_maillon(2); list->next->next->next = new_maillon(7); int found; printf("Taille liste : %u \n", linked_list_size(list)); printf("Valeur position 2 : %d \n", linked_list_get_by_position(list, 2, &found)); printf("Position valeur 19: %d \n", linked_list_get_by_value(list, 19)); linked_list_display(list); linked_list_display(list); printf("Valeur position 2 : %d \n", linked_list_get_by_position(list, 2, &found)); printf("Valeur position 3 : %d \n", linked_list_get_by_position(list, 3, &found)); printf("Position valeur 7: %d \n", linked_list_get_by_value(list, 7)); linked_list_free(&list); return 0; }
void action_paste_contents(linked_list* items, list_item* selected) { if(!clipboard_has_contents()) { prompt_display("Failure", "Clipboard empty.", COLOR_TEXT, false, NULL, NULL, NULL); return; } paste_files_data* data = (paste_files_data*) calloc(1, sizeof(paste_files_data)); if(data == NULL) { error_display(NULL, NULL, "Failed to allocate paste files data."); return; } data->items = items; data->target = (file_info*) selected->data; data->pasteInfo.data = data; data->pasteInfo.op = DATAOP_COPY; data->pasteInfo.copyBufferSize = 256 * 1024; data->pasteInfo.copyEmpty = true; data->pasteInfo.isSrcDirectory = action_paste_files_is_src_directory; data->pasteInfo.makeDstDirectory = action_paste_files_make_dst_directory; data->pasteInfo.openSrc = action_paste_files_open_src; data->pasteInfo.closeSrc = action_paste_files_close_src; data->pasteInfo.getSrcSize = action_paste_files_get_src_size; data->pasteInfo.readSrc = action_paste_files_read_src; data->pasteInfo.openDst = action_paste_files_open_dst; data->pasteInfo.closeDst = action_paste_files_close_dst; data->pasteInfo.writeDst = action_paste_files_write_dst; data->pasteInfo.suspendCopy = action_paste_files_suspend_copy; data->pasteInfo.restoreCopy = action_paste_files_restore_copy; data->pasteInfo.suspend = action_paste_files_suspend; data->pasteInfo.restore = action_paste_files_restore; data->pasteInfo.error = action_paste_files_error; data->pasteInfo.finished = true; linked_list_init(&data->contents); populate_files_data popData; memset(&popData, 0, sizeof(popData)); popData.items = &data->contents; popData.archive = clipboard_get_archive(); strncpy(popData.path, clipboard_get_path(), FILE_PATH_MAX); popData.recursive = true; popData.includeBase = !clipboard_is_contents_only() || !util_is_dir(clipboard_get_archive(), clipboard_get_path()); popData.filter = NULL; popData.filterData = NULL; Result listRes = task_populate_files(&popData); if(R_FAILED(listRes)) { error_display_res(NULL, NULL, listRes, "Failed to initiate clipboard content list population."); action_paste_files_free_data(data); return; } while(!popData.finished) { svcSleepThread(1000000); } if(R_FAILED(popData.result)) { error_display_res(NULL, NULL, popData.result, "Failed to populate clipboard content list."); action_paste_files_free_data(data); return; } data->pasteInfo.total = linked_list_size(&data->contents); data->pasteInfo.processed = data->pasteInfo.total; prompt_display("Confirmation", "Paste clipboard contents to the current directory?", COLOR_TEXT, true, data, action_paste_files_draw_top, action_paste_files_onresponse); }
static int bfwork_run_threaded(bam_fwork_t *fwork) { int err; bam_region_t *region; linked_list_t *regions; double times; omp_lock_t end_condition_lock; int end_condition; omp_lock_t reads_lock; size_t reads; size_t reads_to_write; //Init lock omp_init_lock(&end_condition_lock); omp_init_lock(&reads_lock); //#pragma omp parallel private(err, region, regions, times, reads_to_write) { //#pragma omp single { printf("Running in multithreading mode with %d threads\n", omp_get_max_threads()); end_condition = 1; reads = 0; } #pragma omp parallel sections private(err, region, regions, times, reads_to_write) { //Region read #pragma omp section { regions = fwork->regions_list; while(1) { //Create new current region region = (bam_region_t *)malloc(sizeof(bam_region_t)); breg_init(region); //Fill region #ifdef D_TIME_DEBUG times = omp_get_wtime(); #endif err = bfwork_obtain_region(fwork, region); #ifdef D_TIME_DEBUG times = omp_get_wtime() - times; omp_set_lock(®ion->lock); if(fwork->context->time_stats) if(region->size != 0) time_add_time_slot(D_FWORK_READ, fwork->context->time_stats, times / (double)region->size); omp_unset_lock(®ion->lock); #endif if(err) { if(err == WANDER_REGION_CHANGED || err == WANDER_READ_EOF) { //Until process, this region cant be writed omp_test_lock(®ion->write_lock); //Add region to framework regions bfwork_region_insert(fwork, region); #pragma omp task untied firstprivate(region) private(err) { int i; size_t pf_l; double aux_time; //Process region omp_set_lock(®ion->lock); #ifdef D_TIME_DEBUG times = omp_get_wtime(); #endif //Process region pf_l = fwork->context->processing_f_l; for(i = 0; i < pf_l; i++) { fwork->context->processing_f[i](fwork, region); } #ifdef D_TIME_DEBUG times = omp_get_wtime() - times; if(fwork->context->time_stats) if(region->size != 0) time_add_time_slot(D_FWORK_PROC_FUNC, fwork->context->time_stats, times / (double)region->size); aux_time = omp_get_wtime(); #endif omp_unset_lock(®ion->lock); omp_set_lock(&reads_lock); reads += region->size; printf("Reads processed: %lu\r", reads); omp_unset_lock(&reads_lock); #ifdef D_TIME_DEBUG aux_time = omp_get_wtime() - aux_time; omp_set_lock(®ion->lock); if(fwork->context->time_stats) if(region->size != 0) time_add_time_slot(D_FWORK_PROC, fwork->context->time_stats, (times + aux_time) / (double)region->size); omp_unset_lock(®ion->lock); #endif //Set this region as writable omp_unset_lock(®ion->write_lock); } //End readings if(err == WANDER_READ_EOF) break; } else { if(err == WANDER_READ_TRUNCATED) { LOG_WARN("Readed truncated read\n"); } else { LOG_FATAL_F("Failed to read next region, error code: %d\n", err); } break; } } else { //No more regions, end loop LOG_INFO("No more regions to read"); break; } } omp_set_lock(&end_condition_lock); end_condition = 0; omp_unset_lock(&end_condition_lock); //LOG_WARN("Read thread exit\n"); }//End read section //Write section #pragma omp section { regions = fwork->regions_list; omp_set_lock(&end_condition_lock); while(end_condition || linked_list_size(regions) > 0) { omp_unset_lock(&end_condition_lock); #ifdef D_TIME_DEBUG times = omp_get_wtime(); #endif //Get next region omp_set_lock(&fwork->regions_lock); region = linked_list_get_first(regions); omp_unset_lock(&fwork->regions_lock); if(region == NULL) { omp_set_lock(&end_condition_lock); continue; } //Wait region to be writable omp_set_lock(®ion->write_lock); //Write region omp_set_lock(&fwork->output_file_lock); reads_to_write = region->size; breg_write_n(region, reads_to_write, fwork->output_file); omp_unset_lock(&fwork->output_file_lock); //Remove from list omp_set_lock(&fwork->regions_lock); if(linked_list_size(regions) == 1) //Possible bug? linked_list_clear(regions, NULL); else linked_list_remove_first(regions); //Signal read section if regions list is full if(linked_list_size(regions) < (FWORK_REGIONS_MAX / 2) ) omp_unset_lock(&fwork->free_slots); omp_unset_lock(&fwork->regions_lock); #ifdef D_TIME_DEBUG times = omp_get_wtime() - times; omp_set_lock(®ion->lock); if(fwork->context->time_stats) if(reads_to_write != 0) time_add_time_slot(D_FWORK_WRITE, fwork->context->time_stats, times / (double)reads_to_write); omp_unset_lock(®ion->lock); #endif //Free region breg_destroy(region, 1); free(region); omp_set_lock(&end_condition_lock); } omp_unset_lock(&end_condition_lock); //LOG_WARN("Write thread exit\n"); }//End write section }//End sections }//End parallel //Lineskip printf("\n"); //Free omp_destroy_lock(&end_condition_lock); return NO_ERROR; }
void suffix_mng_update(int chrom, size_t read_start, size_t read_end, size_t genome_start, size_t genome_end, suffix_mng_t *p) { if (!p) return; if (!p->suffix_lists) return; linked_list_t *suffix_list = p->suffix_lists[chrom]; if (!suffix_list) return; seed_t *seed; if (linked_list_size(suffix_list) <= 0) { // list is empty, insert and return seed = seed_new(read_start, read_end, genome_start, genome_end); seed->chromosome_id = chrom; linked_list_insert(seed, suffix_list); p->num_seeds++; return; } linked_list_iterator_t* itr = linked_list_iterator_new(suffix_list); seed = (seed_t *) linked_list_iterator_curr(itr); while (seed != NULL) { // if it's included then return if (seed->chromosome_id == chrom && seed->read_start <= read_start && seed->read_end >= read_end && seed->genome_start <= genome_start && seed->genome_end >= genome_end) { // free memory linked_list_iterator_free(itr); return; } // if it's previous then insert and return if (genome_start < seed->genome_start) { seed = seed_new(read_start, read_end, genome_start, genome_end); seed->chromosome_id = chrom; linked_list_iterator_insert(seed, itr); linked_list_iterator_prev(itr); p->num_seeds++; // free memory linked_list_iterator_free(itr); return; } //continue loop... linked_list_iterator_next(itr); seed = linked_list_iterator_curr(itr); } // insert at the last position seed = seed_new(read_start, read_end, genome_start, genome_end); seed->chromosome_id = chrom; linked_list_insert_last(seed, suffix_list); p->num_seeds++; // free memory linked_list_iterator_free(itr); }
static void files_action_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { files_action_data* actionData = (files_action_data*) data; if(hidKeysDown() & KEY_B) { ui_pop(); list_destroy(view); free(data); return; } if(selected != NULL && (selected->data != NULL || selected == © || selected == ©_all_contents) && (selectedTouched || (hidKeysDown() & KEY_A))) { void(*action)(linked_list*, list_item*) = (void(*)(linked_list*, list_item*)) selected->data; ui_pop(); list_destroy(view); if(selected == © || selected == ©_all_contents) { file_info* info = (file_info*) actionData->selected->data; Result res = 0; if(R_SUCCEEDED(res = clipboard_set_contents(actionData->parent->archiveId, &actionData->parent->archivePath, info->path, selected == ©_all_contents))) { prompt_display("Success", selected == ©_all_contents ? "Current directory contents copied to clipboard." : info->isDirectory ? "Current directory copied to clipboard." : "File copied to clipboard.", COLOR_TEXT, false, info, NULL, ui_draw_file_info, NULL); } else { error_display_res(NULL, info, ui_draw_file_info, res, "Failed to copy to clipboard."); } } else { action(actionData->items, actionData->selected); } free(data); return; } if(linked_list_size(items) == 0) { file_info* info = (file_info*) actionData->selected->data; if(info->isDirectory) { if(info->containsCias) { linked_list_add(items, &install_all_cias); linked_list_add(items, &install_and_delete_all_cias); linked_list_add(items, &delete_all_cias); } if(info->containsTickets) { linked_list_add(items, &install_all_tickets); linked_list_add(items, &install_and_delete_all_tickets); linked_list_add(items, &delete_all_tickets); } linked_list_add(items, &delete_all_contents); linked_list_add(items, ©_all_contents); linked_list_add(items, &delete_dir); } else { if(info->isCia) { linked_list_add(items, &install_cia); linked_list_add(items, &install_and_delete_cia); } if(info->isTicket) { linked_list_add(items, &install_ticket); linked_list_add(items, &install_and_delete_ticket); } linked_list_add(items, &delete_file); } linked_list_add(items, ©); linked_list_add(items, &paste); } }
static void task_populate_files_thread(void* arg) { populate_files_data* data = (populate_files_data*) arg; Result res = 0; list_item* baseItem = NULL; if(R_SUCCEEDED(res = task_create_file_item(&baseItem, data->archive, data->path))) { file_info* baseInfo = (file_info*) baseItem->data; if(baseInfo->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseItem->name, "<current directory>", LIST_ITEM_NAME_MAX); } else { strncpy(baseItem->name, "<current file>", LIST_ITEM_NAME_MAX); } linked_list queue; linked_list_init(&queue); linked_list_add(&queue, baseItem); bool quit = false; while(!quit && R_SUCCEEDED(res) && linked_list_size(&queue) > 0) { u32 tail = linked_list_size(&queue) - 1; list_item* currItem = (list_item*) linked_list_get(&queue, tail); file_info* curr = (file_info*) currItem->data; linked_list_remove_at(&queue, tail); if(data->includeBase || currItem != baseItem) { linked_list_add(data->items, currItem); } if(curr->attributes & FS_ATTRIBUTE_DIRECTORY) { FS_Path* fsPath = util_make_path_utf8(curr->path); if(fsPath != NULL) { Handle dirHandle = 0; if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, curr->archive, *fsPath))) { u32 entryCount = 0; FS_DirectoryEntry* entries = (FS_DirectoryEntry*) calloc(MAX_FILES, sizeof(FS_DirectoryEntry)); if(entries != NULL) { if(R_SUCCEEDED(res = FSDIR_Read(dirHandle, &entryCount, MAX_FILES, entries)) && entryCount > 0) { qsort(entries, entryCount, sizeof(FS_DirectoryEntry), task_populate_files_compare_directory_entries); for(u32 i = 0; i < entryCount && R_SUCCEEDED(res); i++) { svcWaitSynchronization(task_get_pause_event(), U64_MAX); if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) { quit = true; break; } char name[FILE_NAME_MAX] = {'\0'}; utf16_to_utf8((uint8_t*) name, entries[i].name, FILE_NAME_MAX - 1); if(data->filter == NULL || data->filter(data->filterData, name, entries[i].attributes)) { char path[FILE_PATH_MAX] = {'\0'}; snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name); list_item* item = NULL; if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path))) { if(data->recursive && (((file_info*) item->data)->attributes & FS_ATTRIBUTE_DIRECTORY)) { linked_list_add(&queue, item); } else { linked_list_add(data->items, item); } } } } } free(entries); } else { res = R_FBI_OUT_OF_MEMORY; } FSDIR_Close(dirHandle); } util_free_path_utf8(fsPath); } else { res = R_FBI_OUT_OF_MEMORY; } } } if(!data->includeBase) { task_free_file(baseItem); } } svcCloseHandle(data->cancelEvent); data->result = res; data->finished = true; }