static int database_info_list_iterate_end_no_match( database_info_handle_t *db, database_state_handle_t *db_state, const char *path) { /* Reached end of database list, * CRC match probably didn't succeed. */ /* If this was a compressed file and no match in the database * list was found then expand the search list to include the * archive's contents. */ if (path_is_compressed_file(path) && !path_contains_compressed_file(path)) { struct string_list *archive_list = file_archive_get_file_list(path, NULL); if (archive_list && archive_list->size > 0) { unsigned i; for (i = 0; i < archive_list->size; i++) { char *new_path = (char*)malloc( PATH_MAX_LENGTH * sizeof(char)); size_t path_size = PATH_MAX_LENGTH * sizeof(char); size_t path_len = strlen(path); new_path[0] = '\0'; strlcpy(new_path, path, path_size); if (path_len + strlen(archive_list->elems[i].data) + 1 < PATH_MAX_LENGTH) { new_path[path_len] = '#'; strlcpy(new_path + path_len + 1, archive_list->elems[i].data, path_size - path_len); } string_list_append(db->list, new_path, archive_list->elems[i].attr); free(new_path); } string_list_free(archive_list); } } db_state->list_index = 0; db_state->entry_index = 0; if (db_state->crc != 0) db_state->crc = 0; return 0; }
struct string_list *compressed_file_list_new(const char *path, const char* ext) { #if defined(HAVE_ZLIB) || defined(HAVE_7ZIP) const char* file_ext = path_get_extension(path); #endif #ifdef HAVE_7ZIP if (string_is_equal_noncase(file_ext, "7z")) return compressed_7zip_file_list_new(path,ext); #endif #ifdef HAVE_ZLIB if (string_is_equal_noncase(file_ext, "zip")) return file_archive_get_file_list(path, ext); #endif return NULL; }
void core_info_list_get_supported_cores(core_info_list_t *core_info_list, const char *path, const core_info_t **infos, size_t *num_infos) { size_t i; struct string_list *list = NULL; size_t supported = 0; if (!core_info_list) return; core_info_tmp_path = path; #ifdef HAVE_COMPRESSION if (path_is_compressed_file(path)) list = file_archive_get_file_list(path, NULL); core_info_tmp_list = list; #endif /* Let supported core come first in list so we can return * a pointer to them. */ qsort(core_info_list->list, core_info_list->count, sizeof(core_info_t), core_info_qsort_cmp); for (i = 0; i < core_info_list->count; i++, supported++) { const core_info_t *core = &core_info_list->list[i]; if (core_info_does_support_file(core, path)) continue; #ifdef HAVE_COMPRESSION if (core_info_does_support_any_file(core, list)) continue; #endif break; } if (list) string_list_free(list); *infos = core_info_list->list; *num_infos = supported; }
int MainWindow::onExtractArchive(QString path) { QByteArray pathArray = path.toUtf8(); const char *file = pathArray.constData(); file_archive_transfer_t state; struct archive_extract_userdata userdata; struct string_list *file_list = file_archive_get_file_list(file, NULL); bool returnerr = true; unsigned i; if (!file_list || file_list->size == 0) { showMessageBox("Error: Archive is empty.", MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); RARCH_ERR("[Qt]: Downloaded archive is empty?\n"); return -1; } for (i = 0; i < file_list->size; i++) { QFile fileObj(file_list->elems[i].data); if (fileObj.exists()) { if (!fileObj.remove()) { /* if we cannot delete the existing file to update it, rename it for now and delete later */ QFile fileTemp(fileObj.fileName() + TEMP_EXTENSION); if (fileTemp.exists()) { if (!fileTemp.remove()) { showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); RARCH_ERR("[Qt]: Could not delete file: %s\n", file_list->elems[i].data); return -1; } } if (!fileObj.rename(fileTemp.fileName())) { showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); RARCH_ERR("[Qt]: Could not rename file: %s\n", file_list->elems[i].data); return -1; } } } } string_list_free(file_list); memset(&state, 0, sizeof(state)); memset(&userdata, 0, sizeof(userdata)); state.type = ARCHIVE_TRANSFER_INIT; m_updateProgressDialog->setWindowModality(Qt::NonModal); m_updateProgressDialog->setMinimumDuration(0); m_updateProgressDialog->setRange(0, 0); m_updateProgressDialog->setAutoClose(true); m_updateProgressDialog->setAutoReset(true); m_updateProgressDialog->setValue(0); m_updateProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_EXTRACTING)) + "..."); m_updateProgressDialog->setCancelButtonText(QString()); m_updateProgressDialog->show(); if (!task_push_decompress(file, ".", NULL, NULL, NULL, extractCB, this)) { m_updateProgressDialog->cancel(); return -1; } return returnerr; }
database_info_handle_t *database_info_file_init(const char *path, enum database_type type) { union string_list_elem_attr attr = {0}; database_info_handle_t *db = (database_info_handle_t*) calloc(1, sizeof(*db)); if (!db) return NULL; db->list = string_list_new(); if (!db->list) goto error; string_list_append(db->list, path, attr); if (path_is_compressed_file(path)) { struct string_list *archive_list =path_is_compressed_file(path) ? file_archive_get_file_list(path, NULL) : NULL; if (archive_list && archive_list->size > 0) { unsigned i; for (i = 0; i < archive_list->size; i++) { char new_path[PATH_MAX_LENGTH]; size_t path_len = strlen(path); new_path[0] = '\0'; strlcpy(new_path, path, sizeof(new_path)); if (path_len + strlen(archive_list->elems[i].data) + 1 < PATH_MAX_LENGTH) { new_path[path_len] = '#'; strlcpy(new_path + path_len + 1, archive_list->elems[i].data, sizeof(new_path) - path_len); } string_list_append(db->list, new_path, archive_list->elems[i].attr); } string_list_free(archive_list); } } db->list_ptr = 0; db->status = DATABASE_STATUS_ITERATE; db->type = type; return db; error: if (db) free(db); return NULL; }
/* Takes a list of files and folders and adds them to the currently selected playlist. Folders will have their contents added recursively. */ void MainWindow::addFilesToPlaylist(QStringList files) { QStringList list; QString currentPlaylistPath; QListWidgetItem *currentItem = m_listWidget->currentItem(); QByteArray currentPlaylistArray; QScopedPointer<QProgressDialog> dialog(NULL); PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); QHash<QString, QString> selectedCore; QHash<QString, QString> itemToAdd; QString selectedDatabase; QString selectedName; QString selectedPath; const char *currentPlaylistData = NULL; playlist_t *playlist = NULL; int i; /* Assume a blank list means we will manually enter in all fields. */ if (files.isEmpty()) { /* Make sure hash isn't blank, that would mean there's multiple entries to add at once. */ itemToAdd["label"] = ""; itemToAdd["path"] = ""; } else if (files.count() == 1) { QString path = files.at(0); QFileInfo info(path); if (info.isFile()) { itemToAdd["label"] = info.completeBaseName(); itemToAdd["path"] = path; } } if (currentItem) { currentPlaylistPath = currentItem->data(Qt::UserRole).toString(); if (!currentPlaylistPath.isEmpty()) { currentPlaylistArray = currentPlaylistPath.toUtf8(); currentPlaylistData = currentPlaylistArray.constData(); } } if (currentPlaylistPath == ALL_PLAYLISTS_TOKEN) { showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); return; } /* a blank itemToAdd means there will be multiple */ if (!playlistDialog->showDialog(itemToAdd)) return; selectedName = m_playlistEntryDialog->getSelectedName(); selectedPath = m_playlistEntryDialog->getSelectedPath(); selectedCore = m_playlistEntryDialog->getSelectedCore(); selectedDatabase = m_playlistEntryDialog->getSelectedDatabase(); if (selectedDatabase.isEmpty()) selectedDatabase = QFileInfo(currentPlaylistPath).fileName(); else selectedDatabase += file_path_str(FILE_PATH_LPL_EXTENSION); dialog.reset(new QProgressDialog(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES), "Cancel", 0, 0, this)); dialog->setWindowModality(Qt::ApplicationModal); if (selectedName.isEmpty() || selectedPath.isEmpty() || selectedDatabase.isEmpty()) { showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); return; } if (files.isEmpty()) files.append(selectedPath); for (i = 0; i < files.count(); i++) { QString path(files.at(i)); QFileInfo fileInfo(path); if (dialog->wasCanceled()) return; if (i % 25 == 0) { /* Needed to update progress dialog while doing a lot of stuff on the main thread. */ qApp->processEvents(); } if (fileInfo.isDir()) { QDir dir(path); addDirectoryFilesToList(list, dir); continue; } if (fileInfo.isFile()) list.append(fileInfo.absoluteFilePath()); else if (files.count() == 1) { /* If adding a single file, tell user that it doesn't exist. */ showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); return; } } dialog->setLabelText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST)); dialog->setMaximum(list.count()); playlist = playlist_init(currentPlaylistData, COLLECTION_SIZE); for (i = 0; i < list.count(); i++) { QString fileName = list.at(i); QFileInfo fileInfo; QByteArray fileBaseNameArray; QByteArray pathArray; QByteArray corePathArray; QByteArray coreNameArray; QByteArray databaseArray; const char *pathData = NULL; const char *fileNameNoExten = NULL; const char *corePathData = NULL; const char *coreNameData = NULL; const char *databaseData = NULL; if (dialog->wasCanceled()) { playlist_free(playlist); return; } if (fileName.isEmpty()) continue; fileInfo = fileName; if (files.count() == 1 && list.count() == 1 && i == 0) { fileBaseNameArray = selectedName.toUtf8(); pathArray = QDir::toNativeSeparators(selectedPath).toUtf8(); } else { fileBaseNameArray = fileInfo.completeBaseName().toUtf8(); pathArray = QDir::toNativeSeparators(fileName).toUtf8(); } fileNameNoExten = fileBaseNameArray.constData(); /* a modal QProgressDialog calls processEvents() automatically in setValue() */ dialog->setValue(i + 1); pathData = pathArray.constData(); if (selectedCore.isEmpty()) { corePathData = "DETECT"; coreNameData = "DETECT"; } else { corePathArray = QDir::toNativeSeparators(selectedCore.value("core_path")).toUtf8(); coreNameArray = selectedCore.value("core_name").toUtf8(); corePathData = corePathArray.constData(); coreNameData = coreNameArray.constData(); } databaseArray = selectedDatabase.toUtf8(); databaseData = databaseArray.constData(); if (path_is_compressed_file(pathData)) { struct string_list *list = file_archive_get_file_list(pathData, NULL); if (list) { if (list->size == 1) { /* assume archives with one file should have that file loaded directly */ pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); pathData = pathArray.constData(); } string_list_free(list); } } playlist_push(playlist, pathData, fileNameNoExten, corePathData, coreNameData, "00000000|crc", databaseData); } playlist_write_file(playlist); playlist_free(playlist); reloadPlaylists(); }
bool MainWindow::updateCurrentPlaylistEntry(const QHash<QString, QString> &contentHash) { QString playlistPath = getCurrentPlaylistPath(); QString path; QString label; QString corePath; QString coreName; QString dbName; QString crc32; QByteArray playlistPathArray; QByteArray pathArray; QByteArray labelArray; QByteArray corePathArray; QByteArray coreNameArray; QByteArray dbNameArray; QByteArray crc32Array; const char *playlistPathData = NULL; const char *pathData = NULL; const char *labelData = NULL; const char *corePathData = NULL; const char *coreNameData = NULL; const char *dbNameData = NULL; const char *crc32Data = NULL; playlist_t *playlist = NULL; unsigned index = 0; bool ok = false; if (playlistPath.isEmpty() || contentHash.isEmpty() || !contentHash.contains("index")) return false; index = contentHash.value("index").toUInt(&ok); if (!ok) return false; path = contentHash.value("path"); label = contentHash.value("label"); coreName = contentHash.value("core_name"); corePath = contentHash.value("core_path"); dbName = contentHash.value("db_name"); crc32 = contentHash.value("crc32"); if (path.isEmpty() || label.isEmpty() || coreName.isEmpty() || corePath.isEmpty() || dbName.isEmpty() || crc32.isEmpty() ) return false; playlistPathArray = playlistPath.toUtf8(); pathArray = QDir::toNativeSeparators(path).toUtf8(); labelArray = label.toUtf8(); coreNameArray = coreName.toUtf8(); corePathArray = QDir::toNativeSeparators(corePath).toUtf8(); dbNameArray = (dbName + file_path_str(FILE_PATH_LPL_EXTENSION)).toUtf8(); crc32Array = crc32.toUtf8(); playlistPathData = playlistPathArray.constData(); pathData = pathArray.constData(); labelData = labelArray.constData(); coreNameData = coreNameArray.constData(); corePathData = corePathArray.constData(); dbNameData = dbNameArray.constData(); crc32Data = crc32Array.constData(); if (path_is_compressed_file(pathData)) { struct string_list *list = file_archive_get_file_list(pathData, NULL); if (list) { if (list->size == 1) { /* assume archives with one file should have that file loaded directly */ pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); pathData = pathArray.constData(); } string_list_free(list); } } playlist = playlist_init(playlistPathData, COLLECTION_SIZE); playlist_update(playlist, index, pathData, labelData, corePathData, coreNameData, crc32Data, dbNameData); playlist_write_file(playlist); playlist_free(playlist); reloadPlaylists(); return true; }
void filebrowser_parse(void *data, unsigned type_data, bool extensions_honored) { size_t i, list_size; struct string_list *str_list = NULL; unsigned items_found = 0; unsigned files_count = 0; unsigned dirs_count = 0; settings_t *settings = config_get_ptr(); menu_displaylist_info_t *info = (menu_displaylist_info_t*)data; enum menu_displaylist_ctl_state type = (enum menu_displaylist_ctl_state) type_data; bool path_is_compressed = path_is_compressed_file(info->path); bool filter_ext = settings->menu.navigation.browser.filter.supported_extensions_enable; if (string_is_equal(info->label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_FILE))) filter_ext = false; if (extensions_honored) filter_ext = true; if (path_is_compressed) str_list = file_archive_get_file_list(info->path, info->exts); else str_list = dir_list_new(info->path, filter_ext ? info->exts : NULL, true, settings->show_hidden_files, true, false); #ifdef HAVE_LIBRETRODB if (filebrowser_types == FILEBROWSER_SCAN_DIR) menu_entries_prepend(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY), MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY, FILE_TYPE_SCAN_DIRECTORY, 0 ,0); #endif if (filebrowser_types == FILEBROWSER_SELECT_DIR) menu_entries_prepend(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_USE_THIS_DIRECTORY), MENU_ENUM_LABEL_USE_THIS_DIRECTORY, FILE_TYPE_USE_DIRECTORY, 0 ,0); if (!str_list) { const char *str = path_is_compressed ? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE) : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND); menu_entries_append_enum(info->list, str, "", MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, 0, 0, 0); goto end; } dir_list_sort(str_list, true); list_size = str_list->size; if (list_size == 0) { string_list_free(str_list); str_list = NULL; } else { for (i = 0; i < list_size; i++) { char label[PATH_MAX_LENGTH]; bool is_dir = false; enum msg_hash_enums enum_idx = MSG_UNKNOWN; enum msg_file_type file_type = FILE_TYPE_NONE; const char *path = str_list->elems[i].data; label[0] = '\0'; switch (str_list->elems[i].attr.i) { case RARCH_DIRECTORY: file_type = FILE_TYPE_DIRECTORY; break; case RARCH_COMPRESSED_ARCHIVE: file_type = FILE_TYPE_CARCHIVE; break; case RARCH_COMPRESSED_FILE_IN_ARCHIVE: file_type = FILE_TYPE_IN_CARCHIVE; break; case RARCH_PLAIN_FILE: default: file_type = (enum msg_file_type)info->type_default; switch (type) { /* in case of deferred_core_list we have to interpret * every archive as an archive to disallow instant loading */ case DISPLAYLIST_CORES_DETECTED: if (path_is_compressed_file(path)) file_type = FILE_TYPE_CARCHIVE; break; default: break; } break; } is_dir = (file_type == FILE_TYPE_DIRECTORY); if (!is_dir) { if (filebrowser_types == FILEBROWSER_SELECT_DIR) continue; if (filebrowser_types == FILEBROWSER_SCAN_DIR) continue; } /* Need to preserve slash first time. */ if (!string_is_empty(info->path) && !path_is_compressed) path = path_basename(path); if (filebrowser_types == FILEBROWSER_SELECT_COLLECTION) { if (is_dir) file_type = FILE_TYPE_DIRECTORY; else file_type = FILE_TYPE_PLAYLIST_COLLECTION; } if (!is_dir && (settings->multimedia.builtin_mediaplayer_enable || settings->multimedia.builtin_imageviewer_enable)) { switch (path_is_media_type(path)) { case RARCH_CONTENT_MOVIE: #ifdef HAVE_FFMPEG if (settings->multimedia.builtin_mediaplayer_enable) file_type = FILE_TYPE_MOVIE; #endif break; case RARCH_CONTENT_MUSIC: #ifdef HAVE_FFMPEG if (settings->multimedia.builtin_mediaplayer_enable) file_type = FILE_TYPE_MUSIC; #endif break; case RARCH_CONTENT_IMAGE: #ifdef HAVE_IMAGEVIEWER if (settings->multimedia.builtin_imageviewer_enable && type != DISPLAYLIST_IMAGES) file_type = FILE_TYPE_IMAGEVIEWER; else file_type = FILE_TYPE_IMAGE; #endif break; default: break; } } switch (file_type) { case FILE_TYPE_PLAIN: #if 0 enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE; #endif files_count++; break; case FILE_TYPE_MOVIE: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_MOVIE_OPEN; files_count++; break; case FILE_TYPE_MUSIC: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_MUSIC_OPEN; files_count++; break; case FILE_TYPE_IMAGE: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_IMAGE; files_count++; break; case FILE_TYPE_IMAGEVIEWER: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_IMAGE_OPEN_WITH_VIEWER; files_count++; break; case FILE_TYPE_DIRECTORY: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY; dirs_count++; break; default: break; } items_found++; menu_entries_append_enum(info->list, path, label, enum_idx, file_type, 0, 0); } } if (str_list && str_list->size > 0) string_list_free(str_list); if (items_found == 0) { menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), MENU_ENUM_LABEL_NO_ITEMS, MENU_SETTING_NO_ITEM, 0, 0); } /* We don't want to show 'filter by extension' for this. */ if (filebrowser_types == FILEBROWSER_SELECT_DIR) goto end; if (filebrowser_types == FILEBROWSER_SCAN_DIR) goto end; if (!extensions_honored && files_count > 0) menu_entries_prepend(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE), msg_hash_to_str(MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE), MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, 0, 0 ,0); end: menu_entries_prepend(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY), info->path, MENU_ENUM_LABEL_PARENT_DIRECTORY, FILE_TYPE_PARENT_DIRECTORY, 0, 0); }