Revised / improved file search system

Also includes search button combo in instructions
This commit is contained in:
d0k3 2016-07-22 18:32:44 +02:00
parent cd17915028
commit 2c782d47c8
6 changed files with 52 additions and 68 deletions

View File

@ -1,44 +0,0 @@
#include "store.h"
#include "ff.h"
#define STORE_BUFFER ((DirStruct*)0x21300000)
static bool is_stored = false;
bool IsStoredDrive(const char* path) {
return is_stored && (strncmp(path, "Z:", 3) == 0);
}
void StoreDirContents(DirStruct* contents) {
memcpy(STORE_BUFFER, contents, sizeof(DirStruct));
is_stored = true;
}
void GetStoredDirContents(DirStruct* contents) {
// warning: this assumes the store buffer is filled with data that makes sense
DirStruct* stored = STORE_BUFFER;
u32 skip = 0;
// basic sanity checking
if (!is_stored || (stored->n_entries > MAX_ENTRIES)) return;
// copy available entries, remove missing from storage
for (u32 i = 0; i < stored->n_entries; i++) {
DirEntry* entry = &(stored->entry[i]);
if (strncmp(entry->name, "..", 3) == 0) continue; // disregard dotdot entry
if (f_stat(entry->path, NULL) != FR_OK) {
skip++; // remember this has to be removed from the stored struct
} else { // entry is valid
if (skip) { // move remaining entries to the left
stored->n_entries -= skip;
memmove(entry - skip, entry, (stored->n_entries - i) * sizeof(DirEntry));
entry -= skip;
skip = 0;
}
if (contents->n_entries < MAX_ENTRIES)
memcpy(&(contents->entry[contents->n_entries++]), entry, sizeof(DirEntry));
else break;
}
}
stored->n_entries -= skip;
}

View File

@ -1,7 +0,0 @@
#pragma once
#include "fs.h"
bool IsStoredDrive(const char* path);
void StoreDirContents(DirStruct* contents);
void GetStoredDirContents(DirStruct* contents);

View File

@ -2,7 +2,6 @@
#include "fs.h" #include "fs.h"
#include "virtual.h" #include "virtual.h"
#include "image.h" #include "image.h"
#include "store.h"
#include "sha.h" #include "sha.h"
#include "sdmmc.h" #include "sdmmc.h"
#include "ff.h" #include "ff.h"
@ -28,6 +27,10 @@ static u32 write_permissions = PERM_BASE;
// number of currently open file systems // number of currently open file systems
static bool fs_mounted[NORM_FS] = { false }; static bool fs_mounted[NORM_FS] = { false };
// last search pattern & path
static char search_pattern[256] = { 0 };
static char search_path[256] = { 0 };
bool InitSDCardFS() { bool InitSDCardFS() {
#ifndef EXEC_GATEWAY #ifndef EXEC_GATEWAY
// TODO: Magic? // TODO: Magic?
@ -72,10 +75,17 @@ void DeinitSDCardFS() {
} }
} }
void SetFSSearch(const char* pattern, const char* path) {
if (pattern && path) {
strncpy(search_pattern, pattern, 256);
strncpy(search_path, path, 256);
} else *search_pattern = *search_path = '\0';
}
int PathToNumFS(const char* path) { int PathToNumFS(const char* path) {
int fsnum = *path - (int) '0'; int fsnum = *path - (int) '0';
if ((fsnum < 0) || (fsnum >= NORM_FS) || (path[1] != ':')) { if ((fsnum < 0) || (fsnum >= NORM_FS) || (path[1] != ':')) {
if (!GetVirtualSource(path) && !IsStoredDrive(path)) ShowPrompt(false, "Invalid path (%s)", path); if (!GetVirtualSource(path) && !IsSearchDrive(path)) ShowPrompt(false, "Invalid path (%s)", path);
return -1; return -1;
} }
return fsnum; return fsnum;
@ -86,6 +96,10 @@ bool IsMountedFS(const char* path) {
return ((fsnum >= 0) && (fsnum < NORM_FS)) ? fs_mounted[fsnum] : false; return ((fsnum >= 0) && (fsnum < NORM_FS)) ? fs_mounted[fsnum] : false;
} }
bool IsSearchDrive(const char* path) {
return *search_pattern && *search_path && (strncmp(path, "Z:", 3) == 0);
}
uint64_t GetSDCardSize() { uint64_t GetSDCardSize() {
if (sdmmc_sdcard_init() != 0) return 0; if (sdmmc_sdcard_init() != 0) return 0;
return (u64) getMMCDevice(1)->total_size * 512; return (u64) getMMCDevice(1)->total_size * 512;
@ -997,7 +1011,7 @@ bool GetRootDirContentsWorker(DirStruct* contents) {
for (u32 pdrv = 0; (pdrv < NORM_FS+VIRT_FS) && (n_entries < MAX_ENTRIES); pdrv++) { for (u32 pdrv = 0; (pdrv < NORM_FS+VIRT_FS) && (n_entries < MAX_ENTRIES); pdrv++) {
DirEntry* entry = &(contents->entry[n_entries]); DirEntry* entry = &(contents->entry[n_entries]);
if ((pdrv < NORM_FS) && !fs_mounted[pdrv]) continue; if ((pdrv < NORM_FS) && !fs_mounted[pdrv]) continue;
else if ((pdrv >= NORM_FS) && (!CheckVirtualDrive(drvnum[pdrv])) && !(IsStoredDrive(drvnum[pdrv]))) continue; else if ((pdrv >= NORM_FS) && (!CheckVirtualDrive(drvnum[pdrv])) && !(IsSearchDrive(drvnum[pdrv]))) continue;
memset(entry->path, 0x00, 64); memset(entry->path, 0x00, 64);
snprintf(entry->path + 0, 4, drvnum[pdrv]); snprintf(entry->path + 0, 4, drvnum[pdrv]);
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]); snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]);
@ -1063,10 +1077,12 @@ bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fnsize, const ch
entry->size = fno.fsize; entry->size = fno.fsize;
} }
entry->marked = 0; entry->marked = 0;
contents->n_entries++; if (contents->n_entries >= MAX_ENTRIES) {
if (contents->n_entries >= MAX_ENTRIES) ret = true; // Too many entries, still okay
break; break;
} }
contents->n_entries++;
}
if (recursive && (fno.fattrib & AM_DIR)) { if (recursive && (fno.fattrib & AM_DIR)) {
if (!GetDirContentsWorker(contents, fpath, fnsize, pattern, recursive)) if (!GetDirContentsWorker(contents, fpath, fnsize, pattern, recursive))
break; break;
@ -1093,8 +1109,6 @@ void SearchDirContents(DirStruct* contents, const char* path, const char* patter
if (GetVirtualSource(path)) { if (GetVirtualSource(path)) {
if (!GetVirtualDirContentsWorker(contents, path, pattern)) if (!GetVirtualDirContentsWorker(contents, path, pattern))
contents->n_entries = 0; contents->n_entries = 0;
} else if (IsStoredDrive(path)) {
GetStoredDirContents(contents);
} else { } else {
char fpath[256]; // 256 is the maximum length of a full path char fpath[256]; // 256 is the maximum length of a full path
strncpy(fpath, path, 256); strncpy(fpath, path, 256);
@ -1106,7 +1120,11 @@ void SearchDirContents(DirStruct* contents, const char* path, const char* patter
} }
void GetDirContents(DirStruct* contents, const char* path) { void GetDirContents(DirStruct* contents, const char* path) {
SearchDirContents(contents, path, NULL, false); if (*search_pattern && *search_path && IsSearchDrive(path)) {
ShowString("Searching, please wait...");
SearchDirContents(contents, search_path, search_pattern, true);
ClearScreenF(true, false, COLOR_STD_BG);
} else SearchDirContents(contents, path, NULL, false);
} }
uint64_t GetFreeSpace(const char* path) uint64_t GetFreeSpace(const char* path)

View File

@ -39,6 +39,9 @@ bool InitExtFS();
void DeinitExtFS(); void DeinitExtFS();
void DeinitSDCardFS(); void DeinitSDCardFS();
/** Set search pattern / path for special Z: drive **/
void SetFSSearch(const char* pattern, const char* path);
/** Return total size of SD card **/ /** Return total size of SD card **/
uint64_t GetSDCardSize(); uint64_t GetSDCardSize();
@ -111,5 +114,8 @@ int PathToNumFS(const char* path);
/** Check if drive is mounted */ /** Check if drive is mounted */
bool IsMountedFS(const char* path); bool IsMountedFS(const char* path);
/** Check for soecial search drive **/
bool IsSearchDrive(const char* path);
/** Helper function for copying DirEntry structs */ /** Helper function for copying DirEntry structs */
void DirEntryCpy(DirEntry* dest, const DirEntry* orig); void DirEntryCpy(DirEntry* dest, const DirEntry* orig);

View File

@ -6,9 +6,8 @@
#include "nand.h" #include "nand.h"
#include "virtual.h" #include "virtual.h"
#include "image.h" #include "image.h"
#include "store.h"
#define VERSION "0.6.3" #define VERSION "0.6.4"
#define N_PANES 2 #define N_PANES 2
#define IMG_DRV "789I" #define IMG_DRV "789I"
@ -93,6 +92,17 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
ResizeString(tempstr, bytestr, 20, 8, false); ResizeString(tempstr, bytestr, 20, 8, false);
} }
DrawStringF(TOP_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, tempstr); DrawStringF(TOP_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, tempstr);
// path of file (if in search results)
if (IsSearchDrive(curr_path) && strrchr(curr_entry->path, '/')) {
char dirstr[256];
strncpy(dirstr, curr_entry->path, 256);
*(strrchr(dirstr, '/')+1) = '\0';
ResizeString(tempstr, dirstr, 20, 8, false);
DrawStringF(TOP_SCREEN, 4, info_start + 12 + 10 + 10, color_current, COLOR_STD_BG, tempstr);
} else {
ResizeString(tempstr, "", 20, 8, false);
DrawStringF(TOP_SCREEN, 4, info_start + 12 + 10 + 10, color_current, COLOR_STD_BG, tempstr);
}
// right top - clipboard // right top - clipboard
DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - (20*FONT_WIDTH_EXT), info_start, COLOR_STD_FONT, COLOR_STD_BG, "%20s", (clipboard->n_entries) ? "[CLIPBOARD]" : ""); DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - (20*FONT_WIDTH_EXT), info_start, COLOR_STD_FONT, COLOR_STD_BG, "%20s", (clipboard->n_entries) ? "[CLIPBOARD]" : "");
@ -107,7 +117,7 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
// bottom: inctruction block // bottom: inctruction block
char instr[256]; char instr[256];
snprintf(instr, 256, "%s%s\n%s%s%s%s%s%s", snprintf(instr, 256, "%s%s\n%s%s%s%s%s%s%s",
#ifndef SAFEMODE #ifndef SAFEMODE
"GodMode9 Explorer v", VERSION, // generic start part "GodMode9 Explorer v", VERSION, // generic start part
#else #else
@ -119,6 +129,7 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
"R+Y - Unlock write permissions\nR+B - Unmount SD card\n"), "R+Y - Unlock write permissions\nR+B - Unmount SD card\n"),
(*curr_path) ? "" : ((GetMountState() == IMG_RAMDRV) ? "R+X - Unmount RAM drive\n" : (*curr_path) ? "" : ((GetMountState() == IMG_RAMDRV) ? "R+X - Unmount RAM drive\n" :
(GetMountState()) ? "R+X - Unmount image\n" : "R+X - Mount RAM drive\n"), (GetMountState()) ? "R+X - Unmount image\n" : "R+X - Mount RAM drive\n"),
(*curr_path) ? "R+A - Search directory\n" : "R+A - Search drive\n",
"R+L - Make a Screenshot\n", "R+L - Make a Screenshot\n",
"R+\x1B\x1A - Switch to prev/next pane\n", "R+\x1B\x1A - Switch to prev/next pane\n",
(clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full (clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full
@ -547,17 +558,17 @@ u32 GodMode() {
// basic navigation commands // basic navigation commands
if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs
if (switched) { // search directory if (switched && !IsSearchDrive(curr_entry->path)) { // search directory
char searchstr[256]; char searchstr[256];
char namestr[20+1]; char namestr[20+1];
snprintf(searchstr, 256, "*"); snprintf(searchstr, 256, "*");
TruncateString(namestr, curr_entry->name, 20, 8); TruncateString(namestr, curr_entry->name, 20, 8);
if (ShowStringPrompt(searchstr, 256, "Search %s?\nEnter search below.", namestr)) { if (ShowStringPrompt(searchstr, 256, "Search %s?\nEnter search below.", namestr)) {
ShowString("Searching path, please wait..."); SetFSSearch(searchstr, curr_entry->path);
snprintf(current_path, 256, "Z:"); snprintf(current_path, 256, "Z:");
SearchDirContents(current_dir, curr_entry->path, searchstr, true); GetDirContents(current_dir, current_path);
ClearScreenF(true, false, COLOR_STD_BG); cursor = 1;
StoreDirContents(current_dir); scroll = 0;
} }
} else { // one level up } else { // one level up
strncpy(current_path, curr_entry->path, 256); strncpy(current_path, curr_entry->path, 256);

View File

@ -6,7 +6,7 @@
#include "nand.h" #include "nand.h"
#include "image.h" #include "image.h"
#define NAND_BUFFER ((u8*)0x21400000) #define NAND_BUFFER ((u8*)0x21300000)
#define NAND_BUFFER_SIZE (0x100000) // must be multiple of 0x200 #define NAND_BUFFER_SIZE (0x100000) // must be multiple of 0x200
#define NAND_MIN_SECTORS ((GetUnitPlatform() == PLATFORM_N3DS) ? 0x26C000 : 0x1D7800) #define NAND_MIN_SECTORS ((GetUnitPlatform() == PLATFORM_N3DS) ? 0x26C000 : 0x1D7800)